org.h2.mvstore
Class MVMap<K,V>

java.lang.Object
  extended by java.util.AbstractMap<K,V>
      extended by org.h2.mvstore.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:
MVMapConcurrent, MVRTreeMap, SequenceMap

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

A stored map.


Nested Class Summary
static class MVMap.Builder<K,V>
          A builder for this class.
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,V>, java.util.AbstractMap.SimpleImmutableEntry<K,V>
 
Nested classes/interfaces inherited from interface java.util.Map
java.util.Map.Entry<K,V>
 
Field Summary
protected  long currentWriteVersion
          This version is set during a write operation.
protected  Page root
          The current root page (may not be null).
protected  MVStore store
          The store.
protected  long writeVersion
          The version used for writing.
 
Constructor Summary
protected MVMap(DataType keyType, DataType valueType)
           
 
Method Summary
protected  void afterWrite()
          This method is called after writing to the map (whether or not the write operation was successful).
 boolean areValuesEqual(java.lang.Object a, java.lang.Object b)
          Check whether the two values are equal.
protected  void beforeWrite()
          This method is called before writing to the map.
protected  java.lang.Object binarySearch(Page p, java.lang.Object key)
          Get the value for the given key, or null if not found.
protected  Page binarySearchPage(Page p, java.lang.Object key)
          Get the value for the given key, or null if not found.
 K ceilingKey(K key)
          Get the smallest key that is larger or equal to this key.
protected  void checkConcurrentWrite()
          Check that no write operation is in progress.
 void clear()
          Remove all entries.
 boolean containsKey(java.lang.Object key)
           
protected  Page copyOnWrite(Page p, long writeVersion)
          Create a copy of a page, if the write version is higher than the current version.
 Cursor<K,V> cursor(K from)
          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.
 V get(java.lang.Object key)
          Get a value.
protected  int getChildPageCount(Page p)
          Get the child page count for this page.
 long getCreateVersion()
           
protected  K getFirstLast(boolean first)
          Get the first (lowest) or last (largest) key.
 int getId()
           
 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 getKeyType()
          Get the key type.
protected  K getMinMax(K key, boolean min, boolean excluding)
          Get the smallest or largest key using the given bounds.
 java.lang.String getName()
          Get the map name.
protected  Page getPage(K key)
          Get the page for the given value.
 Page getRoot()
          Get the root page.
 java.lang.String getType()
          Get the map type.
 DataType getValueType()
          Get the value type.
 long getVersion()
           
 int hashCode()
           
 K higherKey(K key)
          Get the smallest key that is larger than the given key, or null if no such key exists.
protected  void init(MVStore store, java.util.HashMap<java.lang.String,java.lang.String> config)
          Open this map with the given store and configuration.
 boolean isClosed()
           
 boolean isEmpty()
           
 boolean isReadOnly()
           
 java.util.Iterator<K> keyIterator(K from)
          Iterate over a number of keys.
 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.
protected  void newRoot(Page newRoot)
          Use the new root page from now on.
 MVMap<K,V> openVersion(long version)
          Open an old version for the given map.
 V put(K key, V value)
          Add or replace a key-value pair.
protected  java.lang.Object put(Page p, long writeVersion, java.lang.Object key, java.lang.Object value)
          Add or update a key-value pair.
 V putIfAbsent(K key, V value)
          Add a key-value pair if it does not yet exist.
 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.
protected  java.lang.Object remove(Page p, long writeVersion, java.lang.Object key)
          Remove a key-value pair.
protected  void removePage(long pos)
          Remove the given page (make the space available).
 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.
 int size()
          Get the number of entries, as a integer.
 long sizeAsLong()
          Get the number of entries, as a long.
protected  Page splitRootIfNeeded(Page p, long writeVersion)
          Split the root page if necessary.
 java.lang.String toString()
           
protected  void waitUntilWritten(long version)
          If there is a concurrent update to the given version, wait until it is finished.
 
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.Map
containsValue, putAll, values
 

Field Detail

store

protected MVStore store
The store.


root

protected volatile Page root
The current root page (may not be null).


writeVersion

protected volatile long writeVersion
The version used for writing.


currentWriteVersion

protected volatile long currentWriteVersion
This version is set during a write operation.

Constructor Detail

MVMap

protected MVMap(DataType keyType,
                DataType valueType)
Method Detail

init

protected void init(MVStore store,
                    java.util.HashMap<java.lang.String,java.lang.String> config)
Open this map with the given store and configuration.

Parameters:
store - the store
config - the configuration

copyOnWrite

protected Page copyOnWrite(Page p,
                           long writeVersion)
Create a copy of a page, if the write version is higher than the current version. If a copy is created, the old page is marked as deleted.

Parameters:
p - the page
writeVersion - the write version
Returns:
a page with the given write version

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

splitRootIfNeeded

protected Page splitRootIfNeeded(Page p,
                                 long writeVersion)
Split the root page if necessary.

Parameters:
p - the page
writeVersion - the write version
Returns:
the new sibling

put

protected java.lang.Object put(Page p,
                               long writeVersion,
                               java.lang.Object key,
                               java.lang.Object value)
Add or update a key-value pair.

Parameters:
p - the page
writeVersion - the write version
key - the key (may not be null)
value - the value (may not be null)
Returns:
the old value, or null

firstKey

public K firstKey()
Get the first key, or null if the map is empty.

Returns:
the first key, or null

lastKey

public K lastKey()
Get the last key, or null if the map is empty.

Returns:
the last key, or null

getKey

public 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 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 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

getFirstLast

protected K getFirstLast(boolean first)
Get the first (lowest) or last (largest) key.

Parameters:
first - whether to retrieve the first key
Returns:
the key, or null if the map is empty

higherKey

public K higherKey(K key)
Get the smallest key that is larger than the given key, or null if no such key exists.

Parameters:
key - the key
Returns:
the result

ceilingKey

public 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 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 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

getMinMax

protected K getMinMax(K key,
                      boolean min,
                      boolean excluding)
Get the smallest or largest key using the given bounds.

Parameters:
key - the key
min - whether to retrieve the smallest key
excluding - if the given upper/lower bound is exclusive
Returns:
the key, or null if no such key exists

get

public V get(java.lang.Object key)
Get a value.

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

binarySearch

protected java.lang.Object binarySearch(Page p,
                                        java.lang.Object key)
Get the value for the given key, or null if not found.

Parameters:
p - the page
key - the key
Returns:
the value or null

containsKey

public 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>

getPage

protected Page getPage(K key)
Get the page for the given value.

Parameters:
key - the key
Returns:
the value, or null if not found

binarySearchPage

protected Page binarySearchPage(Page p,
                                java.lang.Object key)
Get the value for the given key, or null if not found.

Parameters:
p - the parent page
key - the key
Returns:
the page or null

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>

isClosed

public 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

putIfAbsent

public 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>
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>
Parameters:
key - the key (may not be null)
value - the expected value
Returns:
true if the item was removed

areValuesEqual

public boolean areValuesEqual(java.lang.Object a,
                              java.lang.Object b)
Check whether the two values are equal.

Parameters:
a - the first value
b - the second value
Returns:
true if they are equal

replace

public 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>
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 V replace(K key,
                 V value)
Replace a value for an existing key.

Specified by:
replace in interface java.util.concurrent.ConcurrentMap<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

remove

protected java.lang.Object remove(Page p,
                                  long writeVersion,
                                  java.lang.Object key)
Remove a key-value pair.

Parameters:
p - the page (may not be null)
writeVersion - the write version
key - the key
Returns:
the old value, or null if the key did not exist

newRoot

protected void newRoot(Page newRoot)
Use the new root page from now on.

Parameters:
newRoot - the new root page

getKeyType

public DataType getKeyType()
Get the key type.

Returns:
the key type

getValueType

public DataType getValueType()
Get the value type.

Returns:
the value type

keyIterator

public java.util.Iterator<K> keyIterator(K from)
Iterate over a number of keys.

Parameters:
from - the first key to return
Returns:
the iterator

cursor

public Cursor<K,V> cursor(K from)
Get a cursor to iterate over a number of keys and values.

Parameters:
from - the first key to return
Returns:
the cursor

entrySet

public 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>

getRoot

public Page getRoot()
Get the root page.

Returns:
the root page

getName

public java.lang.String getName()
Get the map name.

Returns:
the name

getId

public int getId()

isReadOnly

public boolean isReadOnly()

beforeWrite

protected 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

checkConcurrentWrite

protected void checkConcurrentWrite()
Check that no write operation is in progress.


afterWrite

protected void afterWrite()
This method is called after writing to the map (whether or not the write operation was successful).


waitUntilWritten

protected void waitUntilWritten(long version)
If there is a concurrent update to the given version, wait until it is finished.

Parameters:
version - the read version

hashCode

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

equals

public 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 int size()
Get the number of entries, as a integer. Integer.MAX_VALUE is returned if there are more than this entries.

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

sizeAsLong

public 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>

getCreateVersion

public long getCreateVersion()

removePage

protected void removePage(long pos)
Remove the given page (make the space available).

Parameters:
pos - the position of the page to remove

openVersion

public MVMap<K,V> openVersion(long version)
Open an old version for the given map.

Parameters:
version - the version
Returns:
the map

getVersion

public long getVersion()

getChildPageCount

protected int getChildPageCount(Page 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

toString

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