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