public class SnapTreeMap<K,V> extends AbstractMap<K,V> implements ConcurrentNavigableMap<K,V>, Cloneable, Serializable
This data structure honors all of the contracts of ConcurrentSkipListMap
, with the additional contract
that clone, size, toArray, and iteration are linearizable (atomic).
The tree uses optimistic concurrency control. No locks are usually required for get, containsKey, firstKey, firstEntry, lastKey, or lastEntry. Reads are not lock free (or even obstruction free), but obstructing threads perform no memory allocation, system calls, or loops, which seems to work okay in practice. All of the updates to the tree are performed in fixed- size blocks, so restoration of the AVL balance criteria may occur after a change to the tree has linearized (but before the mutating operation has returned). The tree is always properly balanced when quiescent.
To clone the tree (or produce a snapshot for consistent iteration) the root node is marked as shared, which must be (*) done while there are no pending mutations. New mutating operations are blocked if a mark is pending, and when existing mutating operations are completed the mark is made. * - It would be less disruptive if we immediately marked the root as shared, and then waited for pending operations that might not have seen the mark without blocking new mutations. This could result in imbalance being frozen into the shared portion of the tree, though. To minimize the problem we perform the mark and reenable mutation on whichever thread notices that the entry count has become zero, to reduce context switches on the critical path.
The same multi-cache line data structure required for efficiently tracking the entry and exit for mutating operations is used to maintain the current size of the tree. This means that the size can be computed by quiescing as for a clone, but without doing any marking.
Range queries such as higherKey are not amenable to the optimistic hand-over-hand locking scheme used for exact searches, so they are implemented with pessimistic concurrency control. Mutation can be considered to acquire a lock on the map in Intention-eXclusive mode, range queries, size(), and root marking acquire the lock in Shared mode.
Modifier and Type | Class and Description |
---|---|
protected static class |
SnapTreeMap.Node<K,V> |
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
Constructor and Description |
---|
SnapTreeMap() |
SnapTreeMap(Comparator<? super K> comparator) |
SnapTreeMap(Map<? extends K,? extends V> source) |
SnapTreeMap(SortedMap<K,? extends V> source) |
public SnapTreeMap()
public SnapTreeMap(Comparator<? super K> comparator)
public SnapTreeMap<K,V> clone()
clone
in class AbstractMap<K,V>
public int size()
public boolean isEmpty()
public void clear()
public Comparator<? super K> comparator()
comparator
in interface SortedMap<K,V>
public boolean containsValue(Object value)
containsValue
in interface Map<K,V>
containsValue
in class AbstractMap<K,V>
public boolean containsKey(Object key)
containsKey
in interface Map<K,V>
containsKey
in class AbstractMap<K,V>
protected Comparable<? super K> comparable(Object key)
public Map.Entry<K,V> firstEntry()
firstEntry
in interface NavigableMap<K,V>
public K ceilingKey(K key)
ceilingKey
in interface NavigableMap<K,V>
public Map.Entry<K,V> lowerEntry(K key)
lowerEntry
in interface NavigableMap<K,V>
public Map.Entry<K,V> floorEntry(K key)
floorEntry
in interface NavigableMap<K,V>
public Map.Entry<K,V> ceilingEntry(K key)
ceilingEntry
in interface NavigableMap<K,V>
public Map.Entry<K,V> higherEntry(K key)
higherEntry
in interface NavigableMap<K,V>
public V putIfAbsent(K key, V value)
putIfAbsent
in interface ConcurrentMap<K,V>
public boolean replace(K key, V oldValue, V newValue)
replace
in interface ConcurrentMap<K,V>
public boolean remove(Object key, Object value)
remove
in interface ConcurrentMap<K,V>
protected void afterNodeUpdate_nl(SnapTreeMap.Node<K,V> node, Object val)
public Map.Entry<K,V> pollFirstEntry()
pollFirstEntry
in interface NavigableMap<K,V>
public Map.Entry<K,V> pollLastEntry()
pollLastEntry
in interface NavigableMap<K,V>
public NavigableSet<K> keySet()
public NavigableSet<K> navigableKeySet()
navigableKeySet
in interface ConcurrentNavigableMap<K,V>
navigableKeySet
in interface NavigableMap<K,V>
public NavigableSet<K> descendingKeySet()
descendingKeySet
in interface ConcurrentNavigableMap<K,V>
descendingKeySet
in interface NavigableMap<K,V>
public ConcurrentNavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
subMap
in interface ConcurrentNavigableMap<K,V>
subMap
in interface NavigableMap<K,V>
public ConcurrentNavigableMap<K,V> headMap(K toKey, boolean inclusive)
headMap
in interface ConcurrentNavigableMap<K,V>
headMap
in interface NavigableMap<K,V>
public ConcurrentNavigableMap<K,V> tailMap(K fromKey, boolean inclusive)
tailMap
in interface ConcurrentNavigableMap<K,V>
tailMap
in interface NavigableMap<K,V>
public ConcurrentNavigableMap<K,V> subMap(K fromKey, K toKey)
public ConcurrentNavigableMap<K,V> headMap(K toKey)
public ConcurrentNavigableMap<K,V> tailMap(K fromKey)
public ConcurrentNavigableMap<K,V> descendingMap()
descendingMap
in interface ConcurrentNavigableMap<K,V>
descendingMap
in interface NavigableMap<K,V>
Follow @ApacheIgnite
Ignite Fabric : ver. 2.0.0 Release Date : April 30 2017