public class SegmentedHashMap extends Base implements Map
Retrieval and update operations to the map (e.g. get, put) are non-blocking and uncontended and will reflect some state of the map. Insert and remove operations to the map (e.g. put, remove) do require internal locking.
The entries in the map are internally segmented so as to permit a high level of concurrent "locked" operations without contention.
Retrievals and updates that run concurrently with bulk operations (e.g. putAll, clear may reflect insertion or removal of only some entries. Iterators on the Map may also reflect concurrent updates made since the Iterator was created. However, Iterators will not throw ConcurrentModificationException.
Modifier and Type | Class and Description |
---|---|
protected static class |
SegmentedHashMap.ContainsValueAction
Action support for containsValue().
|
protected static class |
SegmentedHashMap.Entry
A map entry (key-value pair).
|
protected static interface |
SegmentedHashMap.EntryAction
An EntryAction encapsulates a logical action to be executed in the
context of a key (that may or may not exist in the map).
|
protected static class |
SegmentedHashMap.EntryActionAdapter
EntryActionAdapter is a convenience class that provides default
implementations for the EntryAction and IterableEntryAction interface
methods.
|
protected class |
SegmentedHashMap.EntrySet
A set of entries backed by this map.
|
protected class |
SegmentedHashMap.GetEntryAction
Action support for getEntryInternal.
|
protected class |
SegmentedHashMap.InsertAction
Action support for insert.
|
protected static interface |
SegmentedHashMap.IterableEntryAction
IterableEntryAction is an EntryAction that is suitable for applying to
all keys in a map.
|
protected class |
SegmentedHashMap.KeySet
A set of entries backed by this map.
|
protected class |
SegmentedHashMap.RemoveAction
Action support for remove().
|
protected static class |
SegmentedHashMap.Segment
Segment metadata.
|
protected class |
SegmentedHashMap.ValuesCollection
A collection of values backed by this map.
|
Base.LoggingWriter, Base.StackFrame
Modifier and Type | Field and Description |
---|---|
protected static int |
BIGGEST_MODULO
Biggest possible modulo.
|
static float |
DEFAULT_GROWTHRATE
Using the default growth rate, the bucket array will grow by a factor
of four.
|
static int |
DEFAULT_INITIALSIZE
Default initial size provides a prime modulo and is large enough that
resize is not immediate.
|
static float |
DEFAULT_LOADFACTOR
The default load factor is 100%, which means that the hash map will not
resize until there is (on average) one entry in every bucket.
|
protected static long |
LOCK_ALL_PENDING
The bit-mask used to indicate that a lock-all is pending.
|
protected static int |
LOCK_ALL_PENDING_IDX
The mutex number used to indicate that a lock-all is pending.
|
protected static int |
LOCK_COUNT
The number of segment-locks.
|
protected static long |
LOCKS_ALL
The lock representation used to indicate that all mutexes are locked.
|
protected static long |
LOCKS_NONE
The lock representation used to indicate that no locks are set.
|
protected SegmentedHashMap.ContainsValueAction |
m_actionContainsValue
The singleton action for containsValue support.
|
protected SegmentedHashMap.GetEntryAction |
m_actionGetEntry
The singleton action for getEntryInternal support.
|
protected SegmentedHashMap.InsertAction |
m_actionInsert
The singleton action for insert support.
|
protected SegmentedHashMap.RemoveAction |
m_actionRemove
The singleton action for remove support.
|
protected SegmentedHashMap.Entry[] |
m_aeBucket
The array of hash buckets.
|
protected SegmentedHashMap.Segment[] |
m_aSegment
An array of the control-structures for the Map's segments.
|
protected AtomicLong |
m_atomicLocks
The "segment-locks".
|
protected SegmentedHashMap.ValuesCollection |
m_colValues
The collection of values backed by this map.
|
protected int |
m_cSegmentCapacity
The capacity of each segment (the point at which we should resize).
|
protected float |
m_flGrowthRate
The rate of growth as a fraction of the current number of buckets,
0 < n, such that the hash map grows to bucketcount * (1 + growth-rate).
|
protected float |
m_flLoadFactor
The determining factor for the hash map capacity given a certain number
of buckets, such that capacity = bucketcount * loadfactor.
|
protected Object |
m_oIterActive
A holder for active Iterator(s): either WeakReference(<Iterator>) or
WeakHashMap(<Iterator> null)
|
protected SegmentedHashMap.EntrySet |
m_setEntries
The set of entries backed by this map.
|
protected SegmentedHashMap.KeySet |
m_setKeys
The set of keys backed by this map.
|
protected static int |
MIN_SEGMENT_CAPACITY
The minimum segment capacity.
|
protected static Object |
NO_VALUE
Object to be used as a value representing that the Entry object is
"synthetic" and while logically associated with a key, does not
represent a key-value mapping in the Map.
|
protected static int[] |
PRIME_MODULO
A list of possible modulos to use.
|
protected static int |
PUTALL_THRESHOLD
Size threshold used by the putAll operation.
|
protected Object |
RESIZING
When resizing completes, a notification is issued against this object.
|
protected static int |
SEGMENT_COUNT
The number of segments to partition the hash buckets into.
|
protected static int |
SEGMENT_LOCK_MAX_SPIN
Maximum number of times to spin while trying to acquire a segment lock
before waiting.
|
Constructor and Description |
---|
SegmentedHashMap()
Default constructor.
|
SegmentedHashMap(int cInitialBuckets,
float flLoadFactor,
float flGrowthRate)
Construct a thread-safe hash map using the specified settings.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Removes all mappings from this map.
|
boolean |
containsKey(Object oKey)
Returns true iff this map contains a mapping for the specified
key.
|
boolean |
containsValue(Object oValue)
Returns true if this map maps one or more keys to the
specified value.
|
protected void |
contendForSegment(int nSegment)
Wait for a segment to be unlocked.
|
protected void |
ensureLoadFactor(SegmentedHashMap.Segment segment)
Check whether or not the specified segment is overloaded and if so,
grow the bucket array (which suggests with high probability that the
per-segment load will decrease).
|
protected static SegmentedHashMap.Entry |
entryFromBucket(SegmentedHashMap.Entry[] aeBucket,
int nBucket)
Return the first non-synthetic Entry object contained by in the
specified bucket.
|
Set |
entrySet()
Returns a set view of the mappings contained in this map.
|
boolean |
equals(Object oThat)
Compares the specified object with this map for equality.
|
Object |
get(Object oKey)
Returns the value to which this map maps the specified key.
|
protected int |
getBucketIndex(int nHash,
int cBuckets)
Calculate the bucket number for a particular hash code.
|
protected SegmentedHashMap.ContainsValueAction |
getContainsValueAction()
Return the registered action for containsValue().
|
Map.Entry |
getEntry(Object key)
Locate an Entry in the this map based on its key.
|
protected SegmentedHashMap.Entry |
getEntryInternal(Object oKey)
Locate an Entry in the hash map based on its key.
|
protected SegmentedHashMap.Entry |
getEntryInternal(Object oKey,
boolean fSynthetic)
Locate an Entry in the hash map based on its key.
|
protected SegmentedHashMap.GetEntryAction |
getGetEntryAction()
Return the registered action for getEntryInternal.
|
protected SegmentedHashMap.InsertAction |
getInsertAction()
Return the registered action for insert.
|
protected SegmentedHashMap.RemoveAction |
getRemoveAction()
Return the registered action for remove().
|
protected SegmentedHashMap.Segment |
getSegmentForKey(Object oKey)
Return the Segment object for the specified key.
|
protected int |
getSegmentIndex(int nBucket)
Calculate the segment index for the the specified bucket.
|
protected SegmentedHashMap.Entry[] |
getStableBucketArray()
Get the bucket array, or if a resize is occurring, wait for the resize
to complete and return the new bucket array.
|
protected void |
grow()
Resize the bucket array, rehashing all Entries.
|
protected void |
grow(int cNew)
Resize the bucket array to the specified size, rehashing all Entries.
|
int |
hashCode()
Returns the hash code value for this Map.
|
protected void |
initializeActions()
Initialize the EntryAction's for this map.
|
protected SegmentedHashMap.ContainsValueAction |
instantiateContainsValueAction()
Factory for ContainsValueAction
|
protected SegmentedHashMap.Entry |
instantiateEntry(Object oKey,
Object oValue,
int nHash)
Factory for Entry.
|
protected SegmentedHashMap.EntrySet |
instantiateEntrySet()
Factory for EntrySet
|
protected SegmentedHashMap.GetEntryAction |
instantiateGetEntryAction()
Factory for GetEntryAction
|
protected SegmentedHashMap.InsertAction |
instantiateInsertAction()
Factory for InsertAction
|
protected SegmentedHashMap.KeySet |
instantiateKeySet()
Factory for KeySet.
|
protected SegmentedHashMap.RemoveAction |
instantiateRemoveAction()
Factory for RemoveAction
|
protected SegmentedHashMap.ValuesCollection |
instantiateValuesCollection()
Factory for ValuesCollection.
|
protected Object |
invokeOnAllKeys(Object oContext,
boolean fLock,
SegmentedHashMap.IterableEntryAction actionEntry)
Perform an action on all Entries in the map.
|
protected Object |
invokeOnKey(Object oKey,
Object oContext,
boolean fLock,
SegmentedHashMap.EntryAction action)
Perform an action on the specified key.
|
protected boolean |
isActiveIterator()
Determine if there are any active Iterators, which may mean that they
are in the middle of iterating over the Map.
|
boolean |
isEmpty()
Returns true if this map contains no key-value mappings.
|
protected void |
iteratorActivated(Iterator iter)
Register the activation of an Iterator.
|
Set |
keySet()
Returns a Set view of the keys contained in this map.
|
protected void |
lockAllBuckets()
Lock everything.
|
protected boolean |
lockAllBuckets(int nBucketAlreadyLocked)
Lock everything, assuming that the segment for the specified bucket has
already been locked.
|
protected boolean |
lockAllSegments(long lLocksHeld)
Lock all segments except for the specified segments that have already
been locked by the calling thread.
|
protected boolean |
lockBucket(int nBucket)
Attempt to lock the segment corresponding to the specified bucket.
|
protected boolean |
lockSegment(int nSegment,
boolean fBlock)
Attempt to lock the specified segment.
|
Object |
put(Object oKey,
Object oValue)
Associates the specified value with the specified key in this map.
|
void |
putAll(Map mapOther)
Copies all of the mappings from the specified map to this map.
|
protected Object |
putInternal(Object oKey,
Object oValue)
Associates the specified value with the specified key in this map.
|
protected Object |
putInternal(Object oKey,
Object oValue,
boolean fOnlyIfAbsent)
Associates the specified value with the specified key in this map.
|
void |
releaseIterator(Iterator iter)
Release the (formerly-active) Iterator.
|
Object |
remove(Object oKey)
Removes the mapping for this key from this map if present.
|
protected Object |
removeInternal(Object oKey,
SegmentedHashMap.EntryAction actionRemove,
Object oContext)
Removes the mapping for this key from this map if present.
|
protected void |
setContainsValueAction(SegmentedHashMap.ContainsValueAction action)
Specify the action for containsValue().
|
protected void |
setGetEntryAction(SegmentedHashMap.GetEntryAction action)
Specify the action for getEntryInternal.
|
protected void |
setInsertAction(SegmentedHashMap.InsertAction action)
Specify the action for insert.
|
protected void |
setRemoveAction(SegmentedHashMap.RemoveAction action)
Specify the action for remove().
|
int |
size()
Returns the number of key-value mappings in this map.
|
protected Object[] |
toArrayInternal(SegmentedHashMap.IterableEntryAction action,
Object[] a)
Apply the specified toArray() action to the entries in the map.
|
String |
toString()
Returns a String representation of this map.
|
protected void |
unlockAllBuckets()
Unlock everything.
|
protected void |
unlockAllBuckets(int nBucketLeaveLocked)
Unlock everything, leaving only the segment for the specified bucket
locked.
|
protected void |
unlockAllSegments(long lLocksKeep)
Unlock all segments, except the segment-locks indicated by the specified
bit-vector.
|
protected void |
unlockBucket(int nBucket)
Unlock the segment corresponding to the specified bucket that was
previously locked using the
lockBucket(int) method. |
protected void |
unlockSegment(int nSegment)
Unlock the specified segment previously locked using the
lockSegment(int, boolean) method. |
Collection |
values()
Returns a collection view of the values contained in this map.
|
azzert, azzert, azzert, azzertFailed, breakLines, breakLines, capitalize, checkNotEmpty, checkNotNull, checkRange, computeSafeWaitTime, decimalValue, dup, dup, ensureBigDecimal, ensureClassLoader, ensureRuntimeException, ensureRuntimeException, equals, equalsDeep, err, err, err, err, err, escape, formatDateTime, getCallerStackFrame, getCommonMonitor, getCommonMonitor, getCommonMonitor, getContextClassLoader, getContextClassLoader, getDeepMessage, getErr, getLastSafeTimeMillis, getLog, getMaxDecDigits, getMaxHexDigits, getOriginalException, getOut, getProcessRandom, getRandom, getRandomBinary, getRandomBinary, getRandomString, getSafeTimeMillis, getStackFrame, getStackFrames, getStackTrace, getStackTrace, getThreadFactory, getTimeZone, getUpTimeMillis, hashCode, hexValue, indentString, indentString, isDecimal, isHex, isLogEcho, isOctal, log, log, log, log, log, makeInteger, makeLong, makeThread, mod, mod, octalValue, out, out, out, out, out, pad, parseBandwidth, parseBandwidth, parseDelimitedString, parseHex, parseHex, parseMemorySize, parseMemorySize, parsePercentage, parseTime, parseTime, parseTimeNanos, parseTimeNanos, printStackTrace, randomize, randomize, randomize, randomize, read, read, read, read, read, read, read, replace, setErr, setLog, setLogEcho, setOut, sleep, toBandwidthString, toBandwidthString, toCharEscape, toCrc, toCrc, toCrc, toCrc, toCrc, toDecString, toDelimitedString, toDelimitedString, toDelimitedString, toDelimitedString, toHex, toHex, toHexDump, toHexEscape, toHexEscape, toHexEscape, toHexEscape, toHexString, toMemorySizeString, toMemorySizeString, toQuotedCharEscape, toQuotedStringEscape, toSqlString, toString, toString, toStringEscape, toUnicodeEscape, trace, trace, trace, trace, trace, trace, trace, trace, trace, truncateString, truncateString, wait
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
protected static final int[] PRIME_MODULO
public static final int DEFAULT_INITIALSIZE
protected static final int BIGGEST_MODULO
public static final float DEFAULT_LOADFACTOR
public static final float DEFAULT_GROWTHRATE
protected static final int MIN_SEGMENT_CAPACITY
protected static final int SEGMENT_COUNT
protected static final int LOCK_COUNT
protected static final long LOCKS_NONE
protected static final long LOCKS_ALL
protected static final int LOCK_ALL_PENDING_IDX
protected static final long LOCK_ALL_PENDING
protected static final int SEGMENT_LOCK_MAX_SPIN
protected static final int PUTALL_THRESHOLD
protected static final Object NO_VALUE
protected final Object RESIZING
protected final AtomicLong m_atomicLocks
protected final SegmentedHashMap.Segment[] m_aSegment
protected volatile SegmentedHashMap.Entry[] m_aeBucket
protected int m_cSegmentCapacity
protected final float m_flLoadFactor
protected final float m_flGrowthRate
protected SegmentedHashMap.EntrySet m_setEntries
protected SegmentedHashMap.KeySet m_setKeys
protected SegmentedHashMap.ValuesCollection m_colValues
protected Object m_oIterActive
protected SegmentedHashMap.GetEntryAction m_actionGetEntry
protected SegmentedHashMap.InsertAction m_actionInsert
protected SegmentedHashMap.RemoveAction m_actionRemove
protected SegmentedHashMap.ContainsValueAction m_actionContainsValue
public SegmentedHashMap()
public SegmentedHashMap(int cInitialBuckets, float flLoadFactor, float flGrowthRate)
cInitialBuckets
- the initial number of hash buckets, 0 < nflLoadFactor
- the acceptable load factor before resizing
occurs, 0 < n, such that a load factor of
1.0 causes resizing when the number of entries
exceeds the number of bucketsflGrowthRate
- the rate of bucket growth when a resize occurs,
0 < n, such that a growth rate of 1.0 will
double the number of buckets:
bucketcount = bucketcount * (1 + growthrate)protected SegmentedHashMap.InsertAction getInsertAction()
protected void setInsertAction(SegmentedHashMap.InsertAction action)
action
- the action for insertprotected SegmentedHashMap.GetEntryAction getGetEntryAction()
protected void setGetEntryAction(SegmentedHashMap.GetEntryAction action)
action
- the action for getEntryInternalprotected SegmentedHashMap.RemoveAction getRemoveAction()
protected void setRemoveAction(SegmentedHashMap.RemoveAction action)
action
- the action for remove()protected SegmentedHashMap.ContainsValueAction getContainsValueAction()
protected void setContainsValueAction(SegmentedHashMap.ContainsValueAction action)
action
- the action for containsValue()public boolean equals(Object oThat)
public int hashCode()
public String toString()
public int size()
Note: Unlike some Map implementations, the size() operation on this map may be relatively expensive.
public boolean isEmpty()
public boolean containsKey(Object oKey)
containsKey
in interface Map
oKey
- key whose presence in this map is to be testedpublic boolean containsValue(Object oValue)
containsValue
in interface Map
oValue
- value whose presence in this map is to be testedpublic Object get(Object oKey)
public Map.Entry getEntry(Object key)
key
- the key object to search forpublic Object put(Object oKey, Object oValue)
put
in interface Map
oKey
- key with which the specified value is to be associatedoValue
- value to be associated with the specified keypublic void putAll(Map mapOther)
for (Iterator iter = mapOther.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry) iter.next(); put(entry.getKey(), entry.getValue()); }
public Set entrySet()
public Set keySet()
public Collection values()
protected void initializeActions()
protected SegmentedHashMap.Entry getEntryInternal(Object oKey)
oKey
- the key object to search forprotected SegmentedHashMap.Entry getEntryInternal(Object oKey, boolean fSynthetic)
oKey
- the key object to search forfSynthetic
- include synthetic Entry objects representing keys
that are not contained in the mapprotected Object putInternal(Object oKey, Object oValue)
oKey
- key with which the specified value is to be associatedoValue
- value to be associated with the specified keyprotected Object putInternal(Object oKey, Object oValue, boolean fOnlyIfAbsent)
oKey
- key with which the specified value is to be associatedoValue
- value to be associated with the specified keyfOnlyIfAbsent
- if true, perform a logical insert only; no action
if the key already existsprotected Object removeInternal(Object oKey, SegmentedHashMap.EntryAction actionRemove, Object oContext)
oKey
- key whose mapping is to be removed from the mapactionRemove
- the EntryAction to applyoContext
- the context for the remove actionprotected Object[] toArrayInternal(SegmentedHashMap.IterableEntryAction action, Object[] a)
action
- the toArray() actiona
- the array into which the elements of the Collection
are to be stored, if it is big enough; otherwise, a
new array of the same runtime type is allocated for
this purposeArrayStoreException
- if the runtime type of the specified array
is not a supertype of the runtime type of the elements returned
by the specified actionprotected void ensureLoadFactor(SegmentedHashMap.Segment segment)
segment
- the segment to ensure the load-factor forprotected void grow()
Note: caller of this method is expected to hold locks on all segments of the map while making this call.
protected void grow(int cNew)
Note: caller of this method is expected to hold locks on all segments of the map while making this call.
cNew
- the minimum size to attempt to grow toprotected Object invokeOnAllKeys(Object oContext, boolean fLock, SegmentedHashMap.IterableEntryAction actionEntry)
The semantics of invokeOnAllKeys are equivalent to:
for (Iterator iter = entrySet().iterator(); iter.hasNext(); ) { Entry entry = (Entry) iter.next(); actionEntry.invokeFound(...); } return oContext;Except that if fLock is specified, it is performed atomically while holding all segment-locks.
oContext
- opaque context for the specified actionfLock
- true if all segment-locks should be
acquired before invoking the specified actionactionEntry
- the action to perform for each entryprotected Object invokeOnKey(Object oKey, Object oContext, boolean fLock, SegmentedHashMap.EntryAction action)
The semantics of invokeOnKey are equivalent to:
Object oResult; if (containsKey(oKey)) { oResult = action.invokeFound(...); } else { oResult = action.invokeNotFound(...); } return oResult;Except that if fLock is specified, it is performed atomically while holding the segment-lock.
oKey
- the key to act onoContext
- opaque context for the specified actionfLock
- true iff the segment should be locked before invoking
the specified actionaction
- the action to invokeprotected int getBucketIndex(int nHash, int cBuckets)
nHash
- the hash codecBuckets
- the number of bucketsprotected int getSegmentIndex(int nBucket)
nBucket
- the bucket numberprotected SegmentedHashMap.Segment getSegmentForKey(Object oKey)
oKey
- the keyprotected SegmentedHashMap.Entry[] getStableBucketArray()
protected void iteratorActivated(Iterator iter)
Note: The map will not grow while there are any active iterators.
iter
- the activated iteratorpublic void releaseIterator(Iterator iter)
Note: This method could be used to accelerate the destruction of unexhausted iterators.
iter
- the iterator to be releasedprotected boolean isActiveIterator()
protected boolean lockBucket(int nBucket)
nBucket
- the bucket indexprotected boolean lockSegment(int nSegment, boolean fBlock)
nSegment
- the segment to lockfBlock
- should we block on trying to lock the segmentprotected void unlockBucket(int nBucket)
lockBucket(int)
method.nBucket
- the bucket to unlockprotected void unlockSegment(int nSegment)
lockSegment(int, boolean)
method.nSegment
- the segment to unlockprotected void contendForSegment(int nSegment)
nSegment
- the segment-lock to be waited forprotected void lockAllBuckets()
protected boolean lockAllBuckets(int nBucketAlreadyLocked)
nBucketAlreadyLocked
- the bucket that was already locked.protected void unlockAllBuckets()
protected void unlockAllBuckets(int nBucketLeaveLocked)
nBucketLeaveLocked
- the bucket that was already lockedprotected boolean lockAllSegments(long lLocksHeld)
lLocksHeld
- the bit-mask representing all segment-locks that the
calling thread already holdsprotected void unlockAllSegments(long lLocksKeep)
lockAllSegments(long)
.lLocksKeep
- the segment-locks to keep lockedprotected SegmentedHashMap.GetEntryAction instantiateGetEntryAction()
protected SegmentedHashMap.InsertAction instantiateInsertAction()
protected SegmentedHashMap.RemoveAction instantiateRemoveAction()
protected SegmentedHashMap.ContainsValueAction instantiateContainsValueAction()
protected SegmentedHashMap.Entry instantiateEntry(Object oKey, Object oValue, int nHash)
oKey
- the keyoValue
- the valuenHash
- the hashCode value of the keyprotected static SegmentedHashMap.Entry entryFromBucket(SegmentedHashMap.Entry[] aeBucket, int nBucket)
aeBucket
- the array of hash bucketsnBucket
- the bucket indexprotected SegmentedHashMap.EntrySet instantiateEntrySet()
protected SegmentedHashMap.KeySet instantiateKeySet()
protected SegmentedHashMap.ValuesCollection instantiateValuesCollection()