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