blob: 7ccf8c7f19b2608497c5f3788828790398e27528 [file] [log] [blame]
Aaron Kruglikov47047b22016-03-31 16:52:48 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Aaron Kruglikov47047b22016-03-31 16:52:48 -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.primitives;
18
19import com.google.common.base.Throwables;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070020import org.onosproject.store.service.AsyncConsistentTreeMap;
Jordan Haltermandae11602018-07-03 00:00:47 -070021import org.onosproject.store.service.AsyncIterator;
Ray Milkey6a51cb92018-03-06 09:03:03 -080022import org.onosproject.store.service.ConsistentMapException;
23import org.onosproject.store.service.ConsistentTreeMap;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070024import org.onosproject.store.service.MapEventListener;
25import org.onosproject.store.service.Synchronous;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070026import org.onosproject.store.service.Versioned;
27
28import java.util.Collection;
Jordan Haltermandae11602018-07-03 00:00:47 -070029import java.util.Iterator;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070030import java.util.Map;
Aaron Kruglikov6a164352016-07-25 11:46:17 -070031import java.util.NavigableMap;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070032import java.util.NavigableSet;
33import java.util.Set;
34import java.util.concurrent.CompletableFuture;
35import java.util.concurrent.ExecutionException;
Madan Jampani0463cf92016-05-04 14:46:08 -070036import java.util.concurrent.Executor;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070037import java.util.concurrent.TimeUnit;
38import java.util.concurrent.TimeoutException;
39import java.util.function.BiFunction;
40import java.util.function.Function;
41import java.util.function.Predicate;
42
43/**
44 * Implementation of the {@link ConsistentTreeMap} interface.
45 */
Aaron Kruglikov6a164352016-07-25 11:46:17 -070046public class DefaultConsistentTreeMap<V>
47 extends Synchronous<AsyncConsistentTreeMap<V>>
48 implements ConsistentTreeMap<V> {
Aaron Kruglikov6a164352016-07-25 11:46:17 -070049 private final AsyncConsistentTreeMap<V> treeMap;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070050 private final long operationTimeoutMillis;
Aaron Kruglikov6a164352016-07-25 11:46:17 -070051 private Map<String, V> javaMap;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070052
Aaron Kruglikov6a164352016-07-25 11:46:17 -070053 public DefaultConsistentTreeMap(AsyncConsistentTreeMap<V> treeMap,
54 long operationTimeoutMillis) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070055 super(treeMap);
56 this.treeMap = treeMap;
57 this.operationTimeoutMillis = operationTimeoutMillis;
58 }
59
60 private <T> T complete(CompletableFuture<T> future) {
61 try {
62 return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
63 } catch (InterruptedException e) {
64 Thread.currentThread().interrupt();
65 throw new ConsistentMapException.Interrupted();
66 } catch (ExecutionException e) {
Ray Milkey6a51cb92018-03-06 09:03:03 -080067 Throwables.throwIfUnchecked(e.getCause());
Aaron Kruglikov47047b22016-03-31 16:52:48 -070068 throw new ConsistentMapException(e.getCause());
Yuta HIGUCHIf13b3df2016-07-25 12:13:22 -070069 } catch (TimeoutException e) {
70 throw new ConsistentMapException.Timeout();
Aaron Kruglikov47047b22016-03-31 16:52:48 -070071 }
72 }
73
74 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -070075 public String firstKey() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070076 return complete(treeMap.firstKey());
77 }
78
79 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -070080 public String lastKey() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070081 return complete(treeMap.lastKey());
82 }
83
84 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -070085 public Map.Entry<String, Versioned<V>> ceilingEntry(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070086 return complete(treeMap.ceilingEntry(key));
87 }
88
89 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -070090 public Map.Entry<String, Versioned<V>> floorEntry(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070091 return complete(treeMap.floorEntry(key));
92 }
93
94 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -070095 public Map.Entry<String, Versioned<V>> higherEntry(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070096 return complete(treeMap.higherEntry(key));
97 }
98
99 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700100 public Map.Entry<String, Versioned<V>> lowerEntry(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700101 return complete(treeMap.lowerEntry(key));
102 }
103
104 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700105 public Map.Entry<String, Versioned<V>> firstEntry() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700106 return complete(treeMap.firstEntry());
107 }
108
109 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700110 public Map.Entry<String, Versioned<V>> lastEntry() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700111 return complete(treeMap.lastEntry());
112 }
113
114 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700115 public Map.Entry<String, Versioned<V>> pollFirstEntry() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700116 return complete(treeMap.pollFirstEntry());
117 }
118
119 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700120 public Map.Entry<String, Versioned<V>> pollLastEntry() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700121 return complete(treeMap.pollLastEntry());
122 }
123
124 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700125 public String lowerKey(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700126 return complete(treeMap.lowerKey(key));
127 }
128
129 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700130 public String floorKey(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700131 return complete(treeMap.floorKey(key));
132 }
133
134 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700135 public String ceilingKey(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700136 return complete(treeMap.ceilingKey(key));
137 }
138
139 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700140 public String higherKey(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700141 return complete(treeMap.higherKey(key));
142 }
143
144
145 @Override
146 /**
147 * {@inheritDoc}
148 * <p>This may be a long operation with greater risk of timeout.</p>
149 */
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700150 public NavigableSet<String> navigableKeySet() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700151 return complete(treeMap.navigableKeySet());
152 }
153
154 @Override
155 public int size() {
156 return complete(treeMap.size());
157 }
158
159 @Override
160 public boolean isEmpty() {
161 return complete(treeMap.isEmpty());
162 }
163
164 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700165 public boolean containsKey(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700166 return complete(treeMap.containsKey(key));
167 }
168
169 @Override
170 public boolean containsValue(V value) {
171 return complete(treeMap.containsValue(value));
172 }
173
174 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700175 public Versioned<V> get(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700176 return complete(treeMap.get(key));
177 }
178
179 @Override
Jordan Haltermanf6272442017-04-20 02:18:08 -0700180 public Versioned<V> getOrDefault(String key, V defaultValue) {
181 return complete(treeMap.getOrDefault(key, defaultValue));
182 }
183
184 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700185 public Versioned<V> computeIfAbsent(String key,
186 Function<? super String,
187 ? extends V> mappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700188 return complete(treeMap.computeIfAbsent(key, mappingFunction));
189 }
190
191 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700192 public Versioned<V> compute(String key,
193 BiFunction<? super String,
194 ? super V,
195 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700196 return complete(treeMap.compute(key, remappingFunction));
197 }
198
199 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700200 public Versioned<V> computeIfPresent(
201 String key,
202 BiFunction<? super String,
203 ? super V,
204 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700205 return complete(treeMap.computeIfPresent(key, remappingFunction));
206 }
207
208 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700209 public Versioned<V> computeIf(String key, Predicate<? super V> condition,
210 BiFunction<? super String,
211 ? super V,
212 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700213 return complete(treeMap.computeIf(key, condition, remappingFunction));
214 }
215
216 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700217 public Versioned<V> put(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700218 return complete(treeMap.put(key, value));
219 }
220
221 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700222 public Versioned<V> putAndGet(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700223 return complete(treeMap.putAndGet(key, value));
224 }
225
226 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700227 public Versioned<V> remove(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700228 return complete(treeMap.remove(key));
229 }
230
231 @Override
232 public void clear() {
233 complete(treeMap.clear());
234 }
235
236 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700237 public Set<String> keySet() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700238 return complete(treeMap.keySet());
239 }
240
241 @Override
242 public Collection<Versioned<V>> values() {
243 return complete(treeMap.values());
244 }
245
246 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700247 public Set<Map.Entry<String, Versioned<V>>> entrySet() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700248 return complete(treeMap.entrySet());
249 }
250
251 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700252 public Versioned<V> putIfAbsent(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700253 return complete(treeMap.putIfAbsent(key, value));
254 }
255
256 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700257 public boolean remove(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700258 return complete(treeMap.remove(key, value));
259 }
260
261 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700262 public boolean remove(String key, long version) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700263 return complete(treeMap.remove(key, version));
264 }
265
266 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700267 public Versioned<V> replace(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700268 return complete(treeMap.replace(key, value));
269 }
270
271 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700272 public boolean replace(String key, V oldValue, V newValue) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700273 return complete(treeMap.replace(key, oldValue, newValue));
274 }
275
276 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700277 public boolean replace(String key, long oldVersion, V newValue) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700278 return complete(treeMap.replace(key, oldVersion, newValue));
279 }
280
281 @Override
Jordan Haltermandae11602018-07-03 00:00:47 -0700282 public Iterator<Map.Entry<String, Versioned<V>>> iterator() {
283 return new DefaultIterator<>(complete(treeMap.iterator()));
284 }
285
286 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700287 public void addListener(MapEventListener<String, V> listener,
288 Executor executor) {
Madan Jampani0463cf92016-05-04 14:46:08 -0700289 complete(treeMap.addListener(listener, executor));
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700290 }
291
292 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700293 public void removeListener(MapEventListener<String, V> listener) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700294 complete(treeMap.removeListener(listener));
295 }
296
Jordan Haltermandae11602018-07-03 00:00:47 -0700297 private class DefaultIterator<K, V> implements Iterator<Map.Entry<K, Versioned<V>>> {
298 private final AsyncIterator<Map.Entry<K, Versioned<V>>> iterator;
299
300 public DefaultIterator(AsyncIterator<Map.Entry<K, Versioned<V>>> iterator) {
301 this.iterator = iterator;
302 }
303
304 @Override
305 public boolean hasNext() {
306 return complete(iterator.hasNext());
307 }
308
309 @Override
310 public Map.Entry<K, Versioned<V>> next() {
311 return complete(iterator.next());
312 }
313 }
314
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700315 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700316 public Map<String, V> asJavaMap() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700317 synchronized (this) {
318 if (javaMap == null) {
319 javaMap = new ConsistentMapBackedJavaMap<>(this);
320 }
321 }
322 return javaMap;
323 }
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700324
325 @Override
326 public NavigableMap<String, V> subMap(String upperKey,
327 String lowerKey,
328 boolean inclusiveUpper,
329 boolean inclusiveLower) {
330 return complete(treeMap.subMap(upperKey, lowerKey,
331 inclusiveUpper, inclusiveLower));
332 }
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700333}