Class MVMap<K,​V>

  • Type Parameters:
    K - the key class
    V - the value class
    All Implemented Interfaces:
    java.util.concurrent.ConcurrentMap<K,​V>, java.util.Map<K,​V>
    Direct Known Subclasses:
    MVRTreeMap, SequenceMap

    public class MVMap<K,​V>
    extends java.util.AbstractMap<K,​V>
    implements java.util.concurrent.ConcurrentMap<K,​V>
    A stored map.

    All read and write operations can happen concurrently with all other operations, without risk of corruption.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  MVMap.BasicBuilder<M extends MVMap<K,​V>,​K,​V>
      A builder for this class.
      static class  MVMap.Builder<K,​V>
      A builder for this class.
      static class  MVMap.Decision
      The decision on what to do on an update.
      static class  MVMap.DecisionMaker<V>
      Class DecisionMaker provides callback interface (and should become a such in Java 8) for MVMap.operate() method.
      static interface  MVMap.MapBuilder<M extends MVMap<K,​V>,​K,​V>
      A builder for maps.
      • Nested classes/interfaces inherited from class java.util.AbstractMap

        java.util.AbstractMap.SimpleEntry<K extends java.lang.Object,​V extends java.lang.Object>, java.util.AbstractMap.SimpleImmutableEntry<K extends java.lang.Object,​V extends java.lang.Object>
      • Nested classes/interfaces inherited from interface java.util.Map

        java.util.Map.Entry<K extends java.lang.Object,​V extends java.lang.Object>
    • Field Summary

      Fields 
      Modifier and Type Field Description
      MVStore store
      The store.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected MVMap​(java.util.Map<java.lang.String,​java.lang.Object> config, DataType<K> keyType, DataType<V> valueType)  
      protected MVMap​(MVMap<K,​V> source)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void append​(K key, V value)
      Appends entry to this map.
      protected java.lang.String asString​(java.lang.String name)
      Get the map metadata as a string.
      protected void beforeWrite()
      This method is called before writing to the map.
      K ceilingKey​(K key)
      Get the smallest key that is larger or equal to this key.
      void clear()
      Remove all entries.
      protected MVMap<K,​V> cloneIt()
      Clone the current map.
      boolean containsKey​(java.lang.Object key)  
      protected Page<K,​V> createEmptyLeaf()
      Create empty leaf node page.
      protected Page<K,​V> createEmptyNode()
      Create empty internal node page.
      Cursor<K,​V> cursor​(K from)
      Get a cursor to iterate over a number of keys and values in the latest version of this map.
      Cursor<K,​V> cursor​(K from, K to, boolean reverse)
      Get a cursor to iterate over a number of keys and values in the latest version of this map.
      Cursor<K,​V> cursor​(RootReference<K,​V> rootReference, K from, K to, boolean reverse)
      Get a cursor to iterate over a number of keys and values.
      java.util.Set<java.util.Map.Entry<K,​V>> entrySet()  
      boolean equals​(java.lang.Object o)  
      K firstKey()
      Get the first key, or null if the map is empty.
      K floorKey​(K key)
      Get the largest key that is smaller or equal to this key.
      RootReference<K,​V> flushAndGetRoot()
      Get the root reference, flushing any current append buffer.
      V get​(java.lang.Object key)
      Get the value for the given key, or null if not found.
      V get​(Page<K,​V> p, K key)
      Get the value for the given key from a snapshot, or null if not found.
      protected int getChildPageCount​(Page<K,​V> p)
      Get the child page count for this page.
      int getId()
      Get the map id.
      K getKey​(long index)
      Get the key at the given index.
      long getKeyIndex​(K key)
      Get the index of the given key in the map.
      DataType<K> getKeyType()
      Get the key type.
      java.lang.String getName()
      Get the map name.
      RootReference<K,​V> getRoot()  
      Page<K,​V> getRootPage()
      The current root page (may not be null).
      MVStore getStore()  
      java.lang.String getType()
      Get the map type.
      DataType<V> getValueType()
      Get the value type.
      long getVersion()
      Get version of the map, which is the version of the store, at the moment when map was modified last time.
      int hashCode()  
      K higherKey​(K key)
      Get the smallest key that is larger than the given key (next key in ascending order), or null if no such key exists.
      K higherKey​(RootReference<K,​V> rootRef, K key)
      Get the smallest key that is larger than the given key, for the given root page, or null if no such key exists.
      boolean isClosed()  
      boolean isEmpty()  
      protected boolean isPersistent()  
      boolean isReadOnly()  
      boolean isVolatile()
      Whether this is volatile map, meaning that changes are not persisted.
      java.util.Iterator<K> keyIterator​(K from)
      Iterate over a number of keys.
      java.util.Iterator<K> keyIteratorReverse​(K from)
      Iterate over a number of keys in reverse order
      java.util.List<K> keyList()
      Get the key list.
      java.util.Set<K> keySet()  
      K lastKey()
      Get the last key, or null if the map is empty.
      K lowerKey​(K key)
      Get the largest key that is smaller than the given key, or null if no such key exists.
      K lowerKey​(RootReference<K,​V> rootRef, K key)
      Get the largest key that is smaller than the given key, for the given root page, or null if no such key exists.
      MVMap<K,​V> openVersion​(long version)
      Open an old version for the given map.
      V operate​(K key, V value, MVMap.DecisionMaker<V> decisionMaker)
      Add, replace or remove a key-value pair.
      V put​(K key, V value)
      Add or replace a key-value pair.
      V putIfAbsent​(K key, V value)
      Add a key-value pair if it does not yet exist.
      protected void registerUnsavedMemory​(int memory)  
      V remove​(java.lang.Object key)
      Remove a key-value pair, if the key exists.
      boolean remove​(java.lang.Object key, java.lang.Object value)
      Remove a key-value pair if the value matches the stored one.
      V replace​(K key, V value)
      Replace a value for an existing key.
      boolean replace​(K key, V oldValue, V newValue)
      Replace a value for an existing key, if the value matches.
      void setVolatile​(boolean isVolatile)
      Set the volatile flag of the map.
      int size()
      Get the number of entries, as integer.
      long sizeAsLong()
      Get the number of entries, as a long.
      java.lang.String toString()  
      void trimLast()
      Removes last entry from this map.
      protected RootReference<K,​V> tryLock​(RootReference<K,​V> rootReference, int attempt)
      Try to lock the root.
      protected void unlockRoot​(Page<K,​V> newRootPage)
      Unlock the root page.
      protected static <K,​V>
      boolean
      updateRoot​(RootReference<K,​V> expectedRootReference, Page<K,​V> newRootPage, int attemptUpdateCounter)
      Use the new root page from now on.
      • Methods inherited from class java.util.AbstractMap

        clone, containsValue, putAll, values
      • Methods inherited from class java.lang.Object

        finalize, getClass, notify, notifyAll, wait, wait, wait
      • Methods inherited from interface java.util.concurrent.ConcurrentMap

        compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, replaceAll
      • Methods inherited from interface java.util.Map

        containsValue, putAll, values
    • Field Detail

      • store

        public final MVStore store
        The store.
    • Constructor Detail

      • MVMap

        protected MVMap​(java.util.Map<java.lang.String,​java.lang.Object> config,
                        DataType<K> keyType,
                        DataType<V> valueType)
      • MVMap

        protected MVMap​(MVMap<K,​V> source)
    • Method Detail

      • cloneIt

        protected MVMap<K,​V> cloneIt()
        Clone the current map.
        Returns:
        clone of this.
      • put

        public V put​(K key,
                     V value)
        Add or replace a key-value pair.
        Specified by:
        put in interface java.util.Map<K,​V>
        Overrides:
        put in class java.util.AbstractMap<K,​V>
        Parameters:
        key - the key (may not be null)
        value - the value (may not be null)
        Returns:
        the old value if the key existed, or null otherwise
      • firstKey

        public final K firstKey()
        Get the first key, or null if the map is empty.
        Returns:
        the first key, or null
      • lastKey

        public final K lastKey()
        Get the last key, or null if the map is empty.
        Returns:
        the last key, or null
      • getKey

        public final K getKey​(long index)
        Get the key at the given index.

        This is a O(log(size)) operation.

        Parameters:
        index - the index
        Returns:
        the key
      • keyList

        public final java.util.List<K> keyList()
        Get the key list. The list is a read-only representation of all keys.

        The get and indexOf methods are O(log(size)) operations. The result of indexOf is cast to an int.

        Returns:
        the key list
      • getKeyIndex

        public final long getKeyIndex​(K key)
        Get the index of the given key in the map.

        This is a O(log(size)) operation.

        If the key was found, the returned value is the index in the key array. If not found, the returned value is negative, where -1 means the provided key is smaller than any keys. See also Arrays.binarySearch.

        Parameters:
        key - the key
        Returns:
        the index
      • higherKey

        public final K higherKey​(K key)
        Get the smallest key that is larger than the given key (next key in ascending order), or null if no such key exists.
        Parameters:
        key - the key
        Returns:
        the result
      • higherKey

        public final K higherKey​(RootReference<K,​V> rootRef,
                                 K key)
        Get the smallest key that is larger than the given key, for the given root page, or null if no such key exists.
        Parameters:
        rootRef - the root reference of the map
        key - to start from
        Returns:
        the result
      • ceilingKey

        public final K ceilingKey​(K key)
        Get the smallest key that is larger or equal to this key.
        Parameters:
        key - the key
        Returns:
        the result
      • floorKey

        public final K floorKey​(K key)
        Get the largest key that is smaller or equal to this key.
        Parameters:
        key - the key
        Returns:
        the result
      • lowerKey

        public final K lowerKey​(K key)
        Get the largest key that is smaller than the given key, or null if no such key exists.
        Parameters:
        key - the key
        Returns:
        the result
      • lowerKey

        public final K lowerKey​(RootReference<K,​V> rootRef,
                                K key)
        Get the largest key that is smaller than the given key, for the given root page, or null if no such key exists.
        Parameters:
        rootRef - the root page
        key - the key
        Returns:
        the result
      • get

        public final V get​(java.lang.Object key)
        Get the value for the given key, or null if not found.
        Specified by:
        get in interface java.util.Map<K,​V>
        Overrides:
        get in class java.util.AbstractMap<K,​V>
        Parameters:
        key - the key
        Returns:
        the value, or null if not found
        Throws:
        java.lang.ClassCastException - if type of the specified key is not compatible with this map
      • get

        public V get​(Page<K,​V> p,
                     K key)
        Get the value for the given key from a snapshot, or null if not found.
        Parameters:
        p - the root of a snapshot
        key - the key
        Returns:
        the value, or null if not found
        Throws:
        java.lang.ClassCastException - if type of the specified key is not compatible with this map
      • containsKey

        public final boolean containsKey​(java.lang.Object key)
        Specified by:
        containsKey in interface java.util.Map<K,​V>
        Overrides:
        containsKey in class java.util.AbstractMap<K,​V>
      • clear

        public void clear()
        Remove all entries.
        Specified by:
        clear in interface java.util.Map<K,​V>
        Overrides:
        clear in class java.util.AbstractMap<K,​V>
      • registerUnsavedMemory

        protected final void registerUnsavedMemory​(int memory)
      • isClosed

        public final boolean isClosed()
      • remove

        public V remove​(java.lang.Object key)
        Remove a key-value pair, if the key exists.
        Specified by:
        remove in interface java.util.Map<K,​V>
        Overrides:
        remove in class java.util.AbstractMap<K,​V>
        Parameters:
        key - the key (may not be null)
        Returns:
        the old value if the key existed, or null otherwise
        Throws:
        java.lang.ClassCastException - if type of the specified key is not compatible with this map
      • putIfAbsent

        public final V putIfAbsent​(K key,
                                   V value)
        Add a key-value pair if it does not yet exist.
        Specified by:
        putIfAbsent in interface java.util.concurrent.ConcurrentMap<K,​V>
        Specified by:
        putIfAbsent in interface java.util.Map<K,​V>
        Parameters:
        key - the key (may not be null)
        value - the new value
        Returns:
        the old value if the key existed, or null otherwise
      • remove

        public boolean remove​(java.lang.Object key,
                              java.lang.Object value)
        Remove a key-value pair if the value matches the stored one.
        Specified by:
        remove in interface java.util.concurrent.ConcurrentMap<K,​V>
        Specified by:
        remove in interface java.util.Map<K,​V>
        Parameters:
        key - the key (may not be null)
        value - the expected value
        Returns:
        true if the item was removed
      • replace

        public final boolean replace​(K key,
                                     V oldValue,
                                     V newValue)
        Replace a value for an existing key, if the value matches.
        Specified by:
        replace in interface java.util.concurrent.ConcurrentMap<K,​V>
        Specified by:
        replace in interface java.util.Map<K,​V>
        Parameters:
        key - the key (may not be null)
        oldValue - the expected value
        newValue - the new value
        Returns:
        true if the value was replaced
      • replace

        public final V replace​(K key,
                               V value)
        Replace a value for an existing key.
        Specified by:
        replace in interface java.util.concurrent.ConcurrentMap<K,​V>
        Specified by:
        replace in interface java.util.Map<K,​V>
        Parameters:
        key - the key (may not be null)
        value - the new value
        Returns:
        the old value, if the value was replaced, or null
      • getKeyType

        public final DataType<K> getKeyType()
        Get the key type.
        Returns:
        the key type
      • getValueType

        public final DataType<V> getValueType()
        Get the value type.
        Returns:
        the value type
      • keyIterator

        public final java.util.Iterator<K> keyIterator​(K from)
        Iterate over a number of keys.
        Parameters:
        from - the first key to return
        Returns:
        the iterator
      • keyIteratorReverse

        public final java.util.Iterator<K> keyIteratorReverse​(K from)
        Iterate over a number of keys in reverse order
        Parameters:
        from - the first key to return
        Returns:
        the iterator
      • cursor

        public final Cursor<K,​V> cursor​(K from)
        Get a cursor to iterate over a number of keys and values in the latest version of this map.
        Parameters:
        from - the first key to return
        Returns:
        the cursor
      • cursor

        public final Cursor<K,​V> cursor​(K from,
                                              K to,
                                              boolean reverse)
        Get a cursor to iterate over a number of keys and values in the latest version of this map.
        Parameters:
        from - the first key to return
        to - the last key to return
        reverse - if true, iterate in reverse (descending) order
        Returns:
        the cursor
      • cursor

        public Cursor<K,​V> cursor​(RootReference<K,​V> rootReference,
                                        K from,
                                        K to,
                                        boolean reverse)
        Get a cursor to iterate over a number of keys and values.
        Parameters:
        rootReference - of this map's version to iterate over
        from - the first key to return
        to - the last key to return
        reverse - if true, iterate in reverse (descending) order
        Returns:
        the cursor
      • entrySet

        public final java.util.Set<java.util.Map.Entry<K,​V>> entrySet()
        Specified by:
        entrySet in interface java.util.Map<K,​V>
        Specified by:
        entrySet in class java.util.AbstractMap<K,​V>
      • keySet

        public java.util.Set<K> keySet()
        Specified by:
        keySet in interface java.util.Map<K,​V>
        Overrides:
        keySet in class java.util.AbstractMap<K,​V>
      • getName

        public final java.lang.String getName()
        Get the map name.
        Returns:
        the name
      • getStore

        public final MVStore getStore()
      • isPersistent

        protected final boolean isPersistent()
      • getId

        public final int getId()
        Get the map id. Please note the map id may be different after compacting a store.
        Returns:
        the map id
      • getRootPage

        public final Page<K,​V> getRootPage()
        The current root page (may not be null).
        Returns:
        the root page
      • flushAndGetRoot

        public RootReference<K,​V> flushAndGetRoot()
        Get the root reference, flushing any current append buffer.
        Returns:
        current root reference
      • updateRoot

        protected static <K,​V> boolean updateRoot​(RootReference<K,​V> expectedRootReference,
                                                        Page<K,​V> newRootPage,
                                                        int attemptUpdateCounter)
        Use the new root page from now on.
        Type Parameters:
        K - the key class
        V - the value class
        Parameters:
        expectedRootReference - expected current root reference
        newRootPage - the new root page
        attemptUpdateCounter - how many attempt (including current) were made to update root
        Returns:
        new RootReference or null if update failed
      • isReadOnly

        public final boolean isReadOnly()
      • setVolatile

        public final void setVolatile​(boolean isVolatile)
        Set the volatile flag of the map.
        Parameters:
        isVolatile - the volatile flag
      • isVolatile

        public final boolean isVolatile()
        Whether this is volatile map, meaning that changes are not persisted. By default, even if the store is not persisted, maps are not volatile.
        Returns:
        whether this map is volatile
      • beforeWrite

        protected final void beforeWrite()
        This method is called before writing to the map. The default implementation checks whether writing is allowed, and tries to detect concurrent modification.
        Throws:
        java.lang.UnsupportedOperationException - if the map is read-only, or if another thread is concurrently writing
      • hashCode

        public final int hashCode()
        Specified by:
        hashCode in interface java.util.Map<K,​V>
        Overrides:
        hashCode in class java.util.AbstractMap<K,​V>
      • equals

        public final boolean equals​(java.lang.Object o)
        Specified by:
        equals in interface java.util.Map<K,​V>
        Overrides:
        equals in class java.util.AbstractMap<K,​V>
      • size

        public final int size()
        Get the number of entries, as integer. Integer.MAX_VALUE is returned if there are more entries than it can hold.
        Specified by:
        size in interface java.util.Map<K,​V>
        Overrides:
        size in class java.util.AbstractMap<K,​V>
        Returns:
        the number of entries, as an integer
        See Also:
        sizeAsLong()
      • sizeAsLong

        public final long sizeAsLong()
        Get the number of entries, as a long.
        Returns:
        the number of entries
      • isEmpty

        public boolean isEmpty()
        Specified by:
        isEmpty in interface java.util.Map<K,​V>
        Overrides:
        isEmpty in class java.util.AbstractMap<K,​V>
      • openVersion

        public final MVMap<K,​V> openVersion​(long version)
        Open an old version for the given map. It will restore map at last known state of the version specified. (at the point right before the commit() call, which advanced map to the next version) Map is opened in read-only mode.
        Parameters:
        version - the version
        Returns:
        the map
      • getVersion

        public final long getVersion()
        Get version of the map, which is the version of the store, at the moment when map was modified last time.
        Returns:
        version
      • getChildPageCount

        protected int getChildPageCount​(Page<K,​V> p)
        Get the child page count for this page. This is to allow another map implementation to override the default, in case the last child is not to be used.
        Parameters:
        p - the page
        Returns:
        the number of direct children
      • getType

        public java.lang.String getType()
        Get the map type. When opening an existing map, the map type must match.
        Returns:
        the map type
      • asString

        protected java.lang.String asString​(java.lang.String name)
        Get the map metadata as a string.
        Parameters:
        name - the map name (or null)
        Returns:
        the string
      • createEmptyLeaf

        protected Page<K,​V> createEmptyLeaf()
        Create empty leaf node page.
        Returns:
        new page
      • createEmptyNode

        protected Page<K,​V> createEmptyNode()
        Create empty internal node page.
        Returns:
        new page
      • append

        public void append​(K key,
                           V value)
        Appends entry to this map. this method is NOT thread safe and can not be used neither concurrently, nor in combination with any method that updates this map. Non-updating method may be used concurrently, but latest appended values are not guaranteed to be visible.
        Parameters:
        key - should be higher in map's order than any existing key
        value - to be appended
      • trimLast

        public void trimLast()
        Removes last entry from this map. this method is NOT thread safe and can not be used neither concurrently, nor in combination with any method that updates this map. Non-updating method may be used concurrently, but latest removal may not be visible.
      • toString

        public final java.lang.String toString()
        Overrides:
        toString in class java.util.AbstractMap<K,​V>
      • operate

        public V operate​(K key,
                         V value,
                         MVMap.DecisionMaker<V> decisionMaker)
        Add, replace or remove a key-value pair.
        Parameters:
        key - the key (may not be null)
        value - new value, it may be null when removal is intended
        decisionMaker - command object to make choices during transaction.
        Returns:
        previous value, if mapping for that key existed, or null otherwise
      • tryLock

        protected RootReference<K,​V> tryLock​(RootReference<K,​V> rootReference,
                                                   int attempt)
        Try to lock the root.
        Parameters:
        rootReference - the old root reference
        attempt - the number of attempts so far
        Returns:
        the new root reference
      • unlockRoot

        protected void unlockRoot​(Page<K,​V> newRootPage)
        Unlock the root page.
        Parameters:
        newRootPage - the new root