blob: b87517ab948a8ab2a2ec0498cb3fe4ae607824a4 [file] [log] [blame]
Ray Milkey35958232015-07-29 11:19:28 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Ray Milkey35958232015-07-29 11:19:28 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.store.service;
17
18import java.util.Collection;
19import java.util.HashMap;
20import java.util.LinkedList;
21import java.util.List;
22import java.util.Map;
23import java.util.Set;
24import java.util.concurrent.ExecutorService;
25import java.util.concurrent.ScheduledExecutorService;
26import java.util.concurrent.TimeUnit;
27import java.util.function.BiFunction;
28
29import org.onlab.util.KryoNamespace;
30import org.onosproject.cluster.NodeId;
31import org.onosproject.store.Timestamp;
32
Aaron Kruglikov66cf0b92015-10-26 15:46:54 -070033import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
34import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
Ray Milkey35958232015-07-29 11:19:28 -070035
36/**
37 * Testing version of an Eventually Consistent Map.
38 */
39
40public final class TestEventuallyConsistentMap<K, V> extends EventuallyConsistentMapAdapter<K, V> {
41
42 private final HashMap<K, V> map;
43 private final String mapName;
44 private final List<EventuallyConsistentMapListener<K, V>> listeners;
45 private final BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
46
47 private TestEventuallyConsistentMap(String mapName,
48 BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
49 map = new HashMap<>();
50 listeners = new LinkedList<>();
51 this.mapName = mapName;
52 this.peerUpdateFunction = peerUpdateFunction;
53 }
54
55 /**
56 * Notify all listeners of an event.
57 */
58 private void notifyListeners(EventuallyConsistentMapEvent<K, V> event) {
59 listeners.forEach(
60 listener -> listener.event(event)
61 );
62 }
63
64 @Override
65 public int size() {
66 return map.size();
67 }
68
69 @Override
70 public boolean isEmpty() {
71 return map.isEmpty();
72 }
73
74 @Override
75 public boolean containsKey(K key) {
76 return map.containsKey(key);
77 }
78
79 @Override
80 public boolean containsValue(V value) {
81 return map.containsValue(value);
82 }
83
84 @Override
85 public V get(K key) {
86 return map.get(key);
87 }
88
89 @Override
90 public void put(K key, V value) {
91 map.put(key, value);
92 EventuallyConsistentMapEvent<K, V> addEvent =
93 new EventuallyConsistentMapEvent<>(mapName, PUT, key, value);
94 notifyListeners(addEvent);
Ray Milkeyb3c5ce22015-08-10 09:07:36 -070095 if (peerUpdateFunction != null) {
96 peerUpdateFunction.apply(key, value);
97 }
Ray Milkey35958232015-07-29 11:19:28 -070098 }
99
100 @Override
101 public V remove(K key) {
102 V result = map.remove(key);
103 if (result != null) {
104 EventuallyConsistentMapEvent<K, V> removeEvent =
105 new EventuallyConsistentMapEvent<>(mapName, REMOVE,
106 key, map.get(key));
107 notifyListeners(removeEvent);
108 }
109 return result;
110 }
111
112 @Override
113 public void remove(K key, V value) {
114 boolean removed = map.remove(key, value);
115 if (removed) {
116 EventuallyConsistentMapEvent<K, V> removeEvent =
117 new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, value);
118 notifyListeners(removeEvent);
119 }
120 }
121
122 @Override
123 public V compute(K key, BiFunction<K, V, V> recomputeFunction) {
124 return map.compute(key, recomputeFunction);
125 }
126
127 @Override
128 public void putAll(Map<? extends K, ? extends V> m) {
129 map.putAll(m);
130 }
131
132 @Override
133 public void clear() {
134 map.clear();
135 }
136
137 @Override
138 public Set<K> keySet() {
139 return map.keySet();
140 }
141
142 @Override
143 public Collection<V> values() {
144 return map.values();
145 }
146
147 @Override
148 public Set<Map.Entry<K, V>> entrySet() {
149 return map.entrySet();
150 }
151
152 public static <K, V> Builder<K, V> builder() {
153 return new Builder<>();
154 }
155
156 @Override
157 public void addListener(EventuallyConsistentMapListener<K, V> listener) {
158 listeners.add(listener);
159 }
160
161 @Override
162 public void removeListener(EventuallyConsistentMapListener<K, V> listener) {
163 listeners.remove(listener);
164 }
165
166 public static class Builder<K, V> implements EventuallyConsistentMapBuilder<K, V> {
167 private String name;
168 private BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
169
170 @Override
171 public EventuallyConsistentMapBuilder<K, V> withName(String name) {
172 this.name = name;
173 return this;
174 }
175
176 @Override
177 public EventuallyConsistentMapBuilder<K, V> withSerializer(KryoNamespace.Builder serializerBuilder) {
178 return this;
179 }
180
181 @Override
182 public EventuallyConsistentMapBuilder<K, V>
183 withTimestampProvider(BiFunction<K, V, Timestamp> timestampProvider) {
184 return this;
185 }
186
187 @Override
188 public EventuallyConsistentMapBuilder<K, V> withEventExecutor(ExecutorService executor) {
189 return this;
190 }
191
192 @Override
193 public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor(ExecutorService executor) {
194 return this;
195 }
196
197 @Override
198 public EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor(ScheduledExecutorService executor) {
199 return this;
200 }
201
202 @Override
203 public EventuallyConsistentMapBuilder<K, V>
204 withPeerUpdateFunction(BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
205 this.peerUpdateFunction = peerUpdateFunction;
206 return this;
207 }
208
209 @Override
210 public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled() {
211 return this;
212 }
213
214 @Override
215 public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod(long period, TimeUnit unit) {
216 return this;
217 }
218
219 @Override
220 public EventuallyConsistentMapBuilder<K, V> withFasterConvergence() {
221 return this;
222 }
223
224 @Override
225 public EventuallyConsistentMapBuilder<K, V> withPersistence() {
226 return this;
227 }
228
229 @Override
230 public EventuallyConsistentMap<K, V> build() {
231 if (name == null) {
232 name = "test";
233 }
234 return new TestEventuallyConsistentMap<>(name, peerUpdateFunction);
235 }
236 }
237
238}
239