blob: 8f91b3dd1e5a4b7b7abf4062d12e197a00d53516 [file] [log] [blame]
Aaron Kruglikov3e29f662016-07-13 10:18:10 -07001/*
Brian O'Connor0a4e6742016-09-15 23:03:10 -07002 * Copyright 2016-present Open Networking Laboratory
Aaron Kruglikov3e29f662016-07-13 10:18:10 -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.resources.impl;
18
Aaron Kruglikov3e29f662016-07-13 10:18:10 -070019import java.util.Collection;
20import java.util.ConcurrentModificationException;
21import java.util.List;
22import java.util.Map;
23import java.util.NavigableMap;
24import java.util.NavigableSet;
Aaron Kruglikov3e29f662016-07-13 10:18:10 -070025import java.util.Set;
26import java.util.concurrent.CompletableFuture;
27import java.util.concurrent.Executor;
28import java.util.concurrent.atomic.AtomicReference;
29import java.util.function.BiFunction;
30import java.util.function.Predicate;
31
Jordan Halterman2bf177c2017-06-29 01:49:08 -070032import com.google.common.collect.Maps;
33import io.atomix.protocols.raft.proxy.RaftProxy;
34import org.onlab.util.KryoNamespace;
35import org.onlab.util.Match;
36import org.onosproject.store.primitives.MapUpdate;
37import org.onosproject.store.primitives.TransactionId;
38import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FloorEntry;
39import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.HigherEntry;
40import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LowerEntry;
41import org.onosproject.store.serializers.KryoNamespaces;
42import org.onosproject.store.service.AsyncConsistentTreeMap;
43import org.onosproject.store.service.MapEvent;
44import org.onosproject.store.service.MapEventListener;
45import org.onosproject.store.service.Serializer;
46import org.onosproject.store.service.TransactionLog;
47import org.onosproject.store.service.Version;
48import org.onosproject.store.service.Versioned;
49
50import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapEvents.CHANGE;
51import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.ADD_LISTENER;
52import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CEILING_ENTRY;
53import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CEILING_KEY;
54import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CLEAR;
55import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CONTAINS_KEY;
56import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CONTAINS_VALUE;
57import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CeilingEntry;
58import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.CeilingKey;
59import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.ContainsKey;
60import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.ContainsValue;
61import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.ENTRY_SET;
62import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FIRST_ENTRY;
63import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FIRST_KEY;
64import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FLOOR_ENTRY;
65import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FLOOR_KEY;
66import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.FloorKey;
67import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.GET;
68import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.GET_OR_DEFAULT;
69import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.Get;
70import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.GetOrDefault;
71import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.HIGHER_ENTRY;
72import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.HIGHER_KEY;
73import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.HigherKey;
74import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.IS_EMPTY;
75import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.KEY_SET;
76import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LAST_ENTRY;
77import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LAST_KEY;
78import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LOWER_ENTRY;
79import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LOWER_KEY;
80import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.LowerKey;
81import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.POLL_FIRST_ENTRY;
82import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.POLL_LAST_ENTRY;
83import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.REMOVE_LISTENER;
84import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.SIZE;
85import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.UPDATE_AND_GET;
86import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.UpdateAndGet;
87import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapOperations.VALUES;
Aaron Kruglikov3e29f662016-07-13 10:18:10 -070088
89/**
90 * Implementation of {@link AsyncConsistentTreeMap}.
91 */
Jordan Halterman2bf177c2017-06-29 01:49:08 -070092public class AtomixConsistentTreeMap extends AbstractRaftPrimitive implements AsyncConsistentTreeMap<byte[]> {
93 private static final Serializer SERIALIZER = Serializer.using(KryoNamespace.newBuilder()
94 .register(KryoNamespaces.BASIC)
95 .register(AtomixConsistentTreeMapOperations.NAMESPACE)
96 .register(AtomixConsistentTreeMapEvents.NAMESPACE)
97 .build());
Aaron Kruglikov3e29f662016-07-13 10:18:10 -070098
99 private final Map<MapEventListener<String, byte[]>, Executor>
100 mapEventListeners = Maps.newConcurrentMap();
101
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700102 public AtomixConsistentTreeMap(RaftProxy proxy) {
103 super(proxy);
104 proxy.addEventListener(CHANGE, SERIALIZER::decode, this::handleEvent);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700105 }
106
107 private void handleEvent(List<MapEvent<String, byte[]>> events) {
108 events.forEach(event -> mapEventListeners.
109 forEach((listener, executor) ->
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700110 executor.execute(() ->
111 listener.event(event))));
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700112 }
113
114 @Override
115 public CompletableFuture<Boolean> isEmpty() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700116 return proxy.invoke(IS_EMPTY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700117 }
118
119 @Override
120 public CompletableFuture<Integer> size() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700121 return proxy.invoke(SIZE, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700122 }
123
124 @Override
125 public CompletableFuture<Boolean> containsKey(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700126 return proxy.invoke(CONTAINS_KEY, SERIALIZER::encode, new ContainsKey(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700127 }
128
129 @Override
130 public CompletableFuture<Boolean> containsValue(byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700131 return proxy.invoke(CONTAINS_VALUE, SERIALIZER::encode, new ContainsValue(value), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700132 }
133
134 @Override
135 public CompletableFuture<Versioned<byte[]>> get(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700136 return proxy.invoke(GET, SERIALIZER::encode, new Get(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700137 }
138
139 @Override
Jordan Haltermanf6272442017-04-20 02:18:08 -0700140 public CompletableFuture<Versioned<byte[]>> getOrDefault(String key, byte[] defaultValue) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700141 return proxy.invoke(
142 GET_OR_DEFAULT,
143 SERIALIZER::encode,
144 new GetOrDefault(key, defaultValue),
145 SERIALIZER::decode);
Jordan Haltermanf6272442017-04-20 02:18:08 -0700146 }
147
148 @Override
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700149 public CompletableFuture<Set<String>> keySet() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700150 return proxy.invoke(KEY_SET, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700151 }
152
153 @Override
154 public CompletableFuture<Collection<Versioned<byte[]>>> values() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700155 return proxy.invoke(VALUES, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700156 }
157
158 @Override
159 public CompletableFuture<Set<Map.Entry<String, Versioned<byte[]>>>> entrySet() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700160 return proxy.invoke(ENTRY_SET, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700161 }
162
163 @Override
164 @SuppressWarnings("unchecked")
165 public CompletableFuture<Versioned<byte[]>> put(String key, byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700166 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
167 UPDATE_AND_GET,
168 SERIALIZER::encode,
169 new UpdateAndGet(key, value, Match.ANY, Match.ANY),
170 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700171 .whenComplete((r, e) -> throwIfLocked(r.status()))
172 .thenApply(v -> v.oldValue());
173 }
174
175 @Override
176 @SuppressWarnings("unchecked")
177 public CompletableFuture<Versioned<byte[]>> putAndGet(String key, byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700178 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
179 UPDATE_AND_GET,
180 SERIALIZER::encode,
181 new UpdateAndGet(key, value, Match.ANY, Match.ANY),
182 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700183 .whenComplete((r, e) -> throwIfLocked(r.status()))
184 .thenApply(v -> v.newValue());
185 }
186
187 @Override
188 @SuppressWarnings("unchecked")
189 public CompletableFuture<Versioned<byte[]>> putIfAbsent(String key, byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700190 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
191 UPDATE_AND_GET,
192 SERIALIZER::encode,
193 new UpdateAndGet(key, value, Match.NULL, Match.ANY),
194 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700195 .whenComplete((r, e) -> throwIfLocked(r.status()))
196 .thenApply(v -> v.oldValue());
197 }
198
199 @Override
200 @SuppressWarnings("unchecked")
201 public CompletableFuture<Versioned<byte[]>> remove(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700202 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
203 UPDATE_AND_GET,
204 SERIALIZER::encode,
205 new UpdateAndGet(key, null, Match.ANY, Match.ANY),
206 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700207 .whenComplete((r, e) -> throwIfLocked(r.status()))
208 .thenApply(v -> v.oldValue());
209 }
210
211 @Override
212 @SuppressWarnings("unchecked")
213 public CompletableFuture<Boolean> remove(String key, byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700214 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
215 UPDATE_AND_GET,
216 SERIALIZER::encode,
217 new UpdateAndGet(key, null, Match.ifValue(value), Match.ANY),
218 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700219 .whenComplete((r, e) -> throwIfLocked(r.status()))
220 .thenApply(v -> v.updated());
221 }
222
223 @Override
224 @SuppressWarnings("unchecked")
225 public CompletableFuture<Boolean> remove(String key, long version) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700226 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
227 UPDATE_AND_GET,
228 SERIALIZER::encode,
229 new UpdateAndGet(key, null, Match.ANY, Match.ifValue(version)),
230 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700231 .whenComplete((r, e) -> throwIfLocked(r.status()))
232 .thenApply(v -> v.updated());
233 }
234
235 @Override
236 @SuppressWarnings("unchecked")
237 public CompletableFuture<Versioned<byte[]>> replace(String key, byte[] value) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700238 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
239 UPDATE_AND_GET,
240 SERIALIZER::encode,
241 new UpdateAndGet(key, value, Match.NOT_NULL, Match.ANY),
242 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700243 .whenComplete((r, e) -> throwIfLocked(r.status()))
244 .thenApply(v -> v.oldValue());
245 }
246
247 @Override
248 @SuppressWarnings("unchecked")
249 public CompletableFuture<Boolean> replace(String key, byte[] oldValue, byte[] newValue) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700250 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
251 UPDATE_AND_GET,
252 SERIALIZER::encode,
253 new UpdateAndGet(key, newValue, Match.ifValue(oldValue), Match.ANY),
254 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700255 .whenComplete((r, e) -> throwIfLocked(r.status()))
256 .thenApply(v -> v.updated());
257 }
258
259 @Override
260 @SuppressWarnings("unchecked")
261 public CompletableFuture<Boolean> replace(String key, long oldVersion, byte[] newValue) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700262 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
263 UPDATE_AND_GET,
264 SERIALIZER::encode,
265 new UpdateAndGet(key, newValue, Match.ANY, Match.ifValue(oldVersion)),
266 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700267 .whenComplete((r, e) -> throwIfLocked(r.status()))
268 .thenApply(v -> v.updated());
269 }
270
271 @Override
272 public CompletableFuture<Void> clear() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700273 return proxy.<MapEntryUpdateResult.Status>invoke(CLEAR, SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700274 .whenComplete((r, e) -> throwIfLocked(r))
275 .thenApply(v -> null);
276 }
277
278 @Override
279 @SuppressWarnings("unchecked")
280 public CompletableFuture<Versioned<byte[]>> computeIf(String key,
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700281 Predicate<? super byte[]> condition,
282 BiFunction<? super String,
283 ? super byte[],
284 ? extends byte[]> remappingFunction) {
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700285 return get(key).thenCompose(r1 -> {
286 byte[] existingValue = r1 == null ? null : r1.value();
287
288 if (!condition.test(existingValue)) {
289 return CompletableFuture.completedFuture(r1);
290 }
291
292 AtomicReference<byte[]> computedValue = new AtomicReference<byte[]>();
293 try {
294 computedValue.set(remappingFunction.apply(key, existingValue));
295 } catch (Exception e) {
296 CompletableFuture<Versioned<byte[]>> future = new CompletableFuture<>();
297 future.completeExceptionally(e);
298 return future;
299 }
300 if (computedValue.get() == null && r1 == null) {
301 return CompletableFuture.completedFuture(null);
302 }
303 Match<byte[]> valueMatch = r1 == null ? Match.NULL : Match.ANY;
304 Match<Long> versionMatch = r1 == null ? Match.ANY : Match.ifValue(r1.version());
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700305 return proxy.<UpdateAndGet, MapEntryUpdateResult<String, byte[]>>invoke(
306 UPDATE_AND_GET,
307 SERIALIZER::encode,
308 new UpdateAndGet(key, computedValue.get(), valueMatch, versionMatch),
309 SERIALIZER::decode)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700310 .whenComplete((r, e) -> throwIfLocked(r.status()))
311 .thenApply(v -> v.newValue());
312 });
313 }
314
315 @Override
316 public CompletableFuture<Void> addListener(
317 MapEventListener<String, byte[]> listener, Executor executor) {
318 if (mapEventListeners.isEmpty()) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700319 return proxy.invoke(ADD_LISTENER).thenRun(() ->
320 mapEventListeners.put(listener,
321 executor));
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700322 } else {
323 mapEventListeners.put(listener, executor);
324 return CompletableFuture.completedFuture(null);
325 }
326 }
327
328 @Override
329 public synchronized CompletableFuture<Void> removeListener(MapEventListener<String, byte[]> listener) {
330 if (mapEventListeners.remove(listener) != null &&
331 mapEventListeners.isEmpty()) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700332 return proxy.invoke(REMOVE_LISTENER)
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700333 .thenApply(v -> null);
334 }
335 return CompletableFuture.completedFuture(null);
336 }
337
338
339 private void throwIfLocked(MapEntryUpdateResult.Status status) {
340 if (status == MapEntryUpdateResult.Status.WRITE_LOCK) {
341 throw new ConcurrentModificationException("Cannot update TreeMap: another update is in progress.");
342 }
343 }
344
345 @Override
346 public CompletableFuture<String> firstKey() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700347 return proxy.invoke(FIRST_KEY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700348 }
349
350 @Override
351 public CompletableFuture<String> lastKey() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700352 return proxy.invoke(LAST_KEY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700353 }
354
355 @Override
356 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> ceilingEntry(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700357 return proxy.invoke(CEILING_ENTRY, SERIALIZER::encode, new CeilingEntry(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700358 }
359
360 @Override
361 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> floorEntry(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700362 return proxy.invoke(FLOOR_ENTRY, SERIALIZER::encode, new FloorEntry(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700363 }
364
365 @Override
366 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> higherEntry(
367 String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700368 return proxy.invoke(HIGHER_ENTRY, SERIALIZER::encode, new HigherEntry(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700369 }
370
371 @Override
372 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> lowerEntry(
373 String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700374 return proxy.invoke(LOWER_ENTRY, SERIALIZER::encode, new LowerEntry(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700375 }
376
377 @Override
378 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> firstEntry() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700379 return proxy.invoke(FIRST_ENTRY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700380 }
381
382 @Override
383 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> lastEntry() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700384 return proxy.invoke(LAST_ENTRY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700385 }
386
387 @Override
388 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> pollFirstEntry() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700389 return proxy.invoke(POLL_FIRST_ENTRY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700390 }
391
392 @Override
393 public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> pollLastEntry() {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700394 return proxy.invoke(POLL_LAST_ENTRY, SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700395 }
396
397 @Override
398 public CompletableFuture<String> lowerKey(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700399 return proxy.invoke(LOWER_KEY, SERIALIZER::encode, new LowerKey(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700400 }
401
402 @Override
403 public CompletableFuture<String> floorKey(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700404 return proxy.invoke(FLOOR_KEY, SERIALIZER::encode, new FloorKey(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700405 }
406
407 @Override
408 public CompletableFuture<String> ceilingKey(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700409 return proxy.invoke(CEILING_KEY, SERIALIZER::encode, new CeilingKey(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700410 }
411
412 @Override
413 public CompletableFuture<String> higherKey(String key) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700414 return proxy.invoke(HIGHER_KEY, SERIALIZER::encode, new HigherKey(key), SERIALIZER::decode);
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700415 }
416
417 @Override
418 public CompletableFuture<NavigableSet<String>> navigableKeySet() {
Jordan Halterman948d6592017-04-20 17:18:24 -0700419 throw new UnsupportedOperationException("This operation is not yet supported.");
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700420 }
421
422 @Override
423 public CompletableFuture<NavigableMap<String, byte[]>> subMap(
424 String upperKey, String lowerKey, boolean inclusiveUpper,
425 boolean inclusiveLower) {
Jordan Halterman948d6592017-04-20 17:18:24 -0700426 throw new UnsupportedOperationException("This operation is not yet supported.");
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700427 }
428
429 @Override
Jordan Halterman948d6592017-04-20 17:18:24 -0700430 public CompletableFuture<Version> begin(TransactionId transactionId) {
431 throw new UnsupportedOperationException("This operation is not yet supported.");
432 }
433
434 @Override
435 public CompletableFuture<Boolean> prepare(TransactionLog<MapUpdate<String, byte[]>> transactionLog) {
436 throw new UnsupportedOperationException("This operation is not yet supported.");
437 }
438
439 @Override
440 public CompletableFuture<Boolean> prepareAndCommit(TransactionLog<MapUpdate<String, byte[]>> transactionLog) {
441 throw new UnsupportedOperationException("This operation is not yet supported.");
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700442 }
443
444 @Override
445 public CompletableFuture<Void> commit(TransactionId transactionId) {
Jordan Halterman948d6592017-04-20 17:18:24 -0700446 throw new UnsupportedOperationException("This operation is not yet supported.");
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700447 }
448
449 @Override
450 public CompletableFuture<Void> rollback(TransactionId transactionId) {
Jordan Halterman948d6592017-04-20 17:18:24 -0700451 throw new UnsupportedOperationException("This operation is not yet supported.");
Aaron Kruglikov3e29f662016-07-13 10:18:10 -0700452 }
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700453}