4f612de25dd09ee69cd47d9762e5f50ed9a5f232
[onosfw.git] /
1 /*
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  */
16 package org.onosproject.store.service;
17
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.LinkedList;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.ExecutorService;
25 import java.util.concurrent.ScheduledExecutorService;
26 import java.util.concurrent.TimeUnit;
27 import java.util.function.BiFunction;
28
29 import org.onlab.util.KryoNamespace;
30 import org.onosproject.cluster.NodeId;
31 import org.onosproject.store.Timestamp;
32
33 import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*;
34
35 /**
36  * Testing version of an Eventually Consistent Map.
37  */
38
39 public final class TestEventuallyConsistentMap<K, V> extends EventuallyConsistentMapAdapter<K, V> {
40
41     private final HashMap<K, V> map;
42     private final String mapName;
43     private final List<EventuallyConsistentMapListener<K, V>> listeners;
44     private final BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
45
46     private TestEventuallyConsistentMap(String mapName,
47                                         BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
48         map = new HashMap<>();
49         listeners = new LinkedList<>();
50         this.mapName = mapName;
51         this.peerUpdateFunction = peerUpdateFunction;
52     }
53
54     /**
55      * Notify all listeners of an event.
56      */
57     private void notifyListeners(EventuallyConsistentMapEvent<K, V> event) {
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 V get(K key) {
85         return map.get(key);
86     }
87
88     @Override
89     public void put(K key, V value) {
90         map.put(key, value);
91         EventuallyConsistentMapEvent<K, V> addEvent =
92                 new EventuallyConsistentMapEvent<>(mapName, PUT, key, value);
93         notifyListeners(addEvent);
94         if (peerUpdateFunction != null) {
95             peerUpdateFunction.apply(key, value);
96         }
97     }
98
99     @Override
100     public V remove(K key) {
101         V result = map.remove(key);
102         if (result != null) {
103             EventuallyConsistentMapEvent<K, V> removeEvent =
104                     new EventuallyConsistentMapEvent<>(mapName, REMOVE,
105                             key, map.get(key));
106             notifyListeners(removeEvent);
107         }
108         return result;
109     }
110
111     @Override
112     public void remove(K key, V value) {
113         boolean removed = map.remove(key, value);
114         if (removed) {
115             EventuallyConsistentMapEvent<K, V> removeEvent =
116                     new EventuallyConsistentMapEvent<>(mapName, REMOVE, key, value);
117             notifyListeners(removeEvent);
118         }
119     }
120
121     @Override
122     public V compute(K key, BiFunction<K, V, V> recomputeFunction) {
123         return map.compute(key, recomputeFunction);
124     }
125
126     @Override
127     public void putAll(Map<? extends K, ? extends V> m) {
128         map.putAll(m);
129     }
130
131     @Override
132     public void clear() {
133         map.clear();
134     }
135
136     @Override
137     public Set<K> keySet() {
138         return map.keySet();
139     }
140
141     @Override
142     public Collection<V> values() {
143         return map.values();
144     }
145
146     @Override
147     public Set<Map.Entry<K, V>> entrySet() {
148         return map.entrySet();
149     }
150
151     public static <K, V> Builder<K, V> builder() {
152         return new Builder<>();
153     }
154
155     @Override
156     public void addListener(EventuallyConsistentMapListener<K, V> listener) {
157         listeners.add(listener);
158     }
159
160     @Override
161     public void removeListener(EventuallyConsistentMapListener<K, V> listener) {
162         listeners.remove(listener);
163     }
164
165     public static class Builder<K, V> implements EventuallyConsistentMapBuilder<K, V> {
166         private String name;
167         private BiFunction<K, V, Collection<NodeId>> peerUpdateFunction;
168
169         @Override
170         public EventuallyConsistentMapBuilder<K, V> withName(String name) {
171             this.name = name;
172             return this;
173         }
174
175         @Override
176         public EventuallyConsistentMapBuilder<K, V> withSerializer(KryoNamespace.Builder serializerBuilder) {
177             return this;
178         }
179
180         @Override
181         public EventuallyConsistentMapBuilder<K, V>
182         withTimestampProvider(BiFunction<K, V, Timestamp> timestampProvider) {
183             return this;
184         }
185
186         @Override
187         public EventuallyConsistentMapBuilder<K, V> withEventExecutor(ExecutorService executor) {
188             return this;
189         }
190
191         @Override
192         public EventuallyConsistentMapBuilder<K, V> withCommunicationExecutor(ExecutorService executor) {
193             return this;
194         }
195
196         @Override
197         public EventuallyConsistentMapBuilder<K, V> withBackgroundExecutor(ScheduledExecutorService executor) {
198             return this;
199         }
200
201         @Override
202         public EventuallyConsistentMapBuilder<K, V>
203         withPeerUpdateFunction(BiFunction<K, V, Collection<NodeId>> peerUpdateFunction) {
204             this.peerUpdateFunction = peerUpdateFunction;
205             return this;
206         }
207
208         @Override
209         public EventuallyConsistentMapBuilder<K, V> withTombstonesDisabled() {
210             return this;
211         }
212
213         @Override
214         public EventuallyConsistentMapBuilder<K, V> withAntiEntropyPeriod(long period, TimeUnit unit) {
215             return this;
216         }
217
218         @Override
219         public EventuallyConsistentMapBuilder<K, V> withFasterConvergence() {
220             return this;
221         }
222
223         @Override
224         public EventuallyConsistentMapBuilder<K, V> withPersistence() {
225             return this;
226         }
227
228         @Override
229         public EventuallyConsistentMap<K, V> build() {
230             if (name == null) {
231                 name = "test";
232             }
233             return new TestEventuallyConsistentMap<>(name, peerUpdateFunction);
234         }
235     }
236
237 }
238