public class SafeSortedMap extends AbstractMap implements SortedMap
SortedMap
based on a
skip-list that is structurally thread-safe. SafeSortedMap uses lockless
(CAS-based) algorithms so all operations are performed without
synchronization. In the presence of concurrent updates, SafeSortedMap
iterators will reflect some state of the map, but will not throw
ConcurrentModificationException or other unexpected exceptions.
Note that the ordering maintained by a sorted map (whether or not an explicit comparator is provided) must be consistent with equals if this sorted map is to correctly implement the Map interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, but a map performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a sorted map is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Map interface.
The structure of the SafeSortedMap is maintained in a 2-dimensional lattice:
Top | I3 -------------------------------> S5 -------------> | | I2 -------------> S2 -------------> S5 -------------> | | | I1 -------> S1 -> S2 -------> S4 -> S5 -------> S7 -> | | | | | | E -> E0 -> E1 -> E2 -> E3 -> E4 -> E5 -> E6 -> E7 ->
Searching for a key involves traversing, starting from the top index node, as far to the right at each index level, then down. For example, the search path for the element E4 in the above example would be:
Removing a key involves inserting a temporary marker-entry while the entry pointers are fixed up. The marker node allows uncontended read threads to traverse the safely. Additionally, removing a key causes any index nodes for that key to be removed as well.
In the above example, the steps to remove entry E3 would be:
Modifier and Type | Class and Description |
---|---|
protected static class |
SafeSortedMap.BaseEntryNode
BaseEntryNode is a synthetic EntryNode that serves as the "head" of the
base entry list.
|
protected static class |
SafeSortedMap.EntryNode
EntryNode represents a key-value mapping in this map.
|
protected class |
SafeSortedMap.IndexNode
IndexNode represents the start node in the map's lattice representation
at a given index-level.
|
protected static class |
SafeSortedMap.SkipNode
SkipNode is an entry or index node in the lattice for a SafeSortedMap's
representation.
|
class |
SafeSortedMap.Split
Split encapsulates the headMap and tailMap of the SafeSortedMap at a
given split-key and could be used as an optimization facility when
both head and tail portions of the SortedMap are needed.
|
protected class |
SafeSortedMap.ViewMap
ViewMap provides a SortedMap view over a subset of the SafeSortedMap.
|
AbstractMap.SimpleEntry<K,V>, AbstractMap.SimpleImmutableEntry<K,V>
Modifier and Type | Field and Description |
---|---|
protected static Object |
BASE_VALUE
Placeholder for a non-existent (deleted) value.
|
protected static int |
DEFAULT_MAX_LEVEL
The default limit on the index-level.
|
protected static int |
DEFAULT_SPAN
The default span value.
|
protected float[] |
m_aflProbabilityThresholds
The array of pre-computed probability thresholds for each level.
|
protected static AtomicReferenceFieldUpdater |
m_atomicUpdaterTopNode
AtomicUpdater for the casTopNode operation.
|
protected Comparator |
m_comparator
The comparator used to sort this map.
|
protected SafeSortedMap.ViewMap |
m_mapView
The default ViewMap (over the entire map's range).
|
protected int |
m_nLevelMax
The maximum number of index levels to use for this map.
|
protected SafeSortedMap.IndexNode |
m_nodeTop
The top index node.
|
protected int |
m_nSpan
The span of the map.
|
protected Random |
m_random
The random-number generator for the map.
|
protected static Object |
NO_VALUE
Placeholder for a non-existent (deleted) value.
|
protected static int |
SEARCH_EQ
Search mode for equal-to.
|
protected static int |
SEARCH_GT
Search mode for strictly greater-than.
|
protected static int |
SEARCH_GTEQ
Search mode for greater-than or equal.
|
protected static int |
SEARCH_LT
Search mode for strictly less-than.
|
protected static int |
SEARCH_LTEQ
Search mode for less-than or equal.
|
Constructor and Description |
---|
SafeSortedMap()
Construct a new SafeSortedMap using the natural ordering of the
Comparable keys in this map.
|
SafeSortedMap(Comparator comparator)
Construct a new SafeSortedMap with the specified Comparator.
|
SafeSortedMap(Comparator comparator,
int nSpan,
int nLevelMax)
Construct a new SafeSortedMap with the specified parameters.
|
Modifier and Type | Method and Description |
---|---|
protected int |
calculateRandomLevel()
Randomly generate a level value 0 <= L <= MAX_LEVEL, in
such a way that the probability p(l) of generating level l
is equal to p(l)=(1/span)^(l+1) and
p(0)=1-(sum of p(l) over l=1..MAX_LEVEL).
|
protected boolean |
casTopNode(SafeSortedMap.IndexNode nodeTopAssume,
SafeSortedMap.IndexNode nodeTopNew)
Atomically set specified IndexNode to the top node iff the current top
node is the expected top node.
|
void |
clear() |
Comparator |
comparator() |
protected static float[] |
computeProbabilityThresholds(int nLevelMax,
int nSpan)
compute and return an array, indexed by level, of the probability
thresholds used to determine what level an entry should be indexed to.
|
boolean |
containsKey(Object oKey) |
String |
dump()
Return a human-readable description of this map's internal state.
|
Set |
entrySet() |
protected SafeSortedMap.EntryNode |
findNearest(SafeSortedMap.IndexNode nodeTop,
Object oKey,
int nMode,
boolean fFixLinks)
Return the SkipNode closest to the specified key, or null.
|
protected SafeSortedMap.EntryNode |
findNearestIndexedEntry(SafeSortedMap.IndexNode nodeTop,
Object oKey,
int nMode)
Return the EntryNode nearest to the specified key according to the
specified search mode, or the synthetic base node if there is none.
|
protected SafeSortedMap.EntryNode |
findPredecessor(SafeSortedMap.IndexNode nodeTop,
Object oKey)
Return an EntryNode that compares strictly less than the specified key, or
the synthetic base node if there is none.
|
Object |
firstKey() |
protected SafeSortedMap.EntryNode |
firstNode()
Return the first valid EntryNode, or null if there are none.
|
Object |
get(Object oKey) |
protected SafeSortedMap.BaseEntryNode |
getBaseNode()
Return the base entry node.
|
Map.Entry |
getEntry(Object oKey)
Locate a Map.Entry in this map based on its key.
|
protected int |
getMaxLevel()
Return the maximum index-level that this map is allowed to reach.
|
protected float[] |
getProbabilityThresholds()
Return the precomputed array of probability thresholds used by this map to
determine what index levels to build.
|
protected Random |
getRandom()
Return the random number generator for this map.
|
protected int |
getSpan()
Return the span of this map.
|
protected SafeSortedMap.IndexNode |
getTopNode()
Return the top index node in the map.
|
protected SafeSortedMap.ViewMap |
getViewMap()
Return a view of the entire map.
|
SortedMap |
headMap(Object toKey) |
protected void |
initialize()
Initialize the index nodes.
|
protected void |
insertIndex(SafeSortedMap.IndexNode nodeTop,
SafeSortedMap.EntryNode nodeNew,
int nLevelThis)
Insert a index nodes for the specified newly inserted EntryNode, up to a
random index-level.
|
Object |
lastKey() |
protected SafeSortedMap.EntryNode |
lastNode()
Return the last valid EntryNode, or null if there are none.
|
Object |
put(Object oKey,
Object oValue) |
Object |
remove(Object oKey) |
protected void |
setTopNode(SafeSortedMap.IndexNode nodeTop)
Set the top index node in the map.
|
int |
size() |
SafeSortedMap.Split |
split(Object oKey)
Return a
SafeSortedMap.Split of this map at the specified key. |
SortedMap |
subMap(Object fromKey,
Object toKey) |
SortedMap |
tailMap(Object fromKey) |
clone, containsValue, equals, hashCode, isEmpty, keySet, putAll, toString, values
finalize, getClass, notify, notifyAll, wait, wait, wait
compute, computeIfAbsent, computeIfPresent, containsValue, equals, forEach, getOrDefault, hashCode, isEmpty, merge, putAll, putIfAbsent, remove, replace, replace, replaceAll
protected static final int DEFAULT_SPAN
protected static final int DEFAULT_MAX_LEVEL
protected static final int SEARCH_EQ
protected static final int SEARCH_LT
protected static final int SEARCH_GT
protected static final int SEARCH_LTEQ
protected static final int SEARCH_GTEQ
protected static final Object NO_VALUE
protected static final Object BASE_VALUE
protected static final AtomicReferenceFieldUpdater m_atomicUpdaterTopNode
protected final Comparator m_comparator
protected final int m_nLevelMax
protected final float[] m_aflProbabilityThresholds
protected int m_nSpan
protected final SafeSortedMap.ViewMap m_mapView
protected volatile SafeSortedMap.IndexNode m_nodeTop
protected Random m_random
public SafeSortedMap()
public SafeSortedMap(Comparator comparator)
comparator
- the comparator used to sort this mappublic SafeSortedMap(Comparator comparator, int nSpan, int nLevelMax)
comparator
- the comparator used to sort this map, or null for
the entries' natural orderingnSpan
- the average span to use for each index-levelnLevelMax
- the maximum index-level to use for this mappublic int size()
size
in interface Map
size
in class AbstractMap
public boolean containsKey(Object oKey)
containsKey
in interface Map
containsKey
in class AbstractMap
public Set entrySet()
public Object put(Object oKey, Object oValue)
put
in interface Map
put
in class AbstractMap
public Object get(Object oKey)
get
in interface Map
get
in class AbstractMap
public Map.Entry getEntry(Object oKey)
Note: the behaviour of {#setValue} on the returned Entry is undefined in the presence of concurrent modifications
oKey
- the key to return an Entry forpublic Object remove(Object oKey)
remove
in interface Map
remove
in class AbstractMap
public void clear()
clear
in interface Map
clear
in class AbstractMap
public Comparator comparator()
comparator
in interface SortedMap
protected SafeSortedMap.ViewMap getViewMap()
protected float[] getProbabilityThresholds()
calculateRandomLevel()
protected Random getRandom()
protected int getMaxLevel()
protected int getSpan()
protected void initialize()
protected SafeSortedMap.IndexNode getTopNode()
protected void setTopNode(SafeSortedMap.IndexNode nodeTop)
nodeTop
- the new top index nodeprotected boolean casTopNode(SafeSortedMap.IndexNode nodeTopAssume, SafeSortedMap.IndexNode nodeTopNew)
nodeTopAssume
- the IndexNode assumed to be the current top nodenodeTopNew
- the new top nodeprotected SafeSortedMap.BaseEntryNode getBaseNode()
protected SafeSortedMap.EntryNode firstNode()
protected SafeSortedMap.EntryNode lastNode()
protected void insertIndex(SafeSortedMap.IndexNode nodeTop, SafeSortedMap.EntryNode nodeNew, int nLevelThis)
nodeTop
- the top index nodenodeNew
- the newly inserted EntryNodenLevelThis
- the level at which to index the specified EntryNodeprotected SafeSortedMap.EntryNode findNearest(SafeSortedMap.IndexNode nodeTop, Object oKey, int nMode, boolean fFixLinks)
nodeTop
- the top index nodeoKey
- the key to search fornMode
- one of the SEARCH_* constantsfFixLinks
- true iff deletion links must be fixedprotected SafeSortedMap.EntryNode findPredecessor(SafeSortedMap.IndexNode nodeTop, Object oKey)
Note: this method is merely guaranteed to return some EntryNode that is less than the specified node, not necessarily the node that is immediately less than the specified node
nodeTop
- the top index nodeoKey
- the key to find a predecessor forprotected SafeSortedMap.EntryNode findNearestIndexedEntry(SafeSortedMap.IndexNode nodeTop, Object oKey, int nMode)
nodeTop
- the top index nodeoKey
- the key to find an indexed EntryNode fornMode
- SEARCH_LT or SEARCH_LTEQ)protected static float[] computeProbabilityThresholds(int nLevelMax, int nSpan)
Threshold values are in the range [0, 1). A randomly chosen value v in that range corresponds to a level l iff the following condition holds: threshold[l-1] <= v < threshold[l-1]
nLevelMax
- the maximum number of levels to compute thresholds fornSpan
- the span of this mapprotected int calculateRandomLevel()
For example, the probabilities (with span=2, and weight of 2) of returning the following levels are: 0 (no-index) - 3/4 1 - 1/8 2 - 1/16 3 - 1/32 ...
public String dump()
public SafeSortedMap.Split split(Object oKey)
SafeSortedMap.Split
of this map at the specified key.oKey
- the key at which to split the map