public class BTreeMap<K,V> implements Verifiable, ConcurrencyAware, ConcurrentNavigableMapExtra<K,V>
A scalable concurrent {@link ConcurrentNavigableMap} implementation. The map is sorted according to the {@linkplain Comparable natural ordering} of its keys, or by a {@link Comparator} provided at map creation time.
Insertion, removal, update, and access operations safely execute concurrently by multiple threads. Iterators are weakly consistent, returning elements reflecting the state of the map at some point at or since the creation of the iterator. They do not throw {@link ConcurrentModificationException}, and may proceed concurrently with other operations. Ascending key ordered views and their iterators are faster than descending ones.
By default BTreeMap does not track its size and {@code size()} traverses collection to count its entries. There is option to enable counter, in that case {@code size()} returns instantly
Additionally, the bulk operations putAll, equals, and clear are not guaranteed to be performed atomically. For example, an iterator operating concurrently with a putAll operation might view only some of the added elements. NOTE: there is an optional
This class and its views and iterators implement all of the optional methods of the {@link Map} and {@link Iterator} interfaces. Like most other concurrent collections, this class does not permit the use of null keys or values because some null return values cannot be reliably distinguished from the absence of
Theoretical design of BTreeMap is based on 1986 paper Concurrent operations on B∗-trees with overtaking written by Yehoshua Sagiv. More practical aspects of BTreeMap implementation are based on demo application from Thomas Dinsdale-Young. Also more work from Thomas: A Simple Abstraction for Complex Concurrent Indexes
B-Linked-Tree used here does not require locking for read. Updates and inserts locks only one, two or three nodes.
This B-Linked-Tree structure does not support removal well, entry deletion does not collapse tree nodes. Massive deletion causes empty nodes and performance lost. There is workaround in form of compaction process, but it is not implemented yet.
Modifier and Type | Class and Description |
---|---|
static class |
BTreeMap.BTreeBoundIterator<K,V> |
static class |
BTreeMap.BTreeIterator<K,V> |
static class |
BTreeMap.Companion |
static class |
BTreeMap.DescendingBoundIterator<K,V> |
static class |
BTreeMap.DescendingIterator<K,V> |
ConcurrencyAware.DefaultImpls
Modifier and Type | Field and Description |
---|---|
static BTreeMap.Companion |
Companion |
Constructor and Description |
---|
BTreeMap(GroupSerializer<K> keySerializer,
GroupSerializer<V> valueSerializer,
long rootRecidRecid,
Store store,
boolean valueInline,
int maxNodeSize,
java.util.Comparator<K> comparator,
boolean isThreadSafe,
long counterRecid,
boolean hasValues,
MapModificationListener<K,V>[] modificationListeners)
A scalable concurrent {@link ConcurrentNavigableMap} implementation.
The map is sorted according to the {@linkplain Comparable natural
ordering} of its keys, or by a {@link Comparator} provided at map
creation time.
|
Modifier and Type | Method and Description |
---|---|
void |
assertCurrentThreadUnlocked() |
java.util.Map.Entry<K,V> |
btreeEntry(K key,
V valueOrig) |
java.util.Map.Entry<K,V> |
ceilingEntry(K key) |
K |
ceilingKey(K key) |
void |
checkThreadSafe()
checks all subcomponents, if this component is really thread safe, and throws an exception if not thread safe
|
void |
clear() |
void |
close() |
java.util.Comparator<? super K> |
comparator() |
boolean |
containsKey(java.lang.Object key) |
boolean |
containsValue(java.lang.Object value) |
java.util.Iterator<java.util.Map.Entry> |
descendingEntryIterator() |
java.util.Iterator<java.util.Map.Entry> |
descendingEntryIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.Iterator<K> |
descendingKeyIterator() |
java.util.Iterator<K> |
descendingKeyIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.NavigableSet<K> |
descendingKeySet() |
java.util.Iterator<org.mapdb.BTreeMapJava.Node> |
descendingLeafIterator(K hi) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
descendingMap() |
java.util.Iterator<V> |
descendingValueIterator() |
java.util.Iterator<V> |
descendingValueIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.Iterator<java.util.Map.Entry> |
entryIterator() |
java.util.Iterator<java.util.Map.Entry> |
entryIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.Set |
entrySet() |
boolean |
equals(java.lang.Object other) |
java.util.Map.Entry<K,V> |
findHigher(K key,
boolean inclusive) |
K |
findHigherKey(K key,
boolean inclusive) |
java.util.Map.Entry<K,V> |
findLower(K key,
boolean inclusive) |
K |
findLowerKey(K key,
boolean inclusive) |
java.util.Map.Entry<K,V> |
firstEntry() |
K |
firstKey() |
K |
firstKey2() |
java.util.Map.Entry<K,V> |
floorEntry(K key) |
K |
floorKey(K key) |
void |
forEach(java.util.function.BiConsumer<? super K,? super V> action) |
void |
forEachKey(Function1<? super K,Unit> procedure) |
void |
forEachValue(Function1<? super V,Unit> procedure) |
V |
get(java.lang.Object key) |
java.util.Comparator<K> |
getComparator() |
long |
getCounterRecid() |
java.util.Set<java.util.Map.Entry> |
getEntries() |
boolean |
getHasValues() |
GroupSerializer<K> |
getKeySerializer() |
java.util.NavigableSet<K> |
getKeys() |
NonExistentClass |
getLeftEdges()
recids of left-most nodes in tree
|
java.util.concurrent.ConcurrentHashMap<java.lang.Long,java.lang.Long> |
getLocks() |
int |
getMaxNodeSize() |
BTreeMapJava.NodeSerializer |
getNodeSerializer() |
long |
getRootRecid() |
long |
getRootRecidRecid() |
int |
getSize() |
Store |
getStore() |
boolean |
getValueInline() |
GroupSerializer<java.lang.Object> |
getValueNodeSerializer() |
GroupSerializer<V> |
getValueSerializer() |
java.util.Collection<V> |
getValues() |
int |
hashCode() |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
headMap(K toKey,
boolean inclusive) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
headMap(K toKey) |
java.util.Map.Entry<K,V> |
higherEntry(K key) |
K |
higherKey(K key) |
boolean |
isClosed() |
boolean |
isEmpty() |
boolean |
isThreadSafe()
returns true if this is configured to be thread safe
|
java.util.Iterator<K> |
keyIterator() |
java.util.Iterator<K> |
keyIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.Set |
keySet() |
java.util.Map.Entry<K,V> |
lastEntry() |
K |
lastKey() |
K |
lastKey2() |
void |
listenerNotify(K key,
V oldValue,
V newValue,
boolean triggered) |
void |
lock(long nodeRecid) |
java.util.Map.Entry<K,V> |
lowerEntry(K key) |
K |
lowerKey(K key) |
java.util.NavigableSet<K> |
navigableKeySet() |
java.util.Map.Entry<K,V> |
pollFirstEntry() |
java.util.Map.Entry<K,V> |
pollLastEntry() |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
prefixSubMap(K prefix) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
prefixSubMap(K prefix,
boolean inclusive) |
void |
printStructure(java.io.PrintStream out) |
V |
put(K key,
V value) |
V |
put2(K key,
V value,
boolean onlyIfAbsent) |
void |
putAll(java.util.Map<? extends K,? extends V> from) |
V |
putIfAbsent(K key,
V value) |
boolean |
putIfAbsentBoolean(K key,
V value)
Atomically associates the specified key with the given value if it is
not already associated with a value.
|
V |
remove(java.lang.Object key) |
boolean |
remove(java.lang.Object key,
java.lang.Object value) |
V |
removeOrReplace(K key,
V expectedOldValue,
V replaceWithValue) |
boolean |
replace(K key,
V oldValue,
V newValue) |
V |
replace(K key,
V value) |
int |
size() |
long |
sizeLong()
map size as long number
|
java.util.concurrent.ConcurrentNavigableMap<K,V> |
subMap(K fromKey,
boolean fromInclusive,
K toKey,
boolean toInclusive) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
subMap(K fromKey,
K toKey) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
tailMap(K fromKey,
boolean inclusive) |
java.util.concurrent.ConcurrentNavigableMap<K,V> |
tailMap(K fromKey) |
void |
unlock(long nodeRecid) |
void |
unlockAllCurrentThread() |
V |
valueExpand(java.lang.Object v) |
java.util.Iterator<V> |
valueIterator() |
java.util.Iterator<V> |
valueIterator(K lo,
boolean loInclusive,
K hi,
boolean hiInclusive) |
java.util.Collection |
values() |
void |
verify() |
verify
checkThreadSafe, isThreadSafe
descendingEntryIterator, descendingEntryIterator, descendingKeyIterator, descendingKeyIterator, descendingValueIterator, descendingValueIterator, entryIterator, findHigher, findHigherKey, findLower, findLowerKey, getHasValues, keyIterator, keyIterator, valueIterator
forEach, forEachKey, forEachValue, getKeySerializer, getValueSerializer, isClosed, putIfAbsentBoolean, sizeLong
firstKey2, lastKey2
public static BTreeMap.Companion Companion
public BTreeMap(GroupSerializer<K> keySerializer, GroupSerializer<V> valueSerializer, long rootRecidRecid, Store store, boolean valueInline, int maxNodeSize, java.util.Comparator<K> comparator, boolean isThreadSafe, long counterRecid, boolean hasValues, MapModificationListener<K,V>[] modificationListeners)
A scalable concurrent {@link ConcurrentNavigableMap} implementation. The map is sorted according to the {@linkplain Comparable natural ordering} of its keys, or by a {@link Comparator} provided at map creation time.
Insertion, removal, update, and access operations safely execute concurrently by multiple threads. Iterators are weakly consistent, returning elements reflecting the state of the map at some point at or since the creation of the iterator. They do not throw {@link ConcurrentModificationException}, and may proceed concurrently with other operations. Ascending key ordered views and their iterators are faster than descending ones.
By default BTreeMap does not track its size and {@code size()} traverses collection to count its entries. There is option to enable counter, in that case {@code size()} returns instantly
Additionally, the bulk operations putAll, equals, and clear are not guaranteed to be performed atomically. For example, an iterator operating concurrently with a putAll operation might view only some of the added elements. NOTE: there is an optional
This class and its views and iterators implement all of the optional methods of the {@link Map} and {@link Iterator} interfaces. Like most other concurrent collections, this class does not permit the use of null keys or values because some null return values cannot be reliably distinguished from the absence of
Theoretical design of BTreeMap is based on 1986 paper Concurrent operations on B∗-trees with overtaking written by Yehoshua Sagiv. More practical aspects of BTreeMap implementation are based on demo application from Thomas Dinsdale-Young. Also more work from Thomas: A Simple Abstraction for Complex Concurrent Indexes
B-Linked-Tree used here does not require locking for read. Updates and inserts locks only one, two or three nodes.
This B-Linked-Tree structure does not support removal well, entry deletion does not collapse tree nodes. Massive deletion causes empty nodes and performance lost. There is workaround in form of compaction process, but it is not implemented yet.
isThreadSafe
- returns true if this is configured to be thread safepublic GroupSerializer<java.lang.Object> getValueNodeSerializer()
public BTreeMapJava.NodeSerializer getNodeSerializer()
public long getRootRecid()
public NonExistentClass getLeftEdges()
recids of left-most nodes in tree
public java.util.concurrent.ConcurrentHashMap<java.lang.Long,java.lang.Long> getLocks()
public V get(java.lang.Object key)
public void listenerNotify(K key, V oldValue, V newValue, boolean triggered)
public V valueExpand(java.lang.Object v)
public V put(K key, V value)
public V put2(K key, V value, boolean onlyIfAbsent)
public V remove(java.lang.Object key)
public V removeOrReplace(K key, V expectedOldValue, V replaceWithValue)
public void lock(long nodeRecid)
public void unlock(long nodeRecid)
public void unlockAllCurrentThread()
public void assertCurrentThreadUnlocked()
public void close()
public void verify()
public void printStructure(java.io.PrintStream out)
public void putAll(java.util.Map<? extends K,? extends V> from)
public boolean putIfAbsentBoolean(K key, V value)
Atomically associates the specified key with the given value if it is not already associated with a value.
This is equivalent to:
if(cache.containsKey(key)){}cache.put(key,value);return true;}else{return false;}
*
except that the action is performed atomically.
public V putIfAbsent(K key, V value)
public boolean remove(java.lang.Object key, java.lang.Object value)
public boolean replace(K key, V oldValue, V newValue)
public V replace(K key, V value)
public boolean containsKey(java.lang.Object key)
public boolean containsValue(java.lang.Object value)
public boolean isEmpty()
public int getSize()
public int size()
public long sizeLong()
map size as long number
public java.util.NavigableSet<K> descendingKeySet()
public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap()
public java.util.Set<java.util.Map.Entry> getEntries()
public java.util.Set entrySet()
public java.util.NavigableSet<K> navigableKeySet()
public java.util.NavigableSet<K> getKeys()
public java.util.Set keySet()
public java.util.Collection<V> getValues()
public java.util.Collection values()
public java.util.Iterator<java.util.Map.Entry> entryIterator()
public java.util.Iterator<java.util.Map.Entry> entryIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Iterator<K> keyIterator()
public java.util.Iterator<K> keyIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Iterator<V> valueIterator()
public java.util.Iterator<V> valueIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Iterator<org.mapdb.BTreeMapJava.Node> descendingLeafIterator(K hi)
public java.util.Iterator<java.util.Map.Entry> descendingEntryIterator()
public java.util.Iterator<java.util.Map.Entry> descendingEntryIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Iterator<K> descendingKeyIterator()
public java.util.Iterator<K> descendingKeyIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Iterator<V> descendingValueIterator()
public java.util.Iterator<V> descendingValueIterator(K lo, boolean loInclusive, K hi, boolean hiInclusive)
public java.util.Map.Entry<K,V> btreeEntry(K key, V valueOrig)
public int hashCode()
public boolean equals(java.lang.Object other)
public boolean isClosed()
public void forEach(java.util.function.BiConsumer<? super K,? super V> action)
public void forEachKey(Function1<? super K,Unit> procedure)
public void forEachValue(Function1<? super V,Unit> procedure)
public java.util.concurrent.ConcurrentNavigableMap<K,V> prefixSubMap(K prefix)
public java.util.concurrent.ConcurrentNavigableMap<K,V> prefixSubMap(K prefix, boolean inclusive)
public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive)
public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey)
public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K toKey)
public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K fromKey)
public java.util.Comparator<? super K> comparator()
public java.util.Map.Entry<K,V> firstEntry()
public java.util.Map.Entry<K,V> lastEntry()
public K firstKey2()
public K lastKey2()
public K firstKey()
public K lastKey()
public java.util.Map.Entry<K,V> pollFirstEntry()
public java.util.Map.Entry<K,V> pollLastEntry()
public java.util.Map.Entry<K,V> findHigher(K key, boolean inclusive)
public java.util.Map.Entry<K,V> findLower(K key, boolean inclusive)
public K findHigherKey(K key, boolean inclusive)
public K findLowerKey(K key, boolean inclusive)
public java.util.Map.Entry<K,V> lowerEntry(K key)
public K lowerKey(K key)
public java.util.Map.Entry<K,V> floorEntry(K key)
public K floorKey(K key)
public java.util.Map.Entry<K,V> ceilingEntry(K key)
public K ceilingKey(K key)
public java.util.Map.Entry<K,V> higherEntry(K key)
public K higherKey(K key)
public void clear()
public void checkThreadSafe()
checks all subcomponents, if this component is really thread safe, and throws an exception if not thread safe
public GroupSerializer<K> getKeySerializer()
public GroupSerializer<V> getValueSerializer()
public long getRootRecidRecid()
public Store getStore()
public boolean getValueInline()
public int getMaxNodeSize()
public java.util.Comparator<K> getComparator()
public boolean isThreadSafe()
returns true if this is configured to be thread safe
public long getCounterRecid()
public boolean getHasValues()