blob: 782a1eca5899ec26bc8f24ebee046fff1ba21129 [file] [log] [blame]
Aaron Kruglikov47047b22016-03-31 16:52:48 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
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;
Madan Jampani0463cf92016-05-04 14:46:08 -070020
Aaron Kruglikov47047b22016-03-31 16:52:48 -070021import org.onosproject.store.service.ConsistentMapException;
22import org.onosproject.store.service.AsyncConsistentTreeMap;
23import org.onosproject.store.service.MapEventListener;
24import org.onosproject.store.service.Synchronous;
25import org.onosproject.store.service.ConsistentTreeMap;
26import org.onosproject.store.service.Versioned;
27
28import java.util.Collection;
29import java.util.Map;
Aaron Kruglikov6a164352016-07-25 11:46:17 -070030import java.util.NavigableMap;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070031import java.util.NavigableSet;
32import java.util.Set;
33import java.util.concurrent.CompletableFuture;
34import java.util.concurrent.ExecutionException;
Madan Jampani0463cf92016-05-04 14:46:08 -070035import java.util.concurrent.Executor;
Aaron Kruglikov47047b22016-03-31 16:52:48 -070036import java.util.concurrent.TimeUnit;
37import java.util.concurrent.TimeoutException;
38import java.util.function.BiFunction;
39import java.util.function.Function;
40import java.util.function.Predicate;
41
42/**
43 * Implementation of the {@link ConsistentTreeMap} interface.
44 */
Aaron Kruglikov6a164352016-07-25 11:46:17 -070045public class DefaultConsistentTreeMap<V>
46 extends Synchronous<AsyncConsistentTreeMap<V>>
47 implements ConsistentTreeMap<V> {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070048 private static final int MAX_DELAY_BETWEEN_RETRY_MILLIS = 50;
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) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -070067 Throwables.propagateIfPossible(e.getCause());
68 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
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700180 public Versioned<V> computeIfAbsent(String key,
181 Function<? super String,
182 ? extends V> mappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700183 return complete(treeMap.computeIfAbsent(key, mappingFunction));
184 }
185
186 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700187 public Versioned<V> compute(String key,
188 BiFunction<? super String,
189 ? super V,
190 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700191 return complete(treeMap.compute(key, remappingFunction));
192 }
193
194 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700195 public Versioned<V> computeIfPresent(
196 String key,
197 BiFunction<? super String,
198 ? super V,
199 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700200 return complete(treeMap.computeIfPresent(key, remappingFunction));
201 }
202
203 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700204 public Versioned<V> computeIf(String key, Predicate<? super V> condition,
205 BiFunction<? super String,
206 ? super V,
207 ? extends V> remappingFunction) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700208 return complete(treeMap.computeIf(key, condition, remappingFunction));
209 }
210
211 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700212 public Versioned<V> put(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700213 return complete(treeMap.put(key, value));
214 }
215
216 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700217 public Versioned<V> putAndGet(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700218 return complete(treeMap.putAndGet(key, value));
219 }
220
221 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700222 public Versioned<V> remove(String key) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700223 return complete(treeMap.remove(key));
224 }
225
226 @Override
227 public void clear() {
228 complete(treeMap.clear());
229 }
230
231 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700232 public Set<String> keySet() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700233 return complete(treeMap.keySet());
234 }
235
236 @Override
237 public Collection<Versioned<V>> values() {
238 return complete(treeMap.values());
239 }
240
241 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700242 public Set<Map.Entry<String, Versioned<V>>> entrySet() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700243 return complete(treeMap.entrySet());
244 }
245
246 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700247 public Versioned<V> putIfAbsent(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700248 return complete(treeMap.putIfAbsent(key, value));
249 }
250
251 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700252 public boolean remove(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700253 return complete(treeMap.remove(key, value));
254 }
255
256 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700257 public boolean remove(String key, long version) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700258 return complete(treeMap.remove(key, version));
259 }
260
261 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700262 public Versioned<V> replace(String key, V value) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700263 return complete(treeMap.replace(key, value));
264 }
265
266 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700267 public boolean replace(String key, V oldValue, V newValue) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700268 return complete(treeMap.replace(key, oldValue, newValue));
269 }
270
271 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700272 public boolean replace(String key, long oldVersion, V newValue) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700273 return complete(treeMap.replace(key, oldVersion, newValue));
274 }
275
276 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700277 public void addListener(MapEventListener<String, V> listener,
278 Executor executor) {
Madan Jampani0463cf92016-05-04 14:46:08 -0700279 complete(treeMap.addListener(listener, executor));
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700280 }
281
282 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700283 public void removeListener(MapEventListener<String, V> listener) {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700284 complete(treeMap.removeListener(listener));
285 }
286
287 @Override
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700288 public Map<String, V> asJavaMap() {
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700289 synchronized (this) {
290 if (javaMap == null) {
291 javaMap = new ConsistentMapBackedJavaMap<>(this);
292 }
293 }
294 return javaMap;
295 }
Aaron Kruglikov6a164352016-07-25 11:46:17 -0700296
297 @Override
298 public NavigableMap<String, V> subMap(String upperKey,
299 String lowerKey,
300 boolean inclusiveUpper,
301 boolean inclusiveLower) {
302 return complete(treeMap.subMap(upperKey, lowerKey,
303 inclusiveUpper, inclusiveLower));
304 }
Aaron Kruglikov47047b22016-03-31 16:52:48 -0700305}