Class MultiKeyMap<V>

java.lang.Object
com.cedarsoftware.util.MultiKeyMap<V>
Type Parameters:
V - the type of values stored in the map
All Implemented Interfaces:
ConcurrentMap<Object,V>, Map<Object,V>

public final class MultiKeyMap<V> extends Object implements ConcurrentMap<Object,V>
High-performance N-dimensional key-value Map implementation - the definitive solution for multidimensional lookups.

MultiKeyMap allows storing and retrieving values using multiple keys. Unlike traditional maps that use a single key, this map can handle keys with any number of components, making it ideal for complex lookup scenarios like user permissions, configuration trees, and caching systems.

Key Features:

  • N-Dimensional Keys: Support for keys with any number of components (1, 2, 3, ... N).
  • High Performance: Zero-allocation polymorphic storage, polynomial rolling hash, and optimized hash computation — no GC/heap pressure for gets in flat cases.
  • Thread-Safe: Lock-free reads with auto-tuned stripe locking that scales with your server cores, similar to ConcurrentHashMap.
  • Map Interface Compatible: Supports single-key operations via the standard Map interface (get()/put() automatically unpack Collections/Arrays into multi-keys).
  • Flexible API: Var-args methods for convenient multi-key operations (getMultiKey()/putMultiKey() with many keys).
  • Smart Collection Handling: Configurable behavior for Collections via MultiKeyMap.CollectionKeyMode — change the default automatic unpacking capability as needed.
  • N-Dimensional Array Expansion: Nested arrays of any depth are automatically flattened recursively into multi-keys.
  • Cross-Container Equivalence: Arrays and ordered Collections (Lists) with equivalent structure are treated as identical keys.
  • Set Support: Sets are treated as order-agnostic containers. Sets only match other Sets (not Lists/Arrays), and matching is independent of element order.

Dimensional Behavior Control:

MultiKeyMap provides revolutionary control over how dimensions are handled through the flattenDimensions parameter:

  • Structure-Preserving Mode (default, flattenDimensions = false): Different structural depths remain distinct keys. Arrays/Collections with different nesting levels create separate entries.
  • Dimension-Flattening Mode (flattenDimensions = true): All equivalent flat representations are treated as identical keys, regardless of original container structure.

Performance Characteristics:

  • Lock-Free Reads: Get operations require no locking for optimal concurrent performance
  • Auto-Tuned Stripe Locking: Write operations use stripe locking that adapts to your server's core count
  • Zero-Allocation Gets: No temporary objects created during retrieval operations
  • Polymorphic Storage: Efficient memory usage adapts storage format based on key complexity
  • Simple Keys Mode: Optional performance optimization that skips nested structure checks when keys are known to be flat

Capacity and Size Limits:

MultiKeyMap uses AtomicLong internally for size tracking, allowing it to scale well beyond the traditional Integer.MAX_VALUE (231-1) limitation:

  • Actual Capacity: The map can hold many more than 231-1 entries, limited only by heap memory.
  • size() Method: Due to the Map.size() interface contract requiring int, the size() method returns Integer.MAX_VALUE if the actual size exceeds this limit.
  • longSize() Method: Use longSize() to get the exact count for very large maps. This method returns the true size as a long without the 231-1 cap.
  • Memory Requirements: Storing 231 entries requires approximately 200-300 GB of heap memory (assuming ~100-150 bytes per entry including bucket overhead).
  • Practical Limit: On modern servers with 512GB-2TB RAM, maps with billions of entries are feasible.

Performance Complexity:

MultiKeyMap provides constant-time performance for most operations:

  • get/put/remove/containsKey: O(k) average, O(k + c) worst case
    where k = key components, c = chain length (typically 1-3)
  • size/longSize/isEmpty: O(1) - atomic counter access
  • clear: O(capacity) - must clear all buckets
  • keySet/values/entrySet: O(n) - creates snapshot of n entries

Key Processing Complexity:

  • Simple keys (String, Integer): O(1) hash and comparison
  • Multi-dimensional keys: O(k) where k = number of components
  • Nested collections: O(k × m) where k = depth, m = average size per level
  • Set keys: ~3-4x slower than List keys (order-agnostic hashing)

Value-Based vs Type-Based Equality:

MultiKeyMap provides two equality modes for key comparison, controlled via the valueBasedEquality parameter:

  • Value-Based Equality (default, valueBasedEquality = true): Cross-type numeric comparisons work naturally. Integer 1 equals Long 1L equals Double 1.0. This mode is ideal for configuration lookups and user-friendly APIs.
  • Type-Based Equality (valueBasedEquality = false): Strict type checking - Integer 1 ≠ Long 1L. This mode provides traditional Java Map semantics and maximum performance.

Value-Based Equality Edge Cases:

  • NaN Behavior: In value-based mode, NaN == NaN returns true (unlike Java's default). This ensures consistent key lookups with floating-point values.
  • Zero Handling: +0.0 == -0.0 returns true in both modes (standard Java behavior).
  • BigDecimal Precision: Doubles are converted via new BigDecimal(number.toString()). This means 0.1d equals BigDecimal("0.1") but NOT BigDecimal(0.1) (the latter has binary rounding errors).
  • Infinity Handling: Comparing Double.POSITIVE_INFINITY or NEGATIVE_INFINITY to BigDecimal returns false (BigDecimal cannot represent infinity).
  • Atomic Types: In type-based mode, only identical atomic types match (AtomicInteger ≠ Integer). In value-based mode, atomic types participate in numeric families (AtomicInteger(1) == Integer(1)).

Case Sensitivity for CharSequences:

MultiKeyMap provides configurable case sensitivity for CharSequence keys (String, StringBuilder, etc.), controlled via the caseSensitive parameter:

  • Case-Sensitive Mode (default, caseSensitive = true): CharSequences are compared using their standard equals() methods. "Hello" and "hello" are different keys.
  • Case-Insensitive Mode (caseSensitive = false): All CharSequence instances are compared case-insensitively. "Hello", "HELLO", and "hello" are treated as the same key.

API Overview:

MultiKeyMap provides two complementary APIs:

  • Map Interface: Use as Map<Object, V> for compatibility with existing code and single-key operations
  • MultiKeyMap API: Declare as MultiKeyMap<V> to access powerful var-args methods for multidimensional operations

Usage Examples:


 // Basic multi-dimensional usage
 MultiKeyMap<String> map = new MultiKeyMap<>();
 map.putMultiKey("user-config", "user123", "settings", "theme");
 String theme = map.getMultiKey("user123", "settings", "theme");
 
 // Cross-container equivalence
 map.put(new String[]{"key1", "key2"}, "value1");           // Array key
 String value = map.get(Arrays.asList("key1", "key2"));     // Collection lookup - same key!
 
 // Structure-preserving vs flattening modes
 MultiKeyMap<String> structured = MultiKeyMap.<String>builder().flattenDimensions(false).build(); // Structure-preserving (default)
 MultiKeyMap<String> flattened = MultiKeyMap.<String>builder().flattenDimensions(true).build();   // Dimension-flattening
 
 // Performance optimization for flat keys (no nested arrays/collections)
 MultiKeyMap<String> fast = MultiKeyMap.<String>builder()
     .simpleKeysMode(true)  // Skip nested structure checks for maximum performance
     .capacity(50000)       // Pre-size for known data volume
     .build();
 
 // Value-based vs Type-based equality
 MultiKeyMap<String> valueMap = MultiKeyMap.<String>builder().valueBasedEquality(true).build();  // Default
 valueMap.putMultiKey("found", 1, 2L, 3.0);        // Mixed numeric types
 String result = valueMap.getMultiKey(1L, 2, 3);   // Found! Cross-type numeric matching
 
 MultiKeyMap<String> typeMap = MultiKeyMap.<String>builder().valueBasedEquality(false).build();
 typeMap.putMultiKey("int-key", 1, 2, 3);
 String missing = typeMap.getMultiKey(1L, 2L, 3L); // null - different types don't match
 
 // Case-insensitive string keys
 MultiKeyMap<String> caseInsensitive = MultiKeyMap.<String>builder().caseSensitive(false).build();
 caseInsensitive.putMultiKey("value", "USER", "Settings", "THEME");
 String found = caseInsensitive.getMultiKey("user", "settings", "theme"); // Found! Case doesn't matter

 // Set support - order-agnostic matching
 MultiKeyMap<String> map = new MultiKeyMap<>();
 Set<String> coordinates = new HashSet<>(Arrays.asList("x", "y", "z"));
 map.put(coordinates, "value");

 // Sets match other Sets regardless of order or Set type
 Set<String> lookup1 = new LinkedHashSet<>(Arrays.asList("z", "x", "y"));  // Different order
 assertEquals("value", map.get(lookup1));  // Found! Order doesn't matter

 Set<String> lookup2 = new TreeSet<>(Arrays.asList("y", "z", "x"));  // Different Set type
 assertEquals("value", map.get(lookup2));  // Found! Set type doesn't matter

 // Sets don't match Lists/Arrays (semantic distinction)
 List<String> listLookup = Arrays.asList("x", "y", "z");
 assertNull(map.get(listLookup));  // Not found - Lists don't match Sets
 

For comprehensive examples and advanced usage patterns, see the user guide documentation.

Set Semantics:

Sets are treated as order-agnostic containers with the following behavior:

  • Order-Agnostic Matching: Sets match other Sets regardless of element order. Set.of(1,2,3) equals Set.of(3,2,1).
  • Type Independence: All Set types (HashSet, TreeSet, LinkedHashSet) are treated equivalently based on their elements.
  • Semantic Distinction: Sets only match other Sets - they do not match Lists or Arrays even with identical elements.
  • Nested Sets: Sets within arrays, lists, or other sets are properly handled with order-agnostic semantics.
  • Performance: Set operations are approximately 3-4x slower than List operations due to order-agnostic hash computation.
  • Empty Sets: Empty Sets are distinct from empty Lists/Arrays.

Complex Key Examples with Sets:

Sets can be combined with other key types in multi-dimensional keys:


 MultiKeyMap<String> map = new MultiKeyMap<>();

 // Example 1: Set combined with Object[] as a multi-key
 Set<String> permissions = new HashSet<>(Arrays.asList("read", "write", "execute"));
 Object[] userKey = new Object[]{"user123", permissions, "config"};
 map.put(userKey, "user-permissions-config");

 // Lookup works with different Set order
 Set<String> samePermsDiffOrder = new LinkedHashSet<>(Arrays.asList("execute", "read", "write"));
 Object[] lookupKey = new Object[]{"user123", samePermsDiffOrder, "config"};
 assertEquals("user-permissions-config", map.get(lookupKey));  // Found!

 // Example 2: Set combined with List as a multi-key
 Set<Integer> tags = Set.of(100, 200, 300);  // Order doesn't matter
 List<String> path = Arrays.asList("api", "v1", "users");  // Order DOES matter
 map.putMultiKey("endpoint-handler", tags, path);

 // Lookup with different Set order but same List order
 Set<Integer> sameTags = Set.of(300, 100, 200);  // Different order - still matches
 List<String> samePath = Arrays.asList("api", "v1", "users");  // Same order required
 assertEquals("endpoint-handler", map.getMultiKey(sameTags, samePath));  // Found!

 // Different List order will NOT match
 List<String> differentPath = Arrays.asList("v1", "api", "users");  // Different order
 assertNull(map.getMultiKey(sameTags, differentPath));  // Not found!
 
Author:
John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC

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

License

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.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Builder for creating configured MultiKeyMap instances.
    static enum 
    Controls how Collections are treated when used as keys in MultiKeyMap.

    Nested classes/interfaces inherited from interface java.util.Map

    Map.Entry<K extends Object,V extends Object>
  • Constructor Summary

    Constructors
    Constructor
    Description
     
    MultiKeyMap(int capacity)
     
    MultiKeyMap(int capacity, float loadFactor)
     
    MultiKeyMap(MultiKeyMap<? extends V> source)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static <V> MultiKeyMap.Builder<V>
     
    void
    Removes all the mappings from this map.
    compute(Object key, BiFunction<? super Object,? super V,? extends V> remappingFunction)
    Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).
    computeIfAbsent(Object key, Function<? super Object,? extends V> mappingFunction)
    If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null.
    computeIfPresent(Object key, BiFunction<? super Object,? super V,? extends V> remappingFunction)
    If the specified key is not already associated with a value, attempts to compute a new mapping given the key and its current mapped value.
    boolean
    Returns true if this map contains a mapping for the specified key.
    boolean
    Returns true if this map contains a mapping for the specified multidimensional key using var-args syntax.
    boolean
    Optimized 2-key containsKey check with zero allocation using ThreadLocal array.
    boolean
    Optimized 3-key containsKey check with zero allocation using ThreadLocal array.
    boolean
    Optimized 4-key containsKey check with zero allocation using ThreadLocal array.
    boolean
    Optimized 5-key containsKey check with zero allocation using ThreadLocal array.
    boolean
    Returns true if this map maps one or more keys to the specified value.
    Returns a Set view of the mappings contained in this map.
    boolean
    Compares the specified object with this map for equality.
    get(Object key)
    Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
    int
    Returns the initial capacity setting for this map.
    boolean
    Returns the current case sensitivity setting for CharSequence comparisons.
    Returns the current collection key mode setting.
    boolean
    Returns the current dimension flattening setting.
    float
    Returns the load factor setting for this map.
    Retrieves the value associated with the specified multidimensional key using var-args syntax.
    Optimized 2-key lookup with zero allocation using ThreadLocal array.
    Optimized 3-key lookup with zero allocation using ThreadLocal array.
    getMultiKey(Object k1, Object k2, Object k3, Object k4)
    Optimized 4-key lookup with zero allocation using ThreadLocal array.
    getMultiKey(Object k1, Object k2, Object k3, Object k4, Object k5)
    Optimized 5-key lookup with zero allocation using ThreadLocal array.
    boolean
    Returns the current simple keys mode setting.
    boolean
    Returns the value-based equality setting for numeric keys.
    int
    Returns the hash code value for this map.
    boolean
    Returns true if this map contains no key-value mappings.
    Returns a Set view of the keys contained in this map.
    long
    Returns the exact number of key-value mappings in this map as a long.
    merge(Object key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
    If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value.
    void
    Prints detailed contention statistics for this map's stripe locking system to the logger.
    put(Object key, V value)
    Associates the specified value with the specified key in this map.
    void
    putAll(Map<?,? extends V> m)
    Copies all the mappings from the specified map to this map.
    putIfAbsent(Object key, V value)
    If the specified key is not already associated with a value, associates it with the given value.
    putMultiKey(V value, Object... keys)
    Associates the specified value with the specified multidimensional key using var-args syntax.
    static Object
    Reconstructs keys as native structures (List, Set, or single items) for serialization.
    Removes the mapping for the specified key from this map if it is present.
    boolean
    remove(Object key, Object value)
    Removes the entry for a key only if it is currently mapped to the specified value.
    Removes the mapping for the specified multidimensional key using var-args syntax.
    replace(Object key, V value)
    Replaces the entry for the specified key only if it is currently mapped to some value.
    boolean
    replace(Object key, V oldValue, V newValue)
    Replaces the entry for the specified key only if currently mapped to the specified value.
    int
    Returns the number of key-value mappings in this map.
    Returns a string representation of this map.
    Returns a Collection view of the values contained in this map.

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait

    Methods inherited from interface java.util.concurrent.ConcurrentMap

    forEach, getOrDefault, replaceAll
  • Constructor Details

    • MultiKeyMap

      public MultiKeyMap(MultiKeyMap<? extends V> source)
    • MultiKeyMap

      public MultiKeyMap()
    • MultiKeyMap

      public MultiKeyMap(int capacity)
    • MultiKeyMap

      public MultiKeyMap(int capacity, float loadFactor)
  • Method Details

    • builder

      public static <V> MultiKeyMap.Builder<V> builder()
    • getCollectionKeyMode

      public MultiKeyMap.CollectionKeyMode getCollectionKeyMode()
      Returns the current collection key mode setting.

      This mode determines how Collections are treated when used as keys in this map.

      Returns:
      the current MultiKeyMap.CollectionKeyMode - either COLLECTIONS_EXPANDED (default) where Collections are automatically unpacked into multi-key entries, or COLLECTIONS_NOT_EXPANDED where Collections are treated as single key objects
      See Also:
    • getFlattenDimensions

      public boolean getFlattenDimensions()
      Returns the current dimension flattening setting.

      This setting controls how nested arrays and collections are handled when used as keys.

      Returns:
      true if dimension flattening is enabled (all equivalent flat representations are treated as identical keys regardless of original container structure), false if structure-preserving mode is used (default, where different structural depths remain distinct keys)
    • getSimpleKeysMode

      public boolean getSimpleKeysMode()
      Returns the current simple keys mode setting.

      This performance optimization setting indicates whether the map assumes keys do not contain nested arrays or collections.

      Returns:
      true if simple keys mode is enabled (nested structure checks are skipped for maximum performance), false if normal operation with full nested structure support
    • getCaseSensitive

      public boolean getCaseSensitive()
      Returns the current case sensitivity setting for CharSequence comparisons.

      This setting controls how CharSequence instances (String, StringBuilder, etc.) are compared within keys.

      Returns:
      true if case-sensitive comparison is enabled (default), false if case-insensitive comparison is used
      Since:
      3.6.0
    • getCapacity

      public int getCapacity()
      Returns the initial capacity setting for this map.

      This is the capacity value specified when the map was built, which was used to determine the initial internal bucket array size.

      Returns:
      the initial capacity
    • getLoadFactor

      public float getLoadFactor()
      Returns the load factor setting for this map.

      The load factor determines when the map will resize. A value of 0.75 means the map will resize when it's 75% full.

      Returns:
      the load factor
    • getValueBasedEquality

      public boolean getValueBasedEquality()
      Returns the value-based equality setting for numeric keys.

      When enabled, numeric keys are compared by value rather than type. For example, Integer(42) will match Long(42) when value-based equality is enabled.

      Returns:
      true if value-based equality is enabled (default), false if type-based equality is used
    • getMultiKey

      public V getMultiKey(Object... keys)
      Retrieves the value associated with the specified multidimensional key using var-args syntax.

      This is a convenience method that allows easy multi-key lookups without having to pass arrays or collections. The keys are treated as separate dimensions of a multi-key.

      Parameters:
      keys - the key components to look up. Can be null or empty (treated as null key), single key, or multiple key components
      Returns:
      the value associated with the multi-key, or null if no mapping exists
      See Also:
    • getMultiKey

      public V getMultiKey(Object k1, Object k2)
      Optimized 2-key lookup with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      Returns:
      the value associated with the multi-key, or null if no mapping exists
    • getMultiKey

      public V getMultiKey(Object k1, Object k2, Object k3)
      Optimized 3-key lookup with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      Returns:
      the value associated with the multi-key, or null if no mapping exists
    • getMultiKey

      public V getMultiKey(Object k1, Object k2, Object k3, Object k4)
      Optimized 4-key lookup with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      k4 - fourth key component
      Returns:
      the value associated with the multi-key, or null if no mapping exists
    • getMultiKey

      public V getMultiKey(Object k1, Object k2, Object k3, Object k4, Object k5)
      Optimized 5-key lookup with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      k4 - fourth key component
      k5 - fifth key component
      Returns:
      the value associated with the multi-key, or null if no mapping exists
    • get

      public V get(Object key)
      Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

      This method supports both single keys and multidimensional keys. Arrays and Collections are automatically expanded into multi-keys based on the map's configuration settings.

      Specified by:
      get in interface Map<Object,V>
      Parameters:
      key - the key whose associated value is to be returned. Can be a single object, array, or Collection that will be normalized according to the map's settings
      Returns:
      the value to which the specified key is mapped, or null if no mapping exists
    • putMultiKey

      public V putMultiKey(V value, Object... keys)
      Associates the specified value with the specified multidimensional key using var-args syntax.

      This is a convenience method that allows easy multi-key storage without having to pass arrays or collections. The keys are treated as separate dimensions of a multi-key.

      Parameters:
      value - the value to be associated with the multi-key
      keys - the key components for the mapping. Can be null or empty (treated as null key), single key, or multiple key components
      Returns:
      the previous value associated with the multi-key, or null if there was no mapping for the key
      See Also:
    • put

      public V put(Object key, V value)
      Associates the specified value with the specified key in this map.

      This method supports both single keys and multidimensional keys. Arrays and Collections are automatically expanded into multi-keys based on the map's configuration settings.

      Specified by:
      put in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated. Can be a single object, array, or Collection that will be normalized according to the map's settings
      value - the value to be associated with the specified key
      Returns:
      the previous value associated with the key, or null if there was no mapping for the key
    • containsMultiKey

      public boolean containsMultiKey(Object... keys)
      Returns true if this map contains a mapping for the specified multidimensional key using var-args syntax.

      This is a convenience method that allows easy multi-key existence checks without having to pass arrays or collections. The keys are treated as separate dimensions of a multi-key.

      Parameters:
      keys - the key components to check for. Can be null or empty (treated as null key), single key, or multiple key components
      Returns:
      true if this map contains a mapping for the specified multi-key
      See Also:
    • containsMultiKey

      public boolean containsMultiKey(Object k1, Object k2)
      Optimized 2-key containsKey check with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      Returns:
      true if this map contains a mapping for the multi-key
    • containsMultiKey

      public boolean containsMultiKey(Object k1, Object k2, Object k3)
      Optimized 3-key containsKey check with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      Returns:
      true if this map contains a mapping for the multi-key
    • containsMultiKey

      public boolean containsMultiKey(Object k1, Object k2, Object k3, Object k4)
      Optimized 4-key containsKey check with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      k4 - fourth key component
      Returns:
      true if this map contains a mapping for the multi-key
    • containsMultiKey

      public boolean containsMultiKey(Object k1, Object k2, Object k3, Object k4, Object k5)
      Optimized 5-key containsKey check with zero allocation using ThreadLocal array.
      Parameters:
      k1 - first key component
      k2 - second key component
      k3 - third key component
      k4 - fourth key component
      k5 - fifth key component
      Returns:
      true if this map contains a mapping for the multi-key
    • containsKey

      public boolean containsKey(Object key)
      Returns true if this map contains a mapping for the specified key.

      This method supports both single keys and multidimensional keys. Arrays and Collections are automatically expanded into multi-keys based on the map's configuration settings.

      Specified by:
      containsKey in interface Map<Object,V>
      Parameters:
      key - the key whose presence in this map is to be tested. Can be a single object, array, or Collection that will be normalized according to the map's settings
      Returns:
      true if this map contains a mapping for the specified key
    • removeMultiKey

      public V removeMultiKey(Object... keys)
      Removes the mapping for the specified multidimensional key using var-args syntax.

      This is a convenience method that allows easy multi-key removal without having to pass arrays or collections. The keys are treated as separate dimensions of a multi-key.

      Parameters:
      keys - the key components for the mapping to remove. Can be null or empty (treated as null key), single key, or multiple key components
      Returns:
      the previous value associated with the multi-key, or null if there was no mapping for the key
      See Also:
    • remove

      public V remove(Object key)
      Removes the mapping for the specified key from this map if it is present.

      This method supports both single keys and multidimensional keys. Arrays and Collections are automatically expanded into multi-keys based on the map's configuration settings.

      Specified by:
      remove in interface Map<Object,V>
      Parameters:
      key - the key whose mapping is to be removed from the map. Can be a single object, array, or Collection that will be normalized according to the map's settings
      Returns:
      the previous value associated with the key, or null if there was no mapping for the key
    • size

      public int size()
      Returns the number of key-value mappings in this map.

      Note: Due to the Map.size() interface contract requiring int, this method returns Integer.MAX_VALUE if the actual size exceeds 231-1. For maps that may exceed this limit, use longSize() to get the accurate count.

      Specified by:
      size in interface Map<Object,V>
      Returns:
      the number of key-value mappings in this map, capped at Integer.MAX_VALUE
      See Also:
    • longSize

      public long longSize()
      Returns the exact number of key-value mappings in this map as a long.

      This method provides the true size without the 231-1 limitation imposed by the Map.size() contract. Use this method when working with very large maps that may contain more than Integer.MAX_VALUE entries.

      Returns:
      the exact number of key-value mappings in this map
      See Also:
    • isEmpty

      public boolean isEmpty()
      Returns true if this map contains no key-value mappings.
      Specified by:
      isEmpty in interface Map<Object,V>
      Returns:
      true if this map contains no key-value mappings
    • clear

      public void clear()
      Removes all the mappings from this map. The map will be empty after this call returns.
      Specified by:
      clear in interface Map<Object,V>
    • containsValue

      public boolean containsValue(Object value)
      Returns true if this map maps one or more keys to the specified value.

      This operation requires time linear in the map size.

      Specified by:
      containsValue in interface Map<Object,V>
      Parameters:
      value - the value whose presence in this map is to be tested
      Returns:
      true if this map maps one or more keys to the specified value
    • keySet

      public Set<Object> keySet()
      Returns a Set view of the keys contained in this map.

      Multidimensional keys are represented as List (ordered) or Set (unordered), while single keys are returned as their original objects. This provides a consistent mental model: keys are always single items, Lists, or Sets - regardless of nesting depth.

      CONTRACT VIOLATION: This method returns a snapshot, not a live view. Changes to the returned set are NOT reflected in the map, and vice versa. This violates the Map.keySet() contract which requires a live view.

      Specified by:
      keySet in interface Map<Object,V>
      Returns:
      a snapshot set view of the keys contained in this map
    • values

      public Collection<V> values()
      Returns a Collection view of the values contained in this map.

      CONTRACT VIOLATION: This method returns a snapshot, not a live view. Changes to the returned collection are NOT reflected in the map, and vice versa. This violates the Map.values() contract which requires a live view.

      Specified by:
      values in interface Map<Object,V>
      Returns:
      a snapshot collection view of the values contained in this map
    • entrySet

      public Set<Map.Entry<Object,V>> entrySet()
      Returns a Set view of the mappings contained in this map.

      Multidimensional keys are represented as List (ordered) or Set (unordered), while single keys are returned as their original objects. This provides a consistent mental model: keys are always single items, Lists, or Sets - regardless of nesting depth.

      CONTRACT VIOLATION: This method returns a snapshot, not a live view. Changes to the returned set are NOT reflected in the map, and vice versa. This violates the Map.entrySet() contract which requires a live view.

      Rationale: Implementing a true live view would require maintaining bidirectional references between the set and map, adding significant complexity and memory overhead. The snapshot approach provides better performance and thread-safety characteristics for this concurrent data structure, at the cost of contract compliance.

      Specified by:
      entrySet in interface Map<Object,V>
      Returns:
      a snapshot set view of the mappings contained in this map
    • putAll

      public void putAll(Map<?,? extends V> m)
      Copies all the mappings from the specified map to this map.

      The effect of this call is equivalent to that of calling put(Object, Object) on this map once for each mapping from key k to value v in the specified map.

      Specified by:
      putAll in interface Map<Object,V>
      Parameters:
      m - mappings to be stored in this map
      Throws:
      NullPointerException - if the specified map is null
    • putIfAbsent

      public V putIfAbsent(Object key, V value)
      If the specified key is not already associated with a value, associates it with the given value.

      This is equivalent to:

       
       if (!map.containsKey(key))
         return map.put(key, value);
       else
         return map.get(key);
       
      except that the action is performed atomically.

      Specified by:
      putIfAbsent in interface ConcurrentMap<Object,V>
      Specified by:
      putIfAbsent in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      value - the value to be associated with the specified key
      Returns:
      the previous value associated with the specified key, or null if there was no mapping for the key
    • computeIfAbsent

      public V computeIfAbsent(Object key, Function<? super Object,? extends V> mappingFunction)
      If the specified key is not already associated with a value, attempts to compute its value using the given mapping function and enters it into this map unless null.

      The entire method invocation is performed atomically, so the function is applied at most once per key.

      Specified by:
      computeIfAbsent in interface ConcurrentMap<Object,V>
      Specified by:
      computeIfAbsent in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      mappingFunction - the function to compute a value
      Returns:
      the current (existing or computed) value associated with the specified key, or null if the computed value is null
      Throws:
      NullPointerException - if the specified mappingFunction is null
    • computeIfPresent

      public V computeIfPresent(Object key, BiFunction<? super Object,? super V,? extends V> remappingFunction)
      If the specified key is not already associated with a value, attempts to compute a new mapping given the key and its current mapped value.

      The entire method invocation is performed atomically. If the function returns null, the mapping is removed.

      Specified by:
      computeIfPresent in interface ConcurrentMap<Object,V>
      Specified by:
      computeIfPresent in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      remappingFunction - the function to compute a value
      Returns:
      the new value associated with the specified key, or null if none
      Throws:
      NullPointerException - if the specified remappingFunction is null
    • compute

      public V compute(Object key, BiFunction<? super Object,? super V,? extends V> remappingFunction)
      Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).

      The entire method invocation is performed atomically. If the function returns null, the mapping is removed (or remains absent if initially absent).

      Specified by:
      compute in interface ConcurrentMap<Object,V>
      Specified by:
      compute in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      remappingFunction - the function to compute a value
      Returns:
      the new value associated with the specified key, or null if none
      Throws:
      NullPointerException - if the specified remappingFunction is null
    • merge

      public V merge(Object key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
      If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. Otherwise, replaces the associated value with the results of the given remapping function, or removes if the result is null.

      The entire method invocation is performed atomically.

      Specified by:
      merge in interface ConcurrentMap<Object,V>
      Specified by:
      merge in interface Map<Object,V>
      Parameters:
      key - the key with which the resulting value is to be associated
      value - the non-null value to be merged with the existing value
      remappingFunction - the function to recompute a value if present
      Returns:
      the new value associated with the specified key, or null if no value is associated with the key
      Throws:
      NullPointerException - if the specified value or remappingFunction is null
    • remove

      public boolean remove(Object key, Object value)
      Removes the entry for a key only if it is currently mapped to the specified value.

      This is equivalent to:

       
       if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
         map.remove(key);
         return true;
       } else
         return false;
       
      except that the action is performed atomically.

      Specified by:
      remove in interface ConcurrentMap<Object,V>
      Specified by:
      remove in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      value - the value expected to be associated with the specified key
      Returns:
      true if the value was removed
    • replace

      public V replace(Object key, V value)
      Replaces the entry for the specified key only if it is currently mapped to some value.

      This is equivalent to:

       
       if (map.containsKey(key)) {
         return map.put(key, value);
       } else
         return null;
       
      except that the action is performed atomically.

      Specified by:
      replace in interface ConcurrentMap<Object,V>
      Specified by:
      replace in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      value - the value to be associated with the specified key
      Returns:
      the previous value associated with the specified key, or null if there was no mapping for the key
    • replace

      public boolean replace(Object key, V oldValue, V newValue)
      Replaces the entry for the specified key only if currently mapped to the specified value.

      This is equivalent to:

       
       if (map.containsKey(key) && Objects.equals(map.get(key), oldValue)) {
         map.put(key, newValue);
         return true;
       } else
         return false;
       
      except that the action is performed atomically.

      Specified by:
      replace in interface ConcurrentMap<Object,V>
      Specified by:
      replace in interface Map<Object,V>
      Parameters:
      key - the key with which the specified value is to be associated
      oldValue - the value expected to be associated with the specified key
      newValue - the value to be associated with the specified key
      Returns:
      true if the value was replaced
    • hashCode

      public int hashCode()
      Returns the hash code value for this map.

      The hash code of a map is defined to be the sum of the hash codes of each entry in the map's entrySet() view. This ensures that m1.equals(m2) implies that m1.hashCode()==m2.hashCode() for any two maps m1 and m2, as required by the general contract of Object.hashCode().

      Specified by:
      hashCode in interface Map<Object,V>
      Overrides:
      hashCode in class Object
      Returns:
      the hash code value for this map
    • equals

      public boolean equals(Object o)
      Compares the specified object with this map for equality.

      Returns true if the given object is also a map and the two maps represent the same mappings. Two maps m1 and m2 represent the same mappings if m1.entrySet().equals(m2.entrySet()).

      Specified by:
      equals in interface Map<Object,V>
      Overrides:
      equals in class Object
      Parameters:
      o - object to be compared for equality with this map
      Returns:
      true if the specified object is equal to this map
    • toString

      public String toString()
      Returns a string representation of this map.

      The string representation consists of a list of key-value mappings in the order returned by the map's entries iterator, enclosed in braces ({}).

      Each key-value mapping is rendered as "key → value", where the key part shows all key components and the value part shows the mapped value. Adjacent mappings are separated by commas and newlines.

      Empty maps are represented as "{}".

      Overrides:
      toString in class Object
      Returns:
      a string representation of this map, formatted for readability with multi-line output and proper indentation
    • reconstructKey

      public static Object reconstructKey(Object[] in)
      Reconstructs keys as native structures (List, Set, or single items) for serialization. This is the preferred method for entrySet()/keySet() as it returns structures that serialize naturally in JSON without requiring marker parsing.

      Returns:

      • Single item if the key has only one component
      • List (ArrayList) for ordered sequences (from OPEN/CLOSE markers or unmarked arrays)
      • Set (LinkedHashSet) for unordered sequences (from SET_OPEN/SET_CLOSE markers)

      Nested structures are handled recursively, so Lists can contain Sets/Lists/singles, and Sets can contain Lists/Sets/singles. This ensures proper equals/hashCode behavior at all nesting levels.

      Parameters:
      in - the flattened internal key array with markers
      Returns:
      the reconstructed key using native List/Set/single-item structures
    • printContentionStatistics

      public void printContentionStatistics()
      Prints detailed contention statistics for this map's stripe locking system to the logger.

      This method outputs comprehensive performance monitoring information including:

      • Total lock acquisitions and contentions across all operations
      • Global lock statistics (used during resize operations)
      • Per-stripe breakdown showing acquisitions, contentions, and contention rates
      • Analysis of stripe distribution including most/least contended stripes
      • Count of unused stripes for load balancing assessment

      This information is useful for performance tuning and understanding concurrency patterns in high-throughput scenarios. The statistics are logged at INFO level.

      See Also:
      • STRIPE_COUNT