blob: 3ce1f07558488adecf32378d78733c64817cfbb4 [file] [log] [blame]
Madan Jampani7c521002015-03-23 12:23:01 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Madan Jampani7c521002015-03-23 12:23:01 -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 */
16
17package org.onosproject.store.service;
18
19import java.util.Collection;
Madan Jampanidfde6ba2016-01-13 21:36:09 -080020import java.util.Objects;
Madan Jampani7c521002015-03-23 12:23:01 -070021import java.util.Map.Entry;
Madan Jampani6e0d1472015-03-24 12:13:44 -070022import java.util.Set;
Madan Jampani7c521002015-03-23 12:23:01 -070023import java.util.concurrent.CompletableFuture;
Madan Jampani346d4f52015-05-04 11:09:39 -070024import java.util.function.BiFunction;
25import java.util.function.Function;
26import java.util.function.Predicate;
Madan Jampani7c521002015-03-23 12:23:01 -070027
Madan Jampani28b2cd62016-02-02 10:49:52 -080028import org.onosproject.store.primitives.DefaultConsistentMap;
Madan Jampani74da78b2016-02-09 21:18:36 -080029import org.onosproject.store.primitives.TransactionId;
Madan Jampani28b2cd62016-02-02 10:49:52 -080030
Madan Jampani7c521002015-03-23 12:23:01 -070031/**
32 * A distributed, strongly consistent map whose methods are all executed asynchronously.
33 * <p>
34 * This map offers strong read-after-update (where update == create/update/delete)
35 * consistency. All operations to the map are serialized and applied in a consistent
36 * manner.
37 * <p>
38 * The stronger consistency comes at the expense of availability in
39 * the event of a network partition. A network partition can be either due to
40 * a temporary disruption in network connectivity between participating nodes
41 * or due to a node being temporarily down.
42 * </p><p>
Madan Jampanifa242182016-01-22 13:42:54 -080043 * All values stored in this map are {@link Versioned versioned} and the API
44 * supports optimistic concurrency by allowing conditional updates that take into
45 * consideration the version or value that was previously read.
Madan Jampani7c521002015-03-23 12:23:01 -070046 * </p><p>
47 * This map does not allow null values. All methods can throw a ConsistentMapException
Madan Jampanifa242182016-01-22 13:42:54 -080048 * (which extends {@code RuntimeException}) to indicate failures.
Madan Jampanidfde6ba2016-01-13 21:36:09 -080049 * <p>
50 * All methods of this interface return a {@link CompletableFuture future} immediately
51 * after a successful invocation. The operation itself is executed asynchronous and
52 * the returned future will be {@link CompletableFuture#complete completed} when the
53 * operation finishes.
Madan Jampani7c521002015-03-23 12:23:01 -070054 */
Madan Jampania090a112016-01-18 16:38:17 -080055public interface AsyncConsistentMap<K, V> extends DistributedPrimitive {
56
57 @Override
Madan Jampani39fff102016-02-14 13:17:28 -080058 default DistributedPrimitive.Type primitiveType() {
Madan Jampania090a112016-01-18 16:38:17 -080059 return DistributedPrimitive.Type.CONSISTENT_MAP;
60 }
Madan Jampani7c521002015-03-23 12:23:01 -070061
Madan Jampanifa242182016-01-22 13:42:54 -080062 @Override
63 default CompletableFuture<Void> destroy() {
64 return clear();
65 }
66
Madan Jampani7c521002015-03-23 12:23:01 -070067 /**
68 * Returns the number of entries in the map.
69 *
70 * @return a future for map size.
71 */
72 CompletableFuture<Integer> size();
73
74 /**
75 * Returns true if the map is empty.
76 *
77 * @return a future whose value will be true if map has no entries, false otherwise.
78 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -080079 default CompletableFuture<Boolean> isEmpty() {
80 return size().thenApply(s -> s == 0);
81 }
Madan Jampani7c521002015-03-23 12:23:01 -070082
83 /**
84 * Returns true if this map contains a mapping for the specified key.
85 *
86 * @param key key
87 * @return a future whose value will be true if map contains key, false otherwise.
88 */
89 CompletableFuture<Boolean> containsKey(K key);
90
91 /**
92 * Returns true if this map contains the specified value.
93 *
94 * @param value value
95 * @return a future whose value will be true if map contains value, false otherwise.
96 */
97 CompletableFuture<Boolean> containsValue(V value);
98
99 /**
100 * Returns the value (and version) to which the specified key is mapped, or null if this
101 * map contains no mapping for the key.
102 *
103 * @param key the key whose associated value (and version) is to be returned
104 * @return a future value (and version) to which the specified key is mapped, or null if
105 * this map contains no mapping for the key
106 */
107 CompletableFuture<Versioned<V>> get(K key);
108
109 /**
Madan Jampani346d4f52015-05-04 11:09:39 -0700110 * If the specified key is not already associated with a value (or is mapped to null),
111 * attempts to compute its value using the given mapping function and enters it into
112 * this map unless null.
113 * If a conflicting concurrent modification attempt is detected, the returned future
114 * will be completed exceptionally with ConsistentMapException.ConcurrentModification.
115 * @param key key with which the specified value is to be associated
116 * @param mappingFunction the function to compute a value
117 * @return the current (existing or computed) value associated with the specified key,
118 * or null if the computed value is null
119 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800120 default CompletableFuture<Versioned<V>> computeIfAbsent(K key,
121 Function<? super K, ? extends V> mappingFunction) {
122 return computeIf(key, Objects::isNull, (k, v) -> mappingFunction.apply(k));
123 }
Madan Jampani346d4f52015-05-04 11:09:39 -0700124
125 /**
126 * If the value for the specified key is present and non-null, attempts to compute a new
127 * mapping given the key and its current mapped value.
128 * If the computed value is null, the current mapping will be removed from the map.
129 * If a conflicting concurrent modification attempt is detected, the returned future
130 * will be completed exceptionally with ConsistentMapException.ConcurrentModification.
131 * @param key key with which the specified value is to be associated
132 * @param remappingFunction the function to compute a value
133 * @return the new value associated with the specified key, or null if computed value is null
134 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800135 default CompletableFuture<Versioned<V>> computeIfPresent(K key,
136 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
137 return computeIf(key, Objects::nonNull, remappingFunction);
138 }
Madan Jampani346d4f52015-05-04 11:09:39 -0700139
140 /**
141 * Attempts to compute a mapping for the specified key and its current mapped value (or
142 * null if there is no current mapping).
143 * If the computed value is null, the current mapping (if one exists) will be removed from the map.
144 * If a conflicting concurrent modification attempt is detected, the returned future
145 * will be completed exceptionally with ConsistentMapException.ConcurrentModification.
146 * @param key key with which the specified value is to be associated
147 * @param remappingFunction the function to compute a value
148 * @return the new value associated with the specified key, or null if computed value is null
149 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800150 default CompletableFuture<Versioned<V>> compute(K key,
151 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
152 return computeIf(key, v -> true, remappingFunction);
153 }
Madan Jampani346d4f52015-05-04 11:09:39 -0700154
155 /**
156 * If the value for the specified key satisfies a condition, attempts to compute a new
157 * mapping given the key and its current mapped value.
158 * If the computed value is null, the current mapping will be removed from the map.
159 * If a conflicting concurrent modification attempt is detected, the returned future
160 * will be completed exceptionally with ConsistentMapException.ConcurrentModification.
161 * @param key key with which the specified value is to be associated
162 * @param condition condition that should evaluate to true for the computation to proceed
163 * @param remappingFunction the function to compute a value
164 * @return the new value associated with the specified key, or the old value if condition evaluates to false
165 */
166 CompletableFuture<Versioned<V>> computeIf(K key,
167 Predicate<? super V> condition,
168 BiFunction<? super K, ? super V, ? extends V> remappingFunction);
169
170 /**
Madan Jampani7c521002015-03-23 12:23:01 -0700171 * Associates the specified value with the specified key in this map (optional operation).
172 * If the map previously contained a mapping for the key, the old value is replaced by the
173 * specified value.
174 *
175 * @param key key with which the specified value is to be associated
176 * @param value value to be associated with the specified key
177 * @return the previous value (and version) associated with key, or null if there was
178 * no mapping for key.
179 */
180 CompletableFuture<Versioned<V>> put(K key, V value);
181
182 /**
Madan Jampani346d4f52015-05-04 11:09:39 -0700183 * Associates the specified value with the specified key in this map (optional operation).
184 * If the map previously contained a mapping for the key, the old value is replaced by the
185 * specified value.
186 *
187 * @param key key with which the specified value is to be associated
188 * @param value value to be associated with the specified key
189 * @return new value.
190 */
191 CompletableFuture<Versioned<V>> putAndGet(K key, V value);
192
193 /**
Madan Jampani7c521002015-03-23 12:23:01 -0700194 * Removes the mapping for a key from this map if it is present (optional operation).
195 *
196 * @param key key whose value is to be removed from the map
197 * @return the value (and version) to which this map previously associated the key,
198 * or null if the map contained no mapping for the key.
199 */
200 CompletableFuture<Versioned<V>> remove(K key);
201
202 /**
203 * Removes all of the mappings from this map (optional operation).
204 * The map will be empty after this call returns.
Madan Jampani6e0d1472015-03-24 12:13:44 -0700205 * @return future that will be successfully completed when the map is cleared
Madan Jampani7c521002015-03-23 12:23:01 -0700206 */
207 CompletableFuture<Void> clear();
208
209 /**
210 * Returns a Set view of the keys contained in this map.
211 * This method differs from the behavior of java.util.Map.keySet() in that
212 * what is returned is a unmodifiable snapshot view of the keys in the ConsistentMap.
213 * Attempts to modify the returned set, whether direct or via its iterator,
214 * result in an UnsupportedOperationException.
215 *
216 * @return a set of the keys contained in this map
217 */
218 CompletableFuture<Set<K>> keySet();
219
220 /**
221 * Returns the collection of values (and associated versions) contained in this map.
222 * This method differs from the behavior of java.util.Map.values() in that
223 * what is returned is a unmodifiable snapshot view of the values in the ConsistentMap.
224 * Attempts to modify the returned collection, whether direct or via its iterator,
225 * result in an UnsupportedOperationException.
226 *
227 * @return a collection of the values (and associated versions) contained in this map
228 */
229 CompletableFuture<Collection<Versioned<V>>> values();
230
231 /**
232 * Returns the set of entries contained in this map.
233 * This method differs from the behavior of java.util.Map.entrySet() in that
234 * what is returned is a unmodifiable snapshot view of the entries in the ConsistentMap.
235 * Attempts to modify the returned set, whether direct or via its iterator,
236 * result in an UnsupportedOperationException.
237 *
238 * @return set of entries contained in this map.
239 */
240 CompletableFuture<Set<Entry<K, Versioned<V>>>> entrySet();
241
242 /**
243 * If the specified key is not already associated with a value
244 * associates it with the given value and returns null, else returns the current value.
245 *
246 * @param key key with which the specified value is to be associated
247 * @param value value to be associated with the specified key
248 * @return the previous value associated with the specified key or null
249 * if key does not already mapped to a value.
250 */
251 CompletableFuture<Versioned<V>> putIfAbsent(K key, V value);
252
253 /**
254 * Removes the entry for the specified key only if it is currently
255 * mapped to the specified value.
256 *
257 * @param key key with which the specified value is associated
258 * @param value value expected to be associated with the specified key
259 * @return true if the value was removed
260 */
261 CompletableFuture<Boolean> remove(K key, V value);
262
263 /**
264 * Removes the entry for the specified key only if its current
265 * version in the map is equal to the specified version.
266 *
267 * @param key key with which the specified version is associated
268 * @param version version expected to be associated with the specified key
269 * @return true if the value was removed
270 */
271 CompletableFuture<Boolean> remove(K key, long version);
272
273 /**
Jihwan Kim9887ad92015-12-12 00:23:57 +0900274 * Replaces the entry for the specified key only if there is any value
275 * which associated with specified key.
276 *
277 * @param key key with which the specified value is associated
278 * @param value value expected to be associated with the specified key
279 * @return the previous value associated with the specified key or null
280 */
281 CompletableFuture<Versioned<V>> replace(K key, V value);
282
283 /**
Madan Jampani7c521002015-03-23 12:23:01 -0700284 * Replaces the entry for the specified key only if currently mapped
285 * to the specified value.
286 *
287 * @param key key with which the specified value is associated
288 * @param oldValue value expected to be associated with the specified key
289 * @param newValue value to be associated with the specified key
290 * @return true if the value was replaced
291 */
292 CompletableFuture<Boolean> replace(K key, V oldValue, V newValue);
293
294 /**
295 * Replaces the entry for the specified key only if it is currently mapped to the
296 * specified version.
297 *
298 * @param key key key with which the specified value is associated
299 * @param oldVersion version expected to be associated with the specified key
300 * @param newValue value to be associated with the specified key
301 * @return true if the value was replaced
302 */
303 CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue);
Madan Jampani346d4f52015-05-04 11:09:39 -0700304
305 /**
Madan Jampani50589ac2015-06-08 11:38:46 -0700306 * Registers the specified listener to be notified whenever the map is updated.
307 *
308 * @param listener listener to notify about map events
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800309 * @return future that will be completed when the operation finishes
Madan Jampani50589ac2015-06-08 11:38:46 -0700310 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800311 CompletableFuture<Void> addListener(MapEventListener<K, V> listener);
Madan Jampani50589ac2015-06-08 11:38:46 -0700312
313 /**
314 * Unregisters the specified listener such that it will no longer
315 * receive map change notifications.
316 *
317 * @param listener listener to unregister
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800318 * @return future that will be completed when the operation finishes
Madan Jampani50589ac2015-06-08 11:38:46 -0700319 */
Madan Jampanidfde6ba2016-01-13 21:36:09 -0800320 CompletableFuture<Void> removeListener(MapEventListener<K, V> listener);
Madan Jampani28b2cd62016-02-02 10:49:52 -0800321
322 /**
Madan Jampani74da78b2016-02-09 21:18:36 -0800323 * Prepares a transaction for commitment.
324 * @param transaction transaction
325 * @return {@code true} if prepare is successful and transaction is ready to be committed;
326 * {@code false} otherwise
327 */
328 CompletableFuture<Boolean> prepare(MapTransaction<K, V> transaction);
329
330 /**
331 * Commits a previously prepared transaction.
332 * @param transactionId transaction identifier
333 * @return future that will be completed when the operation finishes
334 */
335 CompletableFuture<Void> commit(TransactionId transactionId);
336
337 /**
338 * Aborts a previously prepared transaction.
339 * @param transactionId transaction identifier
340 * @return future that will be completed when the operation finishes
341 */
342 CompletableFuture<Void> rollback(TransactionId transactionId);
343
344 /**
Madan Jampani542d9e22016-04-05 15:39:55 -0700345 * Prepares a transaction and commits it in one go.
346 * @param transaction transaction
347 * @return {@code true} if operation is successful and updates are committed
348 * {@code false} otherwise
349 */
350 CompletableFuture<Boolean> prepareAndCommit(MapTransaction<K, V> transaction);
351
352 /**
Madan Jampani74da78b2016-02-09 21:18:36 -0800353 * Returns a new {@link ConsistentMap} that is backed by this instance.
354 *
355 * @return new {@code ConsistentMap} instance
356 */
357 default ConsistentMap<K, V> asConsistentMap() {
358 return asConsistentMap(DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS);
359 }
360
361 /**
Madan Jampani28b2cd62016-02-02 10:49:52 -0800362 * Returns a new {@link ConsistentMap} that is backed by this instance.
363 *
364 * @param timeoutMillis timeout duration for the returned ConsistentMap operations
365 * @return new {@code ConsistentMap} instance
366 */
367 default ConsistentMap<K, V> asConsistentMap(long timeoutMillis) {
368 return new DefaultConsistentMap<>(this, timeoutMillis);
369 }
Madan Jampani7c521002015-03-23 12:23:01 -0700370}