blob: 745202ce4e9dc6b0eb1635eb66f36e067410f92b [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;
20import org.onosproject.store.service.ConsistentMapException;
21import org.onosproject.store.service.AsyncConsistentTreeMap;
22import org.onosproject.store.service.MapEventListener;
23import org.onosproject.store.service.Synchronous;
24import org.onosproject.store.service.ConsistentTreeMap;
25import org.onosproject.store.service.Versioned;
26
27import java.util.Collection;
28import java.util.Map;
29import java.util.NavigableSet;
30import java.util.Set;
31import java.util.concurrent.CompletableFuture;
32import java.util.concurrent.ExecutionException;
33import java.util.concurrent.TimeUnit;
34import java.util.concurrent.TimeoutException;
35import java.util.function.BiFunction;
36import java.util.function.Function;
37import java.util.function.Predicate;
38
39/**
40 * Implementation of the {@link ConsistentTreeMap} interface.
41 */
42public class DefaultConsistentTreeMap<K, V> extends Synchronous<AsyncConsistentTreeMap<K, V>>
43 implements ConsistentTreeMap<K, V> {
44 private static final int MAX_DELAY_BETWEEN_RETRY_MILLIS = 50;
45 private final AsyncConsistentTreeMap<K, V> treeMap;
46 private final long operationTimeoutMillis;
47 private Map<K, V> javaMap;
48
49 public DefaultConsistentTreeMap(AsyncConsistentTreeMap<K, V> treeMap, long operationTimeoutMillis) {
50 super(treeMap);
51 this.treeMap = treeMap;
52 this.operationTimeoutMillis = operationTimeoutMillis;
53 }
54
55 private <T> T complete(CompletableFuture<T> future) {
56 try {
57 return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
58 } catch (InterruptedException e) {
59 Thread.currentThread().interrupt();
60 throw new ConsistentMapException.Interrupted();
61 } catch (ExecutionException e) {
62 throw new ConsistentMapException.Timeout();
63 } catch (TimeoutException e) {
64 Throwables.propagateIfPossible(e.getCause());
65 throw new ConsistentMapException(e.getCause());
66 }
67 }
68
69 @Override
70 public K firstKey() {
71 return complete(treeMap.firstKey());
72 }
73
74 @Override
75 public K lastKey() {
76 return complete(treeMap.lastKey());
77 }
78
79 @Override
80 public Map.Entry<K, Versioned<V>> ceilingEntry(K key) {
81 return complete(treeMap.ceilingEntry(key));
82 }
83
84 @Override
85 public Map.Entry<K, Versioned<V>> floorEntry(K key) {
86 return complete(treeMap.floorEntry(key));
87 }
88
89 @Override
90 public Map.Entry<K, Versioned<V>> higherEntry(K key) {
91 return complete(treeMap.higherEntry(key));
92 }
93
94 @Override
95 public Map.Entry<K, Versioned<V>> lowerEntry(K key) {
96 return complete(treeMap.lowerEntry(key));
97 }
98
99 @Override
100 public Map.Entry<K, Versioned<V>> firstEntry() {
101 return complete(treeMap.firstEntry());
102 }
103
104 @Override
105 public Map.Entry<K, Versioned<V>> lastEntry() {
106 return complete(treeMap.lastEntry());
107 }
108
109 @Override
110 public Map.Entry<K, Versioned<V>> pollFirstEntry() {
111 return complete(treeMap.pollFirstEntry());
112 }
113
114 @Override
115 public Map.Entry<K, Versioned<V>> pollLastEntry() {
116 return complete(treeMap.pollLastEntry());
117 }
118
119 @Override
120 public K lowerKey(K key) {
121 return complete(treeMap.lowerKey(key));
122 }
123
124 @Override
125 public K floorKey(K key) {
126 return complete(treeMap.floorKey(key));
127 }
128
129 @Override
130 public K ceilingKey(K key) {
131 return complete(treeMap.ceilingKey(key));
132 }
133
134 @Override
135 public K higherKey(K key) {
136 return complete(treeMap.higherKey(key));
137 }
138
139
140 @Override
141 /**
142 * {@inheritDoc}
143 * <p>This may be a long operation with greater risk of timeout.</p>
144 */
145 public NavigableSet<K> navigableKeySet() {
146 return complete(treeMap.navigableKeySet());
147 }
148
149 @Override
150 public int size() {
151 return complete(treeMap.size());
152 }
153
154 @Override
155 public boolean isEmpty() {
156 return complete(treeMap.isEmpty());
157 }
158
159 @Override
160 public boolean containsKey(K key) {
161 return complete(treeMap.containsKey(key));
162 }
163
164 @Override
165 public boolean containsValue(V value) {
166 return complete(treeMap.containsValue(value));
167 }
168
169 @Override
170 public Versioned<V> get(K key) {
171 return complete(treeMap.get(key));
172 }
173
174 @Override
175 public Versioned<V> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
176 return complete(treeMap.computeIfAbsent(key, mappingFunction));
177 }
178
179 @Override
180 public Versioned<V> compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
181 return complete(treeMap.compute(key, remappingFunction));
182 }
183
184 @Override
185 public Versioned<V> computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
186 return complete(treeMap.computeIfPresent(key, remappingFunction));
187 }
188
189 @Override
190 public Versioned<V> computeIf(K key, Predicate<? super V> condition,
191 BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
192 return complete(treeMap.computeIf(key, condition, remappingFunction));
193 }
194
195 @Override
196 public Versioned<V> put(K key, V value) {
197 return complete(treeMap.put(key, value));
198 }
199
200 @Override
201 public Versioned<V> putAndGet(K key, V value) {
202 return complete(treeMap.putAndGet(key, value));
203 }
204
205 @Override
206 public Versioned<V> remove(K key) {
207 return complete(treeMap.remove(key));
208 }
209
210 @Override
211 public void clear() {
212 complete(treeMap.clear());
213 }
214
215 @Override
216 public Set<K> keySet() {
217 return complete(treeMap.keySet());
218 }
219
220 @Override
221 public Collection<Versioned<V>> values() {
222 return complete(treeMap.values());
223 }
224
225 @Override
226 public Set<Map.Entry<K, Versioned<V>>> entrySet() {
227 return complete(treeMap.entrySet());
228 }
229
230 @Override
231 public Versioned<V> putIfAbsent(K key, V value) {
232 return complete(treeMap.putIfAbsent(key, value));
233 }
234
235 @Override
236 public boolean remove(K key, V value) {
237 return complete(treeMap.remove(key, value));
238 }
239
240 @Override
241 public boolean remove(K key, long version) {
242 return complete(treeMap.remove(key, version));
243 }
244
245 @Override
246 public Versioned<V> replace(K key, V value) {
247 return complete(treeMap.replace(key, value));
248 }
249
250 @Override
251 public boolean replace(K key, V oldValue, V newValue) {
252 return complete(treeMap.replace(key, oldValue, newValue));
253 }
254
255 @Override
256 public boolean replace(K key, long oldVersion, V newValue) {
257 return complete(treeMap.replace(key, oldVersion, newValue));
258 }
259
260 @Override
261 public void addListener(MapEventListener<K, V> listener) {
262 complete(treeMap.addListener(listener));
263 }
264
265 @Override
266 public void removeListener(MapEventListener<K, V> listener) {
267 complete(treeMap.removeListener(listener));
268 }
269
270 @Override
271 public Map<K, V> asJavaMap() {
272 synchronized (this) {
273 if (javaMap == null) {
274 javaMap = new ConsistentMapBackedJavaMap<>(this);
275 }
276 }
277 return javaMap;
278 }
279}