Class ChampVectorMap<K,V>

java.lang.Object
org.jhotdraw8.icollection.ChampVectorMap<K,V>
Type Parameters:
K - the key type
V - the value type
All Implemented Interfaces:
Serializable, Iterable<Map.Entry<K,V>>, ImmutableMap<K,V>, ImmutableSequencedMap<K,V>, ReadOnlyMap<K,V>, ReadOnlySequencedMap<K,V>

public class ChampVectorMap<K,V> extends Object implements ImmutableSequencedMap<K,V>, Serializable
Implements the ImmutableSequencedMap interface using a Compressed Hash-Array Mapped Prefix-tree (CHAMP) and a bit-mapped trie (Vector).

Features:

  • supports up to 230 entries
  • allows null keys and null values
  • is immutable
  • is thread-safe
  • iterates in the order, in which keys were inserted

Performance characteristics:

  • put, putFirst, putLast: O(log₃₂ N) in an amortized sense, because we sometimes have to renumber the elements.
  • remove: O(log₃₂ N) in an amortized sense, because we sometimes have to renumber the elements.
  • containsKey: O(log₃₂ N)
  • toMutable: O(1) + O(log₃₂ N) distributed across subsequent updates in the mutable copy
  • clone: O(1)
  • iterator creation: O(log₃₂ N)
  • iterator.next: O(1)
  • getFirst, getLast: O(log₃₂ N)

Implementation details:

This map performs read and write operations of single elements in O(log N) time, and in O(log N) space, where N is the number of elements in the set.

The CHAMP trie contains nodes that may be shared with other maps.

If a write operation is performed on a node, then this set creates a copy of the node and of all parent nodes up to the root (copy-path-on-write). Since the CHAMP trie has a fixed maximal height, the cost is O(1).

This map can create a mutable copy of itself in O(1) time and O(1) space using method toMutable(). The mutable copy shares its nodes with this map, until it has gradually replaced the nodes with exclusively owned nodes.

Insertion Order:

This map uses a counter to keep track of the insertion order. It stores the current value of the counter in the sequence number field of each data entry. If the counter wraps around, it must renumber all sequence numbers.

The renumbering is why the add and remove methods are O(1) only in an amortized sense.

To support iteration, we use a Vector. The Vector has the same contents as the CHAMP trie. However, its elements are stored in insertion order.

If an element is removed from the CHAMP trie that is not the first or the last element of the Vector, we replace its corresponding element in the Vector by a tombstone. If the element is at the start or end of the Vector, we remove the element and all its neighboring tombstones from the Vector.

A tombstone can store the number of neighboring tombstones in ascending and in descending direction. We use these numbers to skip tombstones when we iterate over the vector. Since we only allow iteration in ascending or descending order from one of the ends of the vector, we do not need to keep the number of neighbors in all tombstones up to date. It is sufficient, if we update the neighbor with the lowest index and the one with the highest index.

If the number of tombstones exceeds half of the size of the collection, we renumber all sequence numbers, and we create a new Vector.

The immutable version of this set extends from the non-public class ChampBitmapIndexNode. This design safes 16 bytes for every instance, and reduces the number of redirections for finding an element in the collection by 1.

References:

For a similar design, see 'SimpleImmutableSequencedMap.scala'. Note, that this code is not a derivative of that code.

The Scala library. SimpleImmutableSequencedMap.scala. Copyright EPFL and Lightbend, Inc. Apache License 2.0.
github.com
See Also:
  • Constructor Details

    • ChampVectorMap

      protected ChampVectorMap(PrivateData privateData)
      Creates a new instance with the provided privateData data object.

      This constructor is intended to be called from a constructor of the subclass, that is called from method newInstance(PrivateData).

      Parameters:
      privateData - an privateData data object
  • Method Details

    • newInstance

      protected ChampVectorMap<K,V> newInstance(PrivateData privateData)
      Creates a new instance with the provided privateData object as its internal data structure.

      Subclasses must override this method, and return a new instance of their subclass!

      Parameters:
      privateData - the internal data structure needed by this class for creating the instance.
      Returns:
      a new instance of the subclass
    • copyOf

      public static <K, V> ChampVectorMap<K,V> copyOf(Iterable<? extends Map.Entry<? extends K,? extends V>> map)
      Returns an immutable copy of the provided map.
      Type Parameters:
      K - the key type
      V - the value type
      Parameters:
      map - a map
      Returns:
      an immutable copy
    • copyOf

      public static <K, V> ChampVectorMap<K,V> copyOf(Map<? extends K,? extends V> map)
      Returns an immutable copy of the provided map.
      Type Parameters:
      K - the key type
      V - the value type
      Parameters:
      map - a map
      Returns:
      an immutable copy
    • of

      public static <K, V> ChampVectorMap<K,V> of()
      Returns an empty immutable map.
      Type Parameters:
      K - the key type
      V - the value type
      Returns:
      an empty immutable map
    • clear

      public ChampVectorMap<K,V> clear()
      Returns a copy of this map that is empty.
      Specified by:
      clear in interface ImmutableMap<K,V>
      Specified by:
      clear in interface ImmutableSequencedMap<K,V>
      Returns:
      this set instance if it is already empty, or a different set instance that is empty.
    • containsKey

      public boolean containsKey(@Nullable Object o)
      Description copied from interface: ReadOnlyMap
      Returns true if this map contains a entry for the specified key.
      Specified by:
      containsKey in interface ReadOnlyMap<K,V>
      Parameters:
      o - a key
      Returns:
      true if this map contains a entry for the specified key
    • equals

      public boolean equals(@Nullable Object other)
      Description copied from interface: ReadOnlyMap
      Compares the specified object with this map for equality.

      Returns true if the given object is also a read-only map and the two maps represent the same entries, ignorig the sequence of the map entries.

      Specified by:
      equals in interface ReadOnlyMap<K,V>
      Overrides:
      equals in class Object
      Parameters:
      other - an object
      Returns:
      true if the object is equal to this map
    • firstEntry

      public @Nullable Map.Entry<K,V> firstEntry()
      Description copied from interface: ReadOnlySequencedMap
      Gets the first entry in this map or null if this map is empty.
      Specified by:
      firstEntry in interface ReadOnlySequencedMap<K,V>
      Returns:
      the first entry or null
    • lastEntry

      public @Nullable Map.Entry<K,V> lastEntry()
      Description copied from interface: ReadOnlySequencedMap
      Gets the last entry in this map or null if this map is empty.
      Specified by:
      lastEntry in interface ReadOnlySequencedMap<K,V>
      Returns:
      the last entry or null
    • get

      public @Nullable V get(Object o)
      Description copied from interface: ReadOnlyMap
      Returns the value to which the key is mapped, or null if this map contains no entry for the key.
      Specified by:
      get in interface ReadOnlyMap<K,V>
      Parameters:
      o - a key
      Returns:
      the mapped value or null
    • hashCode

      public int hashCode()
      Description copied from interface: ReadOnlyMap
      Returns the hash code value for this map. The hash code is the sum of the hash code of its entries.
      Specified by:
      hashCode in interface ReadOnlyMap<K,V>
      Overrides:
      hashCode in class Object
      Returns:
      the hash code value for this map
      See Also:
    • isEmpty

      public boolean isEmpty()
      Description copied from interface: ReadOnlyMap
      Returns true if this map contains no entries.
      Specified by:
      isEmpty in interface ReadOnlyMap<K,V>
      Returns:
      true if empty
    • iterator

      public Iterator<Map.Entry<K,V>> iterator()
      Description copied from interface: ReadOnlyMap
      Returns an iterator over the entries contained in this map.
      Specified by:
      iterator in interface Iterable<K>
      Specified by:
      iterator in interface ReadOnlyMap<K,V>
      Returns:
      an iterator
    • maxSize

      public int maxSize()
      Description copied from interface: ImmutableMap
      Returns the maximal number of entries that this map type can hold
      Specified by:
      maxSize in interface ImmutableMap<K,V>
      Returns:
      the maximal size
    • put

      public ChampVectorMap<K,V> put(K key, @Nullable V value)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains all entries of this map with the specified entry added or updated.
      Specified by:
      put in interface ImmutableMap<K,V>
      Specified by:
      put in interface ImmutableSequencedMap<K,V>
      Parameters:
      key - the key of the entry
      value - the value of the entry
      Returns:
      this map instance if it already contains the same entry, or a different map instance with the entry added or updated
    • putAll

      public ChampVectorMap<K,V> putAll(Map<? extends K,? extends V> m)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains all entries of this map with entries from the specified map added or updated.
      Specified by:
      putAll in interface ImmutableMap<K,V>
      Parameters:
      m - another map
      Returns:
      this map instance if it already contains the same entries, or a different map instance with the entries added or updated
    • putAll

      public ChampVectorMap<K,V> putAll(Iterable<? extends Map.Entry<? extends K,? extends V>> c)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains all entries of this map with entries from the specified map added or updated.
      Specified by:
      putAll in interface ImmutableMap<K,V>
      Specified by:
      putAll in interface ImmutableSequencedMap<K,V>
      Parameters:
      c - another map
      Returns:
      this map instance if it already contains the same entries, or a different map instance with the entries added or updated
    • putFirst

      public ChampVectorMap<K,V> putFirst(K key, @Nullable V value)
      Description copied from interface: ImmutableSequencedMap
      Creates an entry for the specified key and value and adds it to the front of the map if an entry for the specified key is not already present. If this map already contains an entry for the specified key, replaces the value and moves the entry to the front.
      Specified by:
      putFirst in interface ImmutableSequencedMap<K,V>
      Parameters:
      key - the key
      value - the value
      Returns:
      this map instance if no changes are needed, or a different map instance with the applied changes.
    • putLast

      public ChampVectorMap<K,V> putLast(K key, @Nullable V value)
      Description copied from interface: ImmutableSequencedMap
      Creates an entry for the specified key and value and adds it to the end of the map if an entry for the specified key is not already present. If this map already contains an entry for the specified key, replaces the value and moves the entry to the end.
      Specified by:
      putLast in interface ImmutableSequencedMap<K,V>
      Parameters:
      key - the key
      value - the value
      Returns:
      this map instance if no changes are needed, or a different map instance with the applied changes.
    • readOnlyReversed

      public ReadOnlySequencedMap<K,V> readOnlyReversed()
      Description copied from interface: ReadOnlySequencedMap
      Returns a reversed-order view of this map.

      Changes to the underlying map are visible in the reversed view.

      Specified by:
      readOnlyReversed in interface ReadOnlySequencedMap<K,V>
      Returns:
      a reversed-order view of this map
    • remove

      public ChampVectorMap<K,V> remove(K key)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains all entries of this map with the specified entry removed.
      Specified by:
      remove in interface ImmutableMap<K,V>
      Specified by:
      remove in interface ImmutableSequencedMap<K,V>
      Parameters:
      key - the key of the entry
      Returns:
      this map instance if it already does not contain the entry, or a different map instance with the entry removed
    • removeAll

      public ChampVectorMap<K,V> removeAll(Iterable<? extends K> c)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains all entries of this map except the entries of the specified collection.
      Specified by:
      removeAll in interface ImmutableMap<K,V>
      Specified by:
      removeAll in interface ImmutableSequencedMap<K,V>
      Parameters:
      c - a collection with keys of entries to be removed from this map
      Returns:
      this map instance if it already does not contain the entries, or a different map instance with the entries removed
    • retainAll

      public ChampVectorMap<K,V> retainAll(Iterable<? extends K> c)
      Description copied from interface: ImmutableMap
      Returns a copy of this map that contains only entries that are in this map and in the specified collection.
      Specified by:
      retainAll in interface ImmutableMap<K,V>
      Specified by:
      retainAll in interface ImmutableSequencedMap<K,V>
      Parameters:
      c - a collection with keys of entries to be retained in this map
      Returns:
      this map instance if it has not changed, or a different map instance with entries removed
    • size

      public int size()
      Description copied from interface: ReadOnlyMap
      Returns the number of entries contained in this map..
      Specified by:
      size in interface ReadOnlyMap<K,V>
      Returns:
      the number of entries
    • spliterator

      public Spliterator<Map.Entry<K,V>> spliterator()
      Description copied from interface: ReadOnlyMap
      Returns a spliterator over the entries contained in this map.
      Specified by:
      spliterator in interface Iterable<K>
      Specified by:
      spliterator in interface ReadOnlyMap<K,V>
      Returns:
      a spliterator
    • toMutable

      public MutableChampVectorMap<K,V> toMutable()
      Creates a mutable copy of this map.
      Specified by:
      toMutable in interface ImmutableMap<K,V>
      Specified by:
      toMutable in interface ImmutableSequencedMap<K,V>
      Returns:
      a mutable sequenced CHAMP map
    • asMap

      public MutableChampVectorMap<K,V> asMap()
      Description copied from interface: ReadOnlyMap
      Wraps this map in the Map interface - without copying.
      Specified by:
      asMap in interface ReadOnlyMap<K,V>
      Specified by:
      asMap in interface ReadOnlySequencedMap<K,V>
      Returns:
      the wrapped map
    • toString

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

      The string representation is consistent with the one produced by AbstractMap.toString().

      Overrides:
      toString in class Object
      Returns:
      a string representation
    • characteristics

      public int characteristics()
      Description copied from interface: ReadOnlyMap
      Returns the spliterator characteristics of the key set.

      The default implementation in this interface returns Spliterator.SIZED|Spliterator.DISTINCT.

      Specified by:
      characteristics in interface ReadOnlyMap<K,V>
      Specified by:
      characteristics in interface ReadOnlySequencedMap<K,V>
      Returns:
      characteristics.