blob: 1494b8a5a0d42b69da608f623b98a0c553474bcf [file] [log] [blame]
Ray Milkey6f440332015-07-31 10:40:53 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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.function.BiFunction;
25import java.util.function.Function;
26import java.util.function.Predicate;
27import java.util.stream.Collectors;
28
29import org.onosproject.core.ApplicationId;
30import static org.onosproject.store.service.MapEvent.Type;
31import static org.onosproject.store.service.MapEvent.Type.*;
32
33/**
34 * Test implementation of the consistent map.
35 */
36public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
37
38 private final List<MapEventListener<K, V>> listeners;
39 private final HashMap<K, V> map;
40 private final String mapName;
41
42 private TestConsistentMap(String mapName) {
43 map = new HashMap<>();
44 listeners = new LinkedList<>();
45 this.mapName = mapName;
46 }
47
48 private Versioned<V> version(V v) {
49 return new Versioned<>(v, 1, System.currentTimeMillis());
50 }
51
52 /**
53 * Notify all listeners of an event.
54 */
55 private void notifyListeners(String mapName, Type type,
56 K key, Versioned<V> value) {
57 MapEvent<K, V> event = new MapEvent<>(mapName, type, key, value);
58 listeners.forEach(
59 listener -> listener.event(event)
60 );
61 }
62
63 @Override
64 public int size() {
65 return map.size();
66 }
67
68 @Override
69 public boolean isEmpty() {
70 return map.isEmpty();
71 }
72
73 @Override
74 public boolean containsKey(K key) {
75 return map.containsKey(key);
76 }
77
78 @Override
79 public boolean containsValue(V value) {
80 return map.containsValue(value);
81 }
82
83 @Override
84 public Versioned<V> get(K key) {
85 return version(map.get(key));
86 }
87
88 @Override
89 public Versioned<V> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
90 Versioned<V> result = version(map.computeIfAbsent(key, mappingFunction));
91 notifyListeners(mapName, INSERT, key, result);
92 return result;
93 }
94
95 @Override
96 public Versioned<V> compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
97 return version(map.compute(key, remappingFunction));
98 }
99
100 @Override
101 public Versioned<V> computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
102 return version(map.computeIfPresent(key, remappingFunction));
103 }
104
105 @Override
106 public Versioned<V> computeIf(K key, Predicate<? super V> condition,
107 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
108 return null;
109 }
110
111 @Override
112 public Versioned<V> put(K key, V value) {
113 Versioned<V> result = version(map.put(key, value));
114 notifyListeners(mapName, INSERT, key, result);
115 return result;
116 }
117
118 @Override
119 public Versioned<V> putAndGet(K key, V value) {
120 Versioned<V> result = version(map.put(key, value));
121 notifyListeners(mapName, UPDATE, key, result);
122 return result;
123 }
124
125 @Override
126 public Versioned<V> remove(K key) {
127 Versioned<V> result = version(map.remove(key));
128 notifyListeners(mapName, REMOVE, key, result);
129 return result;
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<Versioned<V>> values() {
144 return map
145 .values()
146 .stream()
147 .map(this::version)
148 .collect(Collectors.toList());
149 }
150
151 @Override
152 public Set<Map.Entry<K, Versioned<V>>> entrySet() {
153 return super.entrySet();
154 }
155
156 @Override
157 public Versioned<V> putIfAbsent(K key, V value) {
158 Versioned<V> result = version(map.putIfAbsent(key, value));
159 if (map.get(key).equals(value)) {
160 notifyListeners(mapName, INSERT, key, result);
161 }
162 return result;
163 }
164
165 @Override
166 public boolean remove(K key, V value) {
167 boolean removed = map.remove(key, value);
168 if (removed) {
169 notifyListeners(mapName, REMOVE, key, null);
170 }
171 return removed;
172 }
173
174 @Override
175 public boolean remove(K key, long version) {
176 boolean removed = map.remove(key, version);
177 if (removed) {
178 notifyListeners(mapName, REMOVE, key, null);
179 }
180 return removed;
181 }
182
183 @Override
184 public boolean replace(K key, V oldValue, V newValue) {
185 boolean replaced = map.replace(key, oldValue, newValue);
186 if (replaced) {
187 notifyListeners(mapName, REMOVE, key, null);
188 }
189 return replaced;
190 }
191
192 @Override
193 public boolean replace(K key, long oldVersion, V newValue) {
194 boolean replaced = map.replace(key, map.get(key), newValue);
195 if (replaced) {
196 notifyListeners(mapName, REMOVE, key, null);
197 }
198 return replaced;
199 }
200
201 @Override
202 public void addListener(MapEventListener<K, V> listener) {
203 listeners.add(listener);
204 }
205
206 @Override
207 public void removeListener(MapEventListener<K, V> listener) {
208 listeners.remove(listener);
209 }
210
211 public static Builder builder() {
212 return new Builder();
213 }
214
215 public static class Builder<K, V> implements ConsistentMapBuilder<K, V> {
216 String mapName = "map";
217
218 @Override
219 public ConsistentMapBuilder<K, V> withName(String mapName) {
220 this.mapName = mapName;
221 return this;
222 }
223
224 @Override
225 public ConsistentMapBuilder<K, V> withApplicationId(ApplicationId id) {
226 return this;
227 }
228
229 @Override
230 public ConsistentMapBuilder<K, V> withSerializer(Serializer serializer) {
231 return this;
232 }
233
234 @Override
235 public ConsistentMapBuilder<K, V> withPartitionsDisabled() {
236 return this;
237 }
238
239 @Override
240 public ConsistentMapBuilder<K, V> withUpdatesDisabled() {
241 return this;
242 }
243
244 @Override
245 public ConsistentMapBuilder<K, V> withPurgeOnUninstall() {
246 return this;
247 }
248
249 @Override
250 public ConsistentMap<K, V> build() {
251 return new TestConsistentMap<>(mapName);
252 }
253
254 @Override
255 public AsyncConsistentMap<K, V> buildAsyncMap() {
256 return null;
257 }
258
259 }
260
261}