Class LoomMap<K,V>
- Type Parameters:
K- the type of keys in the mapV- the type of values in the map
Provides transparent access to a distributed map stored in the LoomCache cluster. All operations are routed through the connected LoomClient and may raise LoomException if the cluster becomes unavailable or a timeout occurs.
Thread Safety
This class is thread-safe. Multiple threads may call methods concurrently; the underlying LoomClient handles synchronization and connection pooling.Async API
This class provides both synchronous and asynchronous methods. Async methods return CompletableFuture for non-blocking operations.Usage Example
org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("loom-map");
LoomClient client = LoomClient.builder()
.addSeed("127.0.0.1:5701")
.build();
client.connect();
LoomMap<String, String> users = client.getMap("users");
users.put("user1", "Alice");
String name = users.get("user1"); // "Alice"
users.delete("user1");
// Async variant
users.putAsync("user2", "Bob")
.thenCompose(v -> users.getAsync("user2"))
.thenAccept(name -> log.info("Got: {}", name))
.join();
- Since:
- 1.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordStatistics snapshot for a LoomMap operation. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddIndex(IndexConfig config) Adds or replaces an index for this map through the client SQL DDL path.addIndexAsync(IndexConfig config) Asynchronously adds or replaces an index for this map.voidclear()Remove all entries from this distributed map with a single server-side command.computeIfAbsent(K key, Function<K, V> mappingFunction) Compute and store a value if the key is absent, using server-side putIfAbsent for safe concurrent insertion.booleancontainsKey(K key) Checks whether a key exists in the distributed map.booleancontainsKey(K key, Duration timeout) Checks whether a key exists with a custom timeout.containsKeyAsync(K key) Asynchronously checks whether a key exists in the distributed map.booleanRemoves a key-value pair from the distributed map.booleanRemoves a key-value pair with a custom timeout.deleteAsync(K key) Asynchronously removes a key-value pair from the distributed map.<R> CompletionStage<@Nullable R> executeOnKey(K key, EntryProcessor<K, V, R> processor) Execute a registered entry processor against a single key through Raft.@Nullable VRetrieves the value associated with a key.@Nullable VRetrieves the value associated with a key with a custom timeout.getAll(Collection<K> keys) Batch retrieve multiple values by their keys.@Nullable VgetAndRemove(K key) Atomically retrieve and remove a key from the distributed map.Asynchronously retrieves the value associated with a key.getStats()Returns a snapshot of operational statistics for this map.@Nullable VStores a key-value pair in the distributed map.@Nullable VStores a key-value pair with a custom timeout.voidBatch store multiple key-value pairs in the distributed map.Asynchronously stores a key-value pair in the distributed map.@Nullable VputIfAbsent(K key, V value) Atomically stores a key-value pair only if the key is not already present.@Nullable VputWithTtl(K key, V value, long ttl, TimeUnit timeUnit) Stores a key-value pair with server-owned entry TTL.@Nullable VputWithTtl(K key, V value, Duration ttl) Stores a key-value pair with server-owned entry TTL.@Nullable VputWithTTL(K key, V value, long ttl, TimeUnit timeUnit) Backward-friendly alias for codebases that use TTL as an acronym in method names.@Nullable VputWithTTL(K key, V value, Duration ttl) Backward-friendly alias for codebases that use TTL as an acronym in method names.scan(long cursor) Scans the map using cursor-based iteration (Redis-like SCAN).Scans the map using cursor-based iteration with a glob pattern filter.Scans the map using cursor-based iteration with full control.scanner()Returns a cursor-based iterator for scanning map entries.Returns a cursor-based iterator for scanning map entries with a glob pattern filter.Returns a cursor-based iterator for scanning map entries with full control.intsize()Returns the number of key-value pairs in the distributed map.Asynchronously returns the number of key-value pairs in the distributed map.
-
Method Details
-
get
Retrieves the value associated with a key.- Parameters:
key- the key to look up (serialized viaClientSerializer)- Returns:
- the value associated with the key, or null if not found
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
put
Stores a key-value pair in the distributed map.If the key already exists, its value is replaced. Returns the previous value if one existed, or null if this is a new key.
- Parameters:
key- the key to store (serialized viaClientSerializer)value- the value to associate with the key- Returns:
- the previous value, or null if the key was not present
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
putWithTtl
-
putWithTtl
-
putWithTTL
-
putWithTTL
-
putIfAbsent
Atomically stores a key-value pair only if the key is not already present.- Parameters:
key- the key to store (serialized viaClientSerializer)value- the value to associate with the key- Returns:
- the existing value if the key was already present, or null if inserted
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
delete
Removes a key-value pair from the distributed map.- Parameters:
key- the key to remove- Returns:
- true if the key was present and removed; false if the key was not found
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
clear
public void clear()Remove all entries from this distributed map with a single server-side command. -
containsKey
Checks whether a key exists in the distributed map.- Parameters:
key- the key to check for- Returns:
- true if the key exists; false otherwise
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
size
public int size()Returns the number of key-value pairs in the distributed map.- Returns:
- the number of entries in the map
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
addIndex
Adds or replaces an index for this map through the client SQL DDL path.- Parameters:
config- index metadata to add for this map- Throws:
LoomException- if the cluster rejects the index DDL or is unavailable
-
scan
Scans the map using cursor-based iteration (Redis-like SCAN). Starts from the beginning with default count of 10.- Parameters:
cursor- the cursor position (0 to start from beginning)- Returns:
- a ScanResult containing the next cursor and matched keys
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
scan
Scans the map using cursor-based iteration with a glob pattern filter. Default count of 10 keys per iteration.- Parameters:
cursor- the cursor position (0 to start from beginning)pattern- optional glob pattern (* = any chars, ? = single char), null = match all- Returns:
- a ScanResult containing the next cursor and matched keys
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
scan
Scans the map using cursor-based iteration with full control.- Parameters:
cursor- the cursor position (0 to start from beginning)pattern- optional glob pattern (* = any chars, ? = single char), null = match allcount- maximum number of keys to return per iteration- Returns:
- a ScanResult containing the next cursor and matched keys
- Throws:
LoomException- if the operation fails or the cluster is unavailable
-
scanner
Returns a cursor-based iterator for scanning map entries.This method provides a clean, idiomatic Java iterator API that handles cursor management and pagination transparently. Useful for iterating over large maps without loading all entries into memory.
Usage Example:
org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("loom-map-scan"); // Simple iteration for (Map.Entry<String, String> entry : users.scanner()) { log.info("{} = {}", entry.getKey(), entry.getValue()); } // With Stream API users.scanner() .stream() .filter(e -> e.getKey().startsWith("user_")) .forEach(e -> log.info("{}", e.getValue()));- Returns:
- an Iterable for iterating over all map entries with default page size (10)
- Since:
- 1.3
-
scanner
Returns a cursor-based iterator for scanning map entries with a glob pattern filter.- Parameters:
pattern- optional glob pattern (* = any chars, ? = single char), null = match all- Returns:
- an Iterable for iterating over matching entries with default page size (10)
- Since:
- 1.3
-
scanner
Returns a cursor-based iterator for scanning map entries with full control.This is the most flexible scanner method, allowing control over both pattern matching and page size for optimal performance.
- Parameters:
pattern- optional glob pattern (* = any chars, ? = single char), null = match allpageSize- number of entries to fetch per scan operation (1-10000 recommended)- Returns:
- an Iterable for iterating over matching entries with the specified page size
- Throws:
IllegalArgumentException- if pageSize invalid input: '<'= 0- Since:
- 1.3
-
getAsync
Asynchronously retrieves the value associated with a key.- Parameters:
key- the key to look up (serialized viaClientSerializer)- Returns:
- a CompletableFuture with the value, or null if not found
-
putAsync
Asynchronously stores a key-value pair in the distributed map.If the key already exists, its value is replaced.
- Parameters:
key- the key to store (serialized viaClientSerializer)value- the value to associate with the key- Returns:
- a CompletableFuture that completes when the put operation is done
-
deleteAsync
Asynchronously removes a key-value pair from the distributed map.- Parameters:
key- the key to remove- Returns:
- a CompletableFuture with true if the key was present and removed; false if not found
-
executeOnKey
Execute a registered entry processor against a single key through Raft. -
containsKeyAsync
Asynchronously checks whether a key exists in the distributed map.- Parameters:
key- the key to check for- Returns:
- a CompletableFuture with true if the key exists; false otherwise
-
sizeAsync
Asynchronously returns the number of key-value pairs in the distributed map.- Returns:
- a CompletableFuture with the number of entries in the map
-
addIndexAsync
Asynchronously adds or replaces an index for this map.- Parameters:
config- index metadata to add for this map- Returns:
- a CompletableFuture that completes when the index metadata has been accepted
-
get
Retrieves the value associated with a key with a custom timeout.- Parameters:
key- the key to look uptimeout- per-operation timeout; if null, uses client's default timeout- Returns:
- the value associated with the key, or null if not found
- Throws:
LoomException- if the operation fails or times out
-
put
Stores a key-value pair with a custom timeout.- Parameters:
key- the key to storevalue- the value to associate with the keytimeout- per-operation timeout; if null, uses client's default timeout- Returns:
- the previous value, or null if the key was not present
- Throws:
LoomException- if the operation fails or times out
-
delete
Removes a key-value pair with a custom timeout.- Parameters:
key- the key to removetimeout- per-operation timeout; if null, uses client's default timeout- Returns:
- true if the key was present and removed; false if the key was not found
- Throws:
LoomException- if the operation fails or times out
-
containsKey
Checks whether a key exists with a custom timeout.- Parameters:
key- the key to check fortimeout- per-operation timeout; if null, uses client's default timeout- Returns:
- true if the key exists; false otherwise
- Throws:
LoomException- if the operation fails or times out
-
getAll
Batch retrieve multiple values by their keys.Fetches all specified keys from the distributed map. Keys that do not exist are omitted from the result map.
Usage Example:
LoomMap<String, String> users = client.getMap("users"); Map<String, String> results = users.getAll(List.of("user1", "user2", "user3")); // Returns: {"user1": "Alice", "user2": "Bob"} when user3 is absent- Parameters:
keys- the keys to retrieve (may be empty)- Returns:
- a Map containing existing requested keys with their values
- Throws:
LoomException- if the operation fails or the cluster is unavailable- Since:
- 1.1
-
putAll
Batch store multiple key-value pairs in the distributed map.Stores all entries from the provided map. If a key already exists, its value is replaced. This operation is not atomic—each key-value pair is stored individually.
Usage Example:
Map<String, String> users = Map.of( "user1", "Alice", "user2", "Bob", "user3", "Charlie" ); map.putAll(users);- Parameters:
entries- the map of entries to store (may be empty)- Throws:
LoomException- if any operation fails or the cluster is unavailable- Since:
- 1.1
-
computeIfAbsent
Compute and store a value if the key is absent, using server-side putIfAbsent for safe concurrent insertion.If the key does not exist in the map, the provided
mappingFunctionis called with the key as input to compute a value. That value is then stored viaputIfAbsent(Object, Object)to prevent a race where two concurrent callers both compute and overwrite each other's value. If another client inserts a value between the initial get and the putIfAbsent, the existing value is returned.Note: The mapping function may be called even if the key was concurrently inserted by another client. In that case the computed value is discarded and the existing server-side value is returned.
Usage Example:
LoomMap<String, Integer> cache = client.getMap("counter"); Integer value = cache.computeIfAbsent("total", k -> 42); // First call: stores 42, returns 42 // Second call: returns 42 (no recomputation)- Parameters:
key- the key to check and potentially compute formappingFunction- function to compute the value if key is absent- Returns:
- the value associated with the key (either existing or newly computed)
- Throws:
LoomException- if the operation fails or the cluster is unavailable- Since:
- 1.1
-
getAndRemove
Atomically retrieve and remove a key from the distributed map.Issues a single server-side
MAP_DELETEround-trip. The server removes the entry atomically and returns the value that was associated with the key at the moment of deletion. No concurrent writer can interleave a put between the read and the delete the way a client-side read-then-delete sequence would allow.Usage Example:
LoomMap<String, String> queue = client.getMap("tasks"); String task = queue.getAndRemove("task_123"); // task is retrieved and immediately deleted — atomic destructive read- Parameters:
key- the key to retrieve and remove- Returns:
- the value that was associated with the key, or null if not found
- Throws:
LoomException- if the operation fails or the cluster is unavailable- Since:
- 1.1
-
getStats
Returns a snapshot of operational statistics for this map.Tracks cache hits, remote fetches, and operation latency. Useful for monitoring and performance optimization.
Usage Example:
org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger("loom-map-stats"); LoomMapStats stats = map.getStats(); log.info("Hit rate: {}%", stats.hitRatePercent()); log.info("Total ops: {}", stats.totalOps()); log.info("Avg latency: {}ms", stats.avgLatencyMs());- Returns:
- a LoomMapStats record with current operation statistics
- Since:
- 1.1
-