Class HeapCache<K,V>
- java.lang.Object
-
- org.cache2k.core.BaseCache<K,V>
-
- org.cache2k.core.HeapCache<K,V>
-
- All Implemented Interfaces:
AutoCloseable,org.cache2k.Cache<K,V>,InternalCache<K,V>,InternalCacheCloseContext,HeapCacheForEviction<K,V>,TimerEventListener<K,V>,org.cache2k.DataAware<K,V>,org.cache2k.KeyValueSource<K,V>
- Direct Known Subclasses:
IntHeapCache
public class HeapCache<K,V> extends BaseCache<K,V> implements HeapCacheForEviction<K,V>
Foundation for all cache variants. All common functionality is in here. For a (in-memory) cache we need three things: a fast hash table implementation, an LRU list (a simple double linked list), and a fast timer. The variants implement different eviction strategies.Locking: The cache has a single structure lock obtained via
lockand also locks on each entry for operations on it. Though, mutation operations that happen on a single entry get serialized.- Author:
- Jens Wilke
-
-
Field Summary
Fields Modifier and Type Field Description protected longclearCntNumber of clear operations.protected longclearedTimeprotected longclearRemovedCntNumber of entries removed by clear.protected org.cache2k.operation.TimeReferenceclockprotected org.cache2k.io.ExceptionPropagator<? super K,? super V>exceptionPropagatorprotected StampedHash<K,V>hashprotected longinternalExceptionCntNumber of internal exceptions.protected longkeyMutationCntCounts the number of key mutations.protected org.cache2k.config.CacheTypekeyTypeprotected org.cache2k.io.AdvancedCacheLoader<K,V>loaderObjectlockStructure lock of the cache.CacheManagerImplmanagerprotected Stringnameprotected longstartedTimeprotected Timing<K,V>timingprotected org.cache2k.config.CacheTypevalueType
-
Constructor Summary
Constructors Constructor Description HeapCache(InternalCacheBuildContext<K,V> ctx)called from CacheBuilder
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidcancelTimerJobs()Preparation for shutdown.Set<K>checkAllPresent(Iterable<? extends K> keys)Checks for entries being present and fresh.voidcheckClosed()voidcheckIntegrity()Cache checks its internal integrity.voidclear()voidclearLocalCache()voidclose()voidclosePart1()voidclosePart2(InternalCache userCache)VcomputeIfAbsent(K key, Function<? super K,? extends V> function)Code duplicates withCache.get(Object)booleancontainsAndRemove(K key)booleancontainsKey(K key)Map<K,V>convertCacheEntry2ValueMap(Map<K,org.cache2k.CacheEntry<K,V>> map)Map<K,V>convertValueMap(Map<K,Object> map)protected <R> EntryAction<K,V,R>createEntryAction(K key, Entry<K,V> e, Semantic<K,V,R> op)protected <R> org.cache2k.core.HeapCache.MyEntryAction<R>createFireAndForgetAction(Entry<K,V> e, Semantic<K,V,R> op)StampedHash<K,V>createHashTable()voidexecuteLoader(Runnable r)Execute with loader executor and back pressure.<T> TexecuteWithGlobalLock(Supplier<T> job)Execute job while making sure that no other operations are going on.protected voidexpireEntry(Entry<K,V> e)protected voidfinishLoadOrEviction(Entry<K,V> e, long nextRefreshTime)static <K> Set<K>generateKeySet(Iterable<? extends K> keys)Generate a set of unique keys from the iterable.Vget(K key)Map<K,V>getAll(Iterable<? extends K> inputKeys)JSR107 bulk interface.org.cache2k.CacheManagergetCacheManager()The cache managerorg.cache2k.operation.TimeReferencegetClock()Time reference for the cache.CommonMetricsgetCommonMetrics()InternalCacheInfogetConsistentInfo()Generate fresh statistics within a global cache lock.InternalCacheInfogetConsistentInfo(InternalCache userCache)org.cache2k.CacheEntry<K,V>getEntry(K key)protected Entry<K,V>getEntryInternal(K key)protected Entry<K,V>getEntryInternal(K key, int hc, int val)StringgetEntryState(K key)EvictiongetEviction()ExecutorgetExecutor()Entry<K,V>[]getHashEntries()Hash table entry array, used only by random eviction.InternalCacheInfogetInfo()Return cache statistic counters.InternalCacheInfogetInfo(InternalCache userCache)protected IntegrityStategetIntegrityState()org.cache2k.config.CacheTypegetKeyType()ExecutorgetLoaderExecutor()LoggetLog()Normally a cache itself logs nothing, so just construct when needed.StringgetName()Designation of target for logging and exceptions.ExecutorgetRefreshExecutor()org.cache2k.operation.TimeReferencegetTimeReference()Timing<K,V>getTiming()Used for testslonggetTotalEntryCount()This method is used forConcurrentMapWrapper.size()org.cache2k.config.CacheTypegetValueType()voidinit()voidinitWithoutTimerHandler()protected voidinsert(Entry<K,V> e, V value, long t0, long t, long refreshTime, byte updateStatistics, long nextRefreshTime)protected Entry<K,V>insertNewEntry(K key, int hc, int val)Insert new entry in all structures (hash and eviction).protected voidinsertOrUpdateAndCalculateExpiry(Entry<K,V> e, V v, long t0, long t, long refreshTime, byte updateStatistics)Calculate the next refresh time if a timer / expiry is needed and call insert.booleanisClosed()booleanisDisabled()protected booleanisKeepAfterExpired()booleanisLoaderPresent()booleanisNullValuePermitted()protected booleanisRecordRefreshTime()booleanisRefreshAhead()protected booleanisRejectNullValues()protected booleanisUpdateTimeNeeded()No need to update the entry last modification time.booleanisWeigherPresent()ConcurrentEntryIterator<K,V>iterateAllHeapEntries()Returns all cache entries within the heap cache.Iterator<org.cache2k.CacheEntry<K,V>>iterator()KkeyObjFromEntry(Entry<K,V> e)Either returns the stored key object or the integer object created from the hashCode field.protected voidload(Entry<K,V> e)CompletableFuture<Void>loadAll(Iterable<? extends K> keys)protected Entry<K,V>loadAndReplace(K key)Always fetch the value from the source.voidlogAndCountInternalException(String text, Throwable exception)protected Entry<K,V>lookupEntry(K key)protected Entry<K,V>lookupEntry(K key, int hc, int val)protected Entry<K,V>lookupEntryNoHitRecord(K key)protected Entry<K,V>lookupEntryNoHitRecord(K key, int hc, int val)protected Entry<K,V>lookupOrNewEntry(K key)Lookup or create a new entry.protected Entry<K,V>lookupOrNewEntry(K key, int hc, int val)protected Entry<K,V>lookupOrNewEntryNoHitRecord(K key)Vpeek(K key)Map<K,V>peekAll(Iterable<? extends K> inputKeys)VpeekAndPut(K key, V value)VpeekAndRemove(K key)VpeekAndReplace(K key, V value)org.cache2k.CacheEntry<K,V>peekEntry(K key)protected Entry<K,V>peekEntryInternal(K key)Return the entry, if it is in the cache, without invoking the cache source.protected Entry<K,V>peekEntryInternal(K key, int hc, int val)voidput(K key, V value)voidputAll(Map<? extends K,? extends V> valueMap)booleanputIfAbsent(K key, V value)protected voidputValue(Entry<K,V> e, V value)Update the value directly within entry lock.protected voidrecordHit(Entry e)Increment the hit counter, because entry was accessed.CompletableFuture<Void>reloadAll(Iterable<? extends K> keys)voidremove(K key)protected booleanremoveEntry(Entry<K,V> e)Remove the entry from the hash and the replacement list.voidremoveEntryForEviction(Entry<K,V> e)Remove the entry from the hash table.booleanremoveIfEquals(K key, V value)Remove the object from the cache.protected booleanreplace(K key, boolean compare, V oldValue, V newValue)replace if value matches.booleanreplace(K key, V newValue)booleanreplaceIfEquals(K key, V oldValue, V newValue)org.cache2k.CacheEntry<K,V>returnCacheEntry(K key, Object valueOrException)In case of an exception we can return the wrapper directly since it implements the CacheEntry interface and is immutable.org.cache2k.CacheEntry<K,V>returnCacheEntry(ExaminationEntry<K,V> entry)Construct a new CacheEntry for the cache client.protected org.cache2k.CacheEntry<K,V>returnEntry(ExaminationEntry<K,V> e)Wrap entry in a separate object instance.RuntimeExceptionreturnNullValueDetectedException()static <V> VreturnValue(Object v)protected VreturnValue(Entry<K,V> e)voidsetDisabled(boolean disabled)voidsetTiming(Timing<K,V> rh)static intspreadHash(int h)This function calculates a modified hash code.intspreadHashFromEntry(Entry e)voidstartRefreshProbationTimer(Entry<K,V> e, long nextRefreshTime)voidtimerEventExpireEntry(Entry<K,V> e, Object task)Called by the timer when an entry is expired or before actual expiry when the entry needs to switch into sharp expiry mode.voidtimerEventProbationTerminated(Entry<K,V> e, Object task)voidtimerEventRefresh(Entry<K,V> e, Object task)The entry should be refreshed.KtoEntryKey(K key)The key object or null, for integer keyed cachesinttoStoredHashCodeOrKey(K key, int hc)We store either the spread hash code or the raw integer key in the hash table-
Methods inherited from class org.cache2k.core.BaseCache
asMap, closeCustomization, entries, execute, execute, expireAt, getQualifiedName, invoke, invokeAll, keys, removeAll, removeAll, requestInterface, toString
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.cache2k.core.api.InternalCache
getUserCache
-
-
-
-
Field Detail
-
name
protected final String name
-
manager
public final CacheManagerImpl manager
-
clock
protected org.cache2k.operation.TimeReference clock
-
lock
public final Object lock
Structure lock of the cache. Every operation that needs a consistent structure of the cache or modifies it needs to synchronize on this. Since this is a global lock, locking on it should be avoided and any operation under the lock should be quick.
-
keyMutationCnt
protected volatile long keyMutationCnt
Counts the number of key mutations. The count is not guarded and racy, but does not need to be exact. We don't put it to the metrics, because we do not want to have this disabled.
-
clearedTime
protected long clearedTime
-
startedTime
protected long startedTime
-
clearRemovedCnt
protected long clearRemovedCnt
Number of entries removed by clear. Guarded by: lock
-
clearCnt
protected long clearCnt
Number of clear operations. Guarded by: lock
-
internalExceptionCnt
protected long internalExceptionCnt
Number of internal exceptions. Guarded by: lock.
-
hash
protected final StampedHash<K,V> hash
-
keyType
protected org.cache2k.config.CacheType keyType
-
valueType
protected org.cache2k.config.CacheType valueType
-
-
Constructor Detail
-
HeapCache
public HeapCache(InternalCacheBuildContext<K,V> ctx)
called from CacheBuilder
-
-
Method Detail
-
getTiming
public Timing<K,V> getTiming()
Used for tests- Specified by:
getTimingin interfaceInternalCache<K,V>
-
getTimeReference
public org.cache2k.operation.TimeReference getTimeReference()
- Specified by:
getTimeReferencein interfaceInternalCache<K,V>
-
getLoaderExecutor
public Executor getLoaderExecutor()
-
isKeepAfterExpired
protected final boolean isKeepAfterExpired()
-
isRejectNullValues
protected final boolean isRejectNullValues()
-
isNullValuePermitted
public final boolean isNullValuePermitted()
- Specified by:
isNullValuePermittedin interfaceInternalCache<K,V>
-
isRefreshAhead
public final boolean isRefreshAhead()
-
isUpdateTimeNeeded
protected final boolean isUpdateTimeNeeded()
No need to update the entry last modification time. False, if no time dependent expiry calculations are done.
-
isRecordRefreshTime
protected final boolean isRecordRefreshTime()
-
getLog
public Log getLog()
Normally a cache itself logs nothing, so just construct when needed. Not requesting the log at startup means that the potential log target is not showing up in some management interfaces. This is intentional, since if caches are created and closed dynamically, we would have a memory leak, since logs can not be closed.- Specified by:
getLogin interfaceInternalCache<K,V>
-
getName
public String getName()
Description copied from interface:TimerEventListenerDesignation of target for logging and exceptions.- Specified by:
getNamein interfaceorg.cache2k.Cache<K,V>- Specified by:
getNamein interfaceInternalCacheCloseContext- Specified by:
getNamein interfaceTimerEventListener<K,V>
-
getKeyType
public org.cache2k.config.CacheType getKeyType()
- Specified by:
getKeyTypein interfaceInternalCache<K,V>
-
getValueType
public org.cache2k.config.CacheType getValueType()
- Specified by:
getValueTypein interfaceInternalCache<K,V>
-
init
public void init()
-
initWithoutTimerHandler
public void initWithoutTimerHandler()
-
checkClosed
public void checkClosed()
-
clearLocalCache
public final void clearLocalCache()
-
cancelTimerJobs
public void cancelTimerJobs()
Preparation for shutdown. Cancel all pending timer jobs e.g. for expiry/refresh or flushing the storage.- Specified by:
cancelTimerJobsin interfaceInternalCache<K,V>
-
closePart1
public void closePart1() throws org.cache2k.CacheClosedException- Throws:
org.cache2k.CacheClosedException- if cache is closed or closing is initiated by another thread.
-
close
public void close()
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceorg.cache2k.Cache<K,V>
-
closePart2
public void closePart2(InternalCache userCache)
-
recordHit
protected void recordHit(Entry e)
Increment the hit counter, because entry was accessed.The hit counter is a dirty counter. In case of multiple CPU cores incrementing the same entry counter, increments will be lost. For the functionality of the eviction algorithm this is not a real loss, since still the most accessed entries will have more counts then the others. On 32 bit systems word tearing may occur. This will also have no real observable negative impact on the eviction, so we do not compensate for it.
The hit count is also used for access statistics. The dirty counting will effect the exact correctness of the access statistics.
Using a 64 bit counter per entry is basically a big waste of memory. When reducing to a 32 bit value is has approximately a negative performance impact of 30%.
-
returnEntry
protected org.cache2k.CacheEntry<K,V> returnEntry(ExaminationEntry<K,V> e)
Wrap entry in a separate object instance. We can return the entry directly, however we lock on the entry object.
-
getEntryState
public String getEntryState(K key)
- Specified by:
getEntryStatein interfaceInternalCache<K,V>
-
returnCacheEntry
public org.cache2k.CacheEntry<K,V> returnCacheEntry(ExaminationEntry<K,V> entry)
Construct a new CacheEntry for the cache client. We cannot return an internal cache entry object since this it is mutable.- Specified by:
returnCacheEntryin interfaceInternalCache<K,V>
-
returnCacheEntry
public org.cache2k.CacheEntry<K,V> returnCacheEntry(K key, Object valueOrException)
In case of an exception we can return the wrapper directly since it implements the CacheEntry interface and is immutable. If it is not a wrapper we construct a CacheEntry object.
-
removeEntry
protected boolean removeEntry(Entry<K,V> e)
Remove the entry from the hash and the replacement list. There is a race condition to catch: The eviction may run in a parallel thread and may have already selected this entry.
-
putValue
protected final void putValue(Entry<K,V> e, V value)
Update the value directly within entry lock. Since we did not start entry processing we do not need to notify any waiting threads.
-
replace
protected boolean replace(K key, boolean compare, V oldValue, V newValue)
replace if value matches. if value not matches, return the existing entry or the dummy entry.
-
peekEntryInternal
protected final Entry<K,V> peekEntryInternal(K key)
Return the entry, if it is in the cache, without invoking the cache source.The cache storage is asked whether the entry is present. If the entry is not present, this result is cached in the local cache.
-
containsKey
public boolean containsKey(K key)
-
computeIfAbsent
public V computeIfAbsent(K key, Function<? super K,? extends V> function)
Code duplicates withCache.get(Object)
-
containsAndRemove
public boolean containsAndRemove(K key)
-
getRefreshExecutor
public Executor getRefreshExecutor()
-
loadAll
public CompletableFuture<Void> loadAll(Iterable<? extends K> keys)
-
reloadAll
public CompletableFuture<Void> reloadAll(Iterable<? extends K> keys)
-
executeLoader
public void executeLoader(Runnable r)
Execute with loader executor and back pressure. In case the execution is rejected because there are not enough threads available, the task is executed in the calling thread to produce back pressure. If callers should never block upon aloadAllthe executor must have a unbound queue.
-
generateKeySet
public static <K> Set<K> generateKeySet(Iterable<? extends K> keys)
Generate a set of unique keys from the iterable. Optimize if its already a set or an collection.
-
checkAllPresent
public Set<K> checkAllPresent(Iterable<? extends K> keys)
Checks for entries being present and fresh. Used byloadAllandprefetchAll- Parameters:
keys- keys to check for- Returns:
- keys not present in the cache
-
loadAndReplace
protected Entry<K,V> loadAndReplace(K key)
Always fetch the value from the source. That is a copy of getEntryInternal without freshness checks.
-
lookupOrNewEntry
protected Entry<K,V> lookupOrNewEntry(K key)
Lookup or create a new entry. The new entry is created, because we need it for locking within the data fetch.
-
returnValue
public static <V> V returnValue(Object v)
-
insertNewEntry
protected Entry<K,V> insertNewEntry(K key, int hc, int val)
Insert new entry in all structures (hash and eviction). The insert at the eviction needs to be done under the same lock, to allow a check of the consistency.
-
getHashEntries
public Entry<K,V>[] getHashEntries()
Description copied from interface:HeapCacheForEvictionHash table entry array, used only by random eviction.- Specified by:
getHashEntriesin interfaceHeapCacheForEviction<K,V>
-
removeEntryForEviction
public void removeEntryForEviction(Entry<K,V> e)
Remove the entry from the hash table. The entry is already removed from the replacement list. Stop the timer, if needed. The remove races with a clear. The clear is not updating each entry state to e.isGone() but just drops the whole hash table instead.With completion of the method the entry content is no more visible. "Nulling" out the key or value of the entry is incorrect, since there can be another thread which is just about to return the entry contents.
- Specified by:
removeEntryForEvictionin interfaceHeapCacheForEviction<K,V>
-
isLoaderPresent
public boolean isLoaderPresent()
- Specified by:
isLoaderPresentin interfaceInternalCache<K,V>
-
isWeigherPresent
public boolean isWeigherPresent()
- Specified by:
isWeigherPresentin interfaceInternalCache<K,V>
-
insertOrUpdateAndCalculateExpiry
protected final void insertOrUpdateAndCalculateExpiry(Entry<K,V> e, V v, long t0, long t, long refreshTime, byte updateStatistics)
Calculate the next refresh time if a timer / expiry is needed and call insert.
-
returnNullValueDetectedException
public RuntimeException returnNullValueDetectedException()
-
insert
protected final void insert(Entry<K,V> e, V value, long t0, long t, long refreshTime, byte updateStatistics, long nextRefreshTime)
-
timerEventRefresh
public void timerEventRefresh(Entry<K,V> e, Object task)
Description copied from interface:TimerEventListenerThe entry should be refreshed.- Specified by:
timerEventRefreshin interfaceTimerEventListener<K,V>- Parameters:
e- seeTimerEventListener.timerEventExpireEntry(Entry, Object)task- seeTimerEventListener.timerEventExpireEntry(Entry, Object)
-
startRefreshProbationTimer
public void startRefreshProbationTimer(Entry<K,V> e, long nextRefreshTime)
-
timerEventProbationTerminated
public void timerEventProbationTerminated(Entry<K,V> e, Object task)
- Specified by:
timerEventProbationTerminatedin interfaceTimerEventListener<K,V>- Parameters:
e- seeTimerEventListener.timerEventExpireEntry(Entry, Object)task- seeTimerEventListener.timerEventExpireEntry(Entry, Object)
-
logAndCountInternalException
public void logAndCountInternalException(String text, Throwable exception)
- Specified by:
logAndCountInternalExceptionin interfaceInternalCache<K,V>
-
timerEventExpireEntry
public void timerEventExpireEntry(Entry<K,V> e, Object task)
Description copied from interface:TimerEventListenerCalled by the timer when an entry is expired or before actual expiry when the entry needs to switch into sharp expiry mode. The actual action to be performed is detected by checking theEntry.getNextRefreshTime()- Specified by:
timerEventExpireEntryin interfaceTimerEventListener<K,V>task- timer task as returned byEntry.getTask()to check whether the timer task is still valid after we obtained the entry lock
-
iterateAllHeapEntries
public final ConcurrentEntryIterator<K,V> iterateAllHeapEntries()
Returns all cache entries within the heap cache. Entries that are expired or contain no valid data are not filtered out.
-
getAll
public Map<K,V> getAll(Iterable<? extends K> inputKeys)
JSR107 bulk interface. The behaviour is compatible to the JSR107 TCK. We also need to be compatible to the exception handling policy, which says that the exception is to be thrown when most specific. So exceptions are only thrown, when the value which has produced an exception is requested from the map.
-
convertCacheEntry2ValueMap
public Map<K,V> convertCacheEntry2ValueMap(Map<K,org.cache2k.CacheEntry<K,V>> map)
-
createEntryAction
protected <R> EntryAction<K,V,R> createEntryAction(K key, Entry<K,V> e, Semantic<K,V,R> op)
- Specified by:
createEntryActionin classBaseCache<K,V>
-
createFireAndForgetAction
protected <R> org.cache2k.core.HeapCache.MyEntryAction<R> createFireAndForgetAction(Entry<K,V> e, Semantic<K,V,R> op)
- Specified by:
createFireAndForgetActionin classBaseCache<K,V>
-
getExecutor
public Executor getExecutor()
- Specified by:
getExecutorin classBaseCache<K,V>
-
getTotalEntryCount
public final long getTotalEntryCount()
Description copied from interface:InternalCacheThis method is used forConcurrentMapWrapper.size()- Specified by:
getTotalEntryCountin interfaceInternalCache<K,V>
-
getIntegrityState
protected IntegrityState getIntegrityState()
-
checkIntegrity
public final void checkIntegrity()
Description copied from interface:InternalCacheCache checks its internal integrity. This is a expansive operation because it may traverse all cache entries. Used for testing.- Specified by:
checkIntegrityin interfaceInternalCache<K,V>
-
getInfo
public final InternalCacheInfo getInfo()
Description copied from interface:InternalCacheReturn cache statistic counters. This method is intended for regular statistics polling. No extensive locking is performed to extract a consistent set of counters.- Specified by:
getInfoin interfaceInternalCache<K,V>
-
getConsistentInfo
public final InternalCacheInfo getConsistentInfo()
Description copied from interface:InternalCacheGenerate fresh statistics within a global cache lock. This version is used by internal consistency tests. This method is not intended to be called at high frequencies or for attaching monitoring or logging. Use theInternalCache.getInfo()method for requesting information for monitoring.- Specified by:
getConsistentInfoin interfaceInternalCache<K,V>
-
getInfo
public final InternalCacheInfo getInfo(InternalCache userCache)
-
getConsistentInfo
public final InternalCacheInfo getConsistentInfo(InternalCache userCache)
-
getCommonMetrics
public CommonMetrics getCommonMetrics()
- Specified by:
getCommonMetricsin interfaceInternalCache<K,V>
-
executeWithGlobalLock
public <T> T executeWithGlobalLock(Supplier<T> job)
Execute job while making sure that no other operations are going on. In case the eviction is connected via a queue we need to stop the queue processing. On the other hand we needs to make sure that the queue is drained because this method is used to access the recent statistics or check integrity. Draining the queue is a two phase job: The draining may not do eviction since we hold the locks, after lifting the lock with do eviction and lock again. This ensures that all queued entries are processed up to the point when the method was called.
-
getClock
public final org.cache2k.operation.TimeReference getClock()
Description copied from interface:InternalCacheTime reference for the cache.- Specified by:
getClockin interfaceInternalCache<K,V>
-
getEviction
public final Eviction getEviction()
- Specified by:
getEvictionin interfaceInternalCache<K,V>
-
isDisabled
public boolean isDisabled()
- Specified by:
isDisabledin interfaceInternalCache<K,V>
-
setDisabled
public void setDisabled(boolean disabled)
- Specified by:
setDisabledin interfaceInternalCache<K,V>
-
getCacheManager
public org.cache2k.CacheManager getCacheManager()
Description copied from interface:InternalCacheCloseContextThe cache manager- Specified by:
getCacheManagerin interfaceorg.cache2k.Cache<K,V>- Specified by:
getCacheManagerin interfaceInternalCacheCloseContext
-
spreadHash
public static int spreadHash(int h)
This function calculates a modified hash code. The intention is to "rehash" the incoming integer hash codes to overcome weak hash code implementations. Identical to latest Java VMs.The mapping needs to be unique, so we can skip equals() check for integer key optimizations.
-
toStoredHashCodeOrKey
public int toStoredHashCodeOrKey(K key, int hc)
We store either the spread hash code or the raw integer key in the hash table
-
spreadHashFromEntry
public int spreadHashFromEntry(Entry e)
-
keyObjFromEntry
public K keyObjFromEntry(Entry<K,V> e)
Either returns the stored key object or the integer object created from the hashCode field.
-
createHashTable
public StampedHash<K,V> createHashTable()
-
-