Class DistributedMultiMap
java.lang.Object
com.loomcache.server.datastructures.DistributedMultiMap
- All Implemented Interfaces:
Snapshotable
Distributed MultiMap — a map where each key can have multiple values.
Backed by ConcurrentHashMap with ConcurrentLinkedDeque values,
providing thread-safe concurrent access to multiple values per key. Supports
operations similar to Guava's Multimap.
Features:
- put(key, value) — add a value to a key
- get(key) → Collection — retrieve all values for a key
- remove(key, value) — remove a specific value
- removeAll(key) — remove all values for a key
- containsKey, containsValue, containsEntry
- size, keyCount, valueCount(key)
- keys, values, entries — snapshot collections
- clear — remove all entries
- Entry listeners (onValueAdded, onValueRemoved)
- Snapshotable support for persistence
- Metrics via Micrometer (operations counter, entry count gauge)
Thread safety: All operations are thread-safe via ConcurrentHashMap and ConcurrentLinkedDeque. Compound operations use ReentrantLock for atomicity. Listener dispatch is fail-safe (try-catch per listener).
- Since:
- 1.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordstatic interfacestatic final recordMultiMapStatistics record for capturing aggregate metrics.static final recordCompact stats record used by enhanced tests (keyCount, valueCount, avgValuesPerKey).Nested classes/interfaces inherited from interface Snapshotable
Snapshotable.SnapshotCapture -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionDistributedMultiMap(String name, int instanceNumber) Create a DistributedMultiMap with the given name.DistributedMultiMap(String name, int instanceNumber, @Nullable io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a DistributedMultiMap with metrics support. -
Method Summary
Modifier and TypeMethodDescriptionvoidvoidclear()Clear all entries from the multimap.booleancontainsEntry(String key, String value) Check if the multimap contains the given key-value pair.booleancontainsKey(String key) Check if the multimap contains the given key.booleancontainsValue(String value) Check if the multimap contains the given value (in any key).entries()Get all key-value entries as Map.Entry pairs.entriesPage(int offset, int pageSize) Return a page of key-value entries in key-sorted, insertion-order-within-key order.Get all values for the given key.Get a snapshot of current multimap statistics.getStats()Returns a compact MultiMapStats snapshot.booleanisEmpty()Check if the multimap is empty.intkeyCount()Get the number of distinct keys.keys()Get all keys in the multimap.keysPage(int offset, int pageSize) Return a page of keys sorted lexicographically.booleanAdd a value to the given key.booleanRemove a specific value from a key.intRemove all values for a given key.voidvoidrestoreSnapshot(byte[] data) Restore this data structure from a previously serialized state.intsize()Get the total number of key-value entries (sum of all values across all keys).Get a unique identifier for this data structure.byte[]Serialize the current state of this data structure into a byte array.toString()intvalueCount(String key) Get the number of values for a specific key.values()Get all values across all keys.Methods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface Snapshotable
captureDeltaSnapshot, captureSnapshot, clearDirtyState, hasDirtyState, rollbackDirtyState, supportsDeltaSnapshot, takeDeltaSnapshot
-
Field Details
-
MAX_COLLECTION_VIEW_ENTRIES
public static final int MAX_COLLECTION_VIEW_ENTRIES- See Also:
-
-
Constructor Details
-
DistributedMultiMap
Create a DistributedMultiMap with the given name.- Parameters:
name- the name of the multimap (must not be null)instanceNumber- the node instance number- Throws:
NullPointerException- if name is null
-
DistributedMultiMap
public DistributedMultiMap(String name, int instanceNumber, @Nullable io.micrometer.core.instrument.MeterRegistry meterRegistry) Create a DistributedMultiMap with metrics support.- Parameters:
name- the name of the multimap (must not be null)instanceNumber- the node instance numbermeterRegistry- the meter registry for metrics (may be null)- Throws:
NullPointerException- if name is null
-
-
Method Details
-
getTransactionLock
-
put
-
get
Get all values for the given key.- Parameters:
key- the key (must not be null)- Returns:
- unmodifiable collection of values (empty if key not found)
-
remove
-
removeAll
Remove all values for a given key.- Parameters:
key- the key (must not be null)- Returns:
- the number of values removed
-
containsKey
Check if the multimap contains the given key.- Parameters:
key- the key (must not be null)- Returns:
- true if the key exists (has at least one value)
-
containsValue
Check if the multimap contains the given value (in any key).- Parameters:
value- the value (must not be null)- Returns:
- true if the value exists in any key
-
containsEntry
-
size
public int size()Get the total number of key-value entries (sum of all values across all keys).- Returns:
- total entry count
-
keyCount
public int keyCount()Get the number of distinct keys.- Returns:
- number of keys
-
valueCount
Get the number of values for a specific key.- Parameters:
key- the key (must not be null)- Returns:
- number of values for the key (0 if key not found)
-
keys
-
values
Get all values across all keys.- Returns:
- unmodifiable collection of all values
-
entries
Get all key-value entries as Map.Entry pairs.- Returns:
- unmodifiable collection of entries
-
keysPage
Return a page of keys sorted lexicographically. Pairs withkeys()as the paginated alternative for multimaps aboveMAX_COLLECTION_VIEW_ENTRIES.- Parameters:
offset- starting key index (0-based); clamped to total key countpageSize- page size (must be positive and ≤MAX_COLLECTION_VIEW_ENTRIES)
-
entriesPage
Return a page of key-value entries in key-sorted, insertion-order-within-key order. Callers drive pagination withDistributedMultiMap.EntryPage.nextOffset()until it returns -1.- Parameters:
offset- entry offset (0-based across the flat view)pageSize- page size (must be positive and ≤MAX_COLLECTION_VIEW_ENTRIES)
-
clear
public void clear()Clear all entries from the multimap. -
isEmpty
public boolean isEmpty()Check if the multimap is empty.- Returns:
- true if no entries
-
getStatistics
Get a snapshot of current multimap statistics.- Returns:
- MultiMapStatistics record with aggregated stats
-
getStats
Returns a compact MultiMapStats snapshot. -
addMultiMapListener
-
removeMultiMapListener
-
takeSnapshot
public byte[] takeSnapshot()Description copied from interface:SnapshotableSerialize the current state of this data structure into a byte array.- Specified by:
takeSnapshotin interfaceSnapshotable- Returns:
- byte array containing the serialized state
-
restoreSnapshot
public void restoreSnapshot(byte[] data) Description copied from interface:SnapshotableRestore this data structure from a previously serialized state.Must restore the state atomically, clearing existing data and populating with the snapshot contents.
- Specified by:
restoreSnapshotin interfaceSnapshotable- Parameters:
data- the serialized state to restore from
-
snapshotId
Description copied from interface:SnapshotableGet a unique identifier for this data structure.Used to identify which data structure a snapshot belongs to in a full state machine snapshot.
- Specified by:
snapshotIdin interfaceSnapshotable- Returns:
- unique identifier for this data structure
-
toString
-