
io.atomix.collections.DistributedMap Maven / Gradle / Ivy
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.atomix.collections;
import io.atomix.collections.internal.MapCommands;
import io.atomix.collections.util.DistributedMapFactory;
import io.atomix.copycat.client.CopycatClient;
import io.atomix.resource.AbstractResource;
import io.atomix.resource.ReadConsistency;
import io.atomix.resource.ResourceTypeInfo;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Stores a map of keys to values.
*
* The distributed map stores a map of keys and values via an interface similar to that of {@link Map}.
* Map entries are stored in memory on each stateful node and backed by disk, thus the size of the map is
* limited to the available memory on the smallest node in the cluster. This map requires non-null keys but
* supports {@code null} values. All keys and values must be serializable by a
* {@link io.atomix.catalyst.serializer.Serializer}. Serializable types include implementations of
* {@link java.io.Serializable} or {@link io.atomix.catalyst.serializer.CatalystSerializable}. See the
* serialization API for more information.
*
* A {@code DistributedMap} can be created either via the {@code Atomix} API or by wrapping a {@link CopycatClient}
* directly. To create a map via the Atomix API, use the {@code getMap} factory method:
*
* {@code
* DistributedMap map = atomix.getMap("foo").get();
* }
*
* Maps are distributed and are referenced by the map name. If a value is {@link #put(Object, Object)} in
* a map on one node, that value is immediately available for {@link #get(Object) reading} by any other node
* in the cluster by operating on the same map.
*
* In addition to supporting normal {@link java.util.Map} methods, this implementation supports values
* with TTLs. When a key is set with a TTL, the value will expire and be automatically evicted from the map
* some time after the TTL.
*
* @param The map key type.
* @param The map entry type.
* @author Jordan Halterman
*/
@ResourceTypeInfo(id=-11, factory=DistributedMapFactory.class)
public class DistributedMap extends AbstractResource> {
public DistributedMap(CopycatClient client) {
this(client, new Options());
}
public DistributedMap(CopycatClient client, Properties options) {
super(client, options);
}
/**
* Returns {@code true} if the map is empty.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, empty checks
* may return stale results. To perform a fully consistent empty check, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).isEmpty().thenAccept(isEmpty -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.isEmpty().get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.isEmpty().thenAccept(isEmpty -> {
* ...
* });
* }
*
*
* @return A completable future to be completed with a boolean value indicating whether the map is empty.
*/
public CompletableFuture isEmpty() {
return client.submit(new MapCommands.IsEmpty());
}
/**
* Returns {@code true} if the map is empty.
*
* Note that depending on the {@link ReadConsistency}, empty checks may return stale results. To perform a fully
* consistent empty check, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.isEmpty(ReadConsistency.ATOMIC).thenAccept(isEmpty -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.isEmpty(ReadConsistency.ATOMIC).get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.isEmpty(ReadConsistency.ATOMIC).thenAccept(isEmpty -> {
* ...
* });
* }
*
*
* @param consistency The read consistency level.
* @return A completable future to be completed with a boolean value indicating whether the map is empty.
*/
public CompletableFuture isEmpty(ReadConsistency consistency) {
return client.submit(new MapCommands.IsEmpty(consistency.level()));
}
/**
* Gets the number of key-value pairs in the map.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, size checks
* may return stale results. To perform a fully consistent size check, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).size().thenAccept(size -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* int size = map.size().get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.size().thenAccept(size -> {
* ...
* });
* }
*
*
* @return A completable future to be completed with the number of entries in the map.
*/
public CompletableFuture size() {
return client.submit(new MapCommands.Size());
}
/**
* Gets the number of key-value pairs in the map.
*
* Note that depending on the {@link ReadConsistency}, size checks may return stale results. To perform a
* fully consistent size check, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.size(ReadConsistency.ATOMIC).thenAccept(size -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* int size = map.size(ReadConsistency.ATOMIC).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.size(ReadConsistency.ATOMIC).thenAccept(size -> {
* ...
* });
* }
*
*
* @param consistency The read consistency level.
* @return A completable future to be completed with the number of entries in the map.
*/
public CompletableFuture size(ReadConsistency consistency) {
return client.submit(new MapCommands.Size(consistency.level()));
}
/**
* Returns {@code true} if the given key is present in the map.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, checks
* may return stale results. To perform a fully consistent check, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).containsKey("foo").thenAccept(contains -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.containsKey("foo").get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.containsKey("foo").thenAccept(contains -> {
* ...
* });
* }
*
*
* @param key The key to check.
* @return A completable future to be completed with a boolean indicating whether {@code key} is present in the map.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture containsKey(Object key) {
return client.submit(new MapCommands.ContainsKey(key));
}
/**
* Returns {@code true} if the given key is present in the map.
*
* Note that depending on the {@link ReadConsistency}, checks may return stale results. To perform a fully
* consistent check, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.containsKey("foo", ReadConsistency.ATOMIC).thenAccept(contains -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.containsKey("foo", ReadConsistency.ATOMIC).get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.containsKey("foo", ReadConsistency.ATOMIC).thenAccept(contains -> {
* ...
* });
* }
*
*
* @param key The key to check.
* @param consistency The read consistency level.
* @return A completable future to be completed with a boolean indicating whether {@code key} is present in the map.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture containsKey(Object key, ReadConsistency consistency) {
return client.submit(new MapCommands.ContainsKey(key, consistency.level()));
}
/**
* Returns {@code true} if the map contains a key with the given value.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, checks
* may return stale results. To perform a fully consistent check, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).containsValue("foo").thenAccept(contains -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.containsValue("foo").get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.containsValue("foo").thenAccept(contains -> {
* ...
* });
* }
*
*
* @param value The value for which to search keys.
* @return A completable future to be completed with a boolean indicating whether {@code key} is present in the map.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture containsValue(Object value) {
return client.submit(new MapCommands.ContainsValue(value));
}
/**
* Returns {@code true} if the map contains a key with the given value.
*
* Note that depending on the {@link ReadConsistency}, checks may return stale results. To perform a fully
* consistent check, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.containsValue("foo", ReadConsistency.ATOMIC).thenAccept(contains -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* if (map.containsValue("foo", ReadConsistency.ATOMIC).get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.containsValue("foo", ReadConsistency.ATOMIC).thenAccept(contains -> {
* ...
* });
* }
*
*
* @param value The value for which to search keys.
* @param consistency The read consistency level.
* @return A completable future to be completed with a boolean indicating whether {@code key} is present in the map.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture containsValue(Object value, ReadConsistency consistency) {
return client.submit(new MapCommands.ContainsValue(value, consistency.level()));
}
/**
* Gets a value from the map.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, queries
* may return stale results. To perform a fully consistent query, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).get("key").thenAccept(value -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* String value = map.get("key").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.get("key").thenAccept(value -> {
* ...
* });
* }
*
*
* @param key The key to get.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture get(Object key) {
return client.submit(new MapCommands.Get(key)).thenApply(result -> (V) result);
}
/**
* Gets a value from the map.
*
* Note that depending on the {@link ReadConsistency}, queries may return stale results. To perform a fully
* consistent query, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.get("key", ReadConsistency.ATOMIC).thenAccept(value -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* String value = map.get("key", ReadConsistency.ATOMIC).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.get("key", ReadConsistency.ATOMIC).thenAccept(value -> {
* ...
* });
* }
*
*
* @param key The key to get.
* @param consistency The read consistency level.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture get(Object key, ReadConsistency consistency) {
return client.submit(new MapCommands.Get(key, consistency.level())).thenApply(result -> (V) result);
}
/**
* Gets the value of {@code key} or returns the given default value if {@code key} does not exist.
*
* If no value for the given {@code key} is present in the map, the returned {@link CompletableFuture} will
* be completed {@code null}. If a value is present, the returned future will be completed with that value.
*
* Note that depending on the configured {@link ReadConsistency} of the map instance, queries
* may return stale results. To perform a fully consistent query, configure the map with
* {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.with(Consistency.ATOMIC).getOrDefault("key", "Hello world!").thenAccept(value -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* String valueOrDefault = map.getOrDefault("key", "Hello world!").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.getOrDefault("key", "Hello world!").thenAccept(valueOrDefault -> {
* ...
* });
* }
*
*
* @param key The key to get.
* @param defaultValue The default value to return if the key does not exist.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture getOrDefault(Object key, V defaultValue) {
return client.submit(new MapCommands.GetOrDefault(key, defaultValue)).thenApply(result -> (V) result);
}
/**
* Gets the value of {@code key} or returns the given default value if {@code key} does not exist.
*
* If no value for the given {@code key} is present in the map, the returned {@link CompletableFuture} will
* be completed {@code null}. If a value is present, the returned future will be completed with that value.
*
* Note that depending on the {@link ReadConsistency}, queries may return stale results. To perform a fully
* consistent query, use {@link ReadConsistency#ATOMIC} consistency (the default).
*
* {@code
* map.getOrDefault("key", "Hello world!", ReadConsistency.ATOMIC).thenAccept(value -> {
* ...
* });
* }
*
* For better performance with potentially stale results, use a lower consistency level. See the
* {@link ReadConsistency} documentation for specific consistency guarantees.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} method to block the calling thread:
*
* {@code
* String valueOrDefault = map.getOrDefault("key", "Hello world!", ReadConsistency.ATOMIC).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.getOrDefault("key", "Hello world!", ReadConsistency.ATOMIC).thenAccept(valueOrDefault -> {
* ...
* });
* }
*
*
* @param key The key to get.
* @param defaultValue The default value to return if the key does not exist.
* @param consistency The read consistency level.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture getOrDefault(Object key, V defaultValue, ReadConsistency consistency) {
return client.submit(new MapCommands.GetOrDefault(key, defaultValue, consistency.level())).thenApply(result -> (V) result);
}
/**
* Puts a value in the map for the given {@code key}.
*
* Any previous value associated with the given {@code key} will be overridden. Additionally, if the previous value
* was set with a TTL, the TTL will be cancelled and this value will be set with no TTL.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.put("key", "Hello world!").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.put("key", "Hello world!").thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to set.
* @param value The value to set.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture put(K key, V value) {
return client.submit(new MapCommands.Put(key, value)).thenApply(result -> (V) result);
}
/**
* Puts a value in the map with a time-to-live for the given {@code key}.
*
* Any previous value associated with the given {@code key} will be overridden. Additionally, if the previous value
* was set with a TTL, the TTL will be cancelled and this value's TTL will be set.
*
* The {@code value} will remain in the map until the provided {@link Duration} of time has elapsed or it is overridden
* by a more recent put operation. Note that the provided {@code ttl} should only be considered an estimate of time.
* Values may be evicted at some arbitrary point after the provided duration has elapsed, but never before.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.put("key", "Hello world!", Duration.ofSeconds(10)).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.put("key", "Hello world!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to set.
* @param value The value to set.
* @param ttl The duration after which to expire the key.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture put(K key, V value, Duration ttl) {
return client.submit(new MapCommands.Put(key, value, ttl.toMillis())).thenApply(result -> (V) result);
}
/**
* Puts a value in the map if the given {@code key} does not exist.
*
* If the given {@code key} is not already present in the map, the key will be set to the given {@code value}.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.put("key", "Hello world!").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.put("key", "Hello world!").thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to set.
* @param value The value to set if the given key does not exist.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture putIfAbsent(K key, V value) {
return client.submit(new MapCommands.PutIfAbsent(key, value)).thenApply(result -> (V) result);
}
/**
* Puts a value with a time-to-live in the map if the given {@code key} does not exist.
*
* If the given {@code key} is not already present in the map, the key will be set to the given {@code value}.
*
* The {@code value} will remain in the map until the provided {@link Duration} of time has elapsed or it is overridden
* by a more recent put operation. Note that the provided {@code ttl} should only be considered an estimate of time.
* Values may be evicted at some arbitrary point after the provided duration has elapsed, but never before.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.put("key", "Hello world!", Duration.ofSeconds(10)).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.put("key", "Hello world!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to set.
* @param value The value to set if the given key does not exist.
* @param ttl The time to live duration.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture putIfAbsent(K key, V value, Duration ttl) {
return client.submit(new MapCommands.PutIfAbsent(key, value, ttl.toMillis())).thenApply(result -> (V) result);
}
/**
* Removes a the value for the given {@code key} from the map.
*
* If no value for the given {@code key} is present in the map, the returned {@link CompletableFuture} will
* be completed {@code null}. If a value is present, that value will be removed from the distributed map and the
* returned future will be completed with that value. If the previous value was set with a TTL, the TTL will
* be cancelled.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.remove("key").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.remove("key").thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to remove.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture remove(Object key) {
return client.submit(new MapCommands.Remove(key)).thenApply(result -> (V) result);
}
/**
* Removes the given {@code key} from the map if its value matches the given {@code value}.
*
* If no value for the given {@code key} is present in the map or if the value doesn't match the provided {@code value},
* the returned {@link CompletableFuture} will be completed {@code false}. If a value is present and matches {@code value},
* that value will be removed from the distributed map and the returned future will be completed {@code true}. If the
* previous value was set with a TTL, the TTL will be cancelled.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* if (map.remove("key", "Hello world!").get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.remove("key", "Hello world!").thenAccept(removed -> {
* ...
* });
* }
*
*
* @param key The key to remove.
* @param value The value to remove.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture remove(K key, V value) {
return client.submit(new MapCommands.RemoveIfPresent(key, value));
}
/**
* Replaces a value in the map if the {@code key} exists.
*
* If the given {@code key} is not already present in the map, no change will be made and {@code null} will be returned.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.replace("key", "Hello world!").get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.replace("key", "Hello world!").thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to replace.
* @param value The value with which to replace the key if it exists.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture replace(K key, V value) {
return client.submit(new MapCommands.Replace(key, value)).thenApply(result -> (V) result);
}
/**
* Replaces a value in the map if the {@code key} exist.
*
* If the given {@code key} is not already present in the map, no change will be made and {@code null} will be returned.
*
* If the value is successfully replaced, the {@code value} will remain in the map until the provided {@link Duration}
* of time has elapsed or it is overridden by a more recent put operation. Note that the provided {@code ttl} should
* only be considered an estimate of time. Values may be evicted at some arbitrary point after the provided duration
* has elapsed, but never before.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* String oldValue = map.replace("key", "Hello world!", Duration.ofSeconds(10)).get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.replace("key", "Hello world!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to replace.
* @param value The value with which to replace the key if it exists.
* @param ttl The duration after which to expire the key/value.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture replace(K key, V value, Duration ttl) {
return client.submit(new MapCommands.Replace(key, value, ttl.toMillis())).thenApply(result -> (V) result);
}
/**
* Replaces a value in the map.
*
* If the given {@code key} is not already present in the map, no change will be made and {@code null} will be returned.
* If the key is present and its value matches {@code oldValue}, it will be updated with {@code newValue}.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* if (map.replace("key", "Hello world!", "Hello world again!").get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.replace("key", "Hello world!", "Hello world again!").thenAccept(replaced -> {
* ...
* });
* }
*
*
* @param key The key to replace.
* @param oldValue The value to check.
* @param newValue The value to replace.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
public CompletableFuture replace(K key, V oldValue, V newValue) {
return client.submit(new MapCommands.ReplaceIfPresent(key, oldValue, newValue));
}
/**
* Replaces a value in the map with a time-to-live.
*
* If the given {@code key} is not already present in the map, no change will be made and {@code null} will be returned.
* If the key is present and its value matches {@code oldValue}, it will be updated with {@code newValue}.
*
* If the value is successfully replaced, the {@code value} will remain in the map until the provided {@link Duration}
* of time has elapsed or it is overridden by a more recent put operation. Note that the provided {@code ttl} should
* only be considered an estimate of time. Values may be evicted at some arbitrary point after the provided duration
* has elapsed, but never before.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* if (map.replace("key", "Hello world!", "Hello world again!", Duration.ofSeconds(10)).get()) {
* ...
* }
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.replace("key", "Hello world!", "Hello world again!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @param key The key to replace.
* @param oldValue The value to check.
* @param newValue The value to replace.
* @param ttl The duration after which to expire the key/value.
* @return A completable future to be completed with the result once complete.
* @throws NullPointerException if {@code key} is {@code null}
*/
@SuppressWarnings("unchecked")
public CompletableFuture replace(K key, V oldValue, V newValue, Duration ttl) {
return client.submit(new MapCommands.ReplaceIfPresent(key, oldValue, newValue, ttl.toMillis()));
}
/**
* Reads the set of all keys in the map.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* Set keys = map.keySet().get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.keySet().thenAccept(keys -> {
* keys.forEach(key -> ...);
* });
* map.replace("key", "Hello world!", "Hello world again!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @return A completable future to be completed with the result once complete.
*/
@SuppressWarnings("unchecked")
public CompletableFuture> keySet() {
return client.submit(new MapCommands.KeySet()).thenApply(keys -> (Set) keys);
}
/**
* Reads the collection of all values in the map.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* Set keys = map.keySet().get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.keySet().thenAccept(keys -> {
* keys.forEach(key -> ...);
* });
* map.replace("key", "Hello world!", "Hello world again!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @return A completable future to be completed with the result once complete.
*/
@SuppressWarnings("unchecked")
public CompletableFuture> values() {
return client.submit(new MapCommands.Values()).thenApply(values -> (Collection) values);
}
/**
* Reads the set of all entries in the map.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#get()} or {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* Set keys = map.keySet().get();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.keySet().thenAccept(keys -> {
* keys.forEach(key -> ...);
* });
* map.replace("key", "Hello world!", "Hello world again!", Duration.ofSeconds(10)).thenAccept(oldValue -> {
* ...
* });
* }
*
*
* @return A completable future to be completed with the result once complete.
*/
@SuppressWarnings("unchecked")
public CompletableFuture>> entrySet() {
return client.submit(new MapCommands.EntrySet()).thenApply(entries -> (Set>) entries);
}
/**
* Removes all entries from the map.
*
* This method returns a {@link CompletableFuture} which can be used to block until the operation completes
* or to be notified in a separate thread once the operation completes. To block until the operation completes,
* use the {@link CompletableFuture#join()} method to block the calling thread:
*
* {@code
* map.clear().join();
* }
*
* Alternatively, to execute the operation asynchronous and be notified once the operation is complete in a different
* thread, use one of the many completable future callbacks:
*
* {@code
* map.clear().thenRun(() -> {
* ...
* });
* }
*
*
* @return A completable future to be completed once the operation is complete.
*/
public CompletableFuture clear() {
return client.submit(new MapCommands.Clear());
}
}