Base class for write-back caches which asynchronously evict entries to backing stores.
The cache uses water mark based eviction. A dedicated thread waits for the cache to reach its
high water mark, then evicts entries until the cache size reaches the low water mark. All backing
store write operations are performed asynchronously in the eviction thread, unless the cache hits
maximum capacity. At maximum capacity, methods interact synchronously with the backing store. For
best performance, maximum capacity should never be reached. This requires that the eviction
thread can keep up cache writes.
Cache hit reads are served without any locking. Writes and cache miss reads take locks on their
This class leverages the entry-level locks of ConcurrentHashMap to synchronize operations on the
Retrieves a value from the cache, loading it from the backing store if necessary.
If the value needs to be loaded, concurrent calls to get(key) will block while waiting for the
first call to finish loading the value.
If option.shouldSkipCache() is true, then the value loaded from the backing store will not be
cached and the eviction thread will not be woken up.
key - the key to get the value for
option - the read options
the value, or empty if the key doesn't exist in the cache or in the backing store
Removes a key from the cache.
The key is not immediately removed from the backing store. Instead, we set the entry's value to
null to indicate to the eviction thread that to evict the entry, it must first remove the key
from the backing store. However, if the cache is full we must synchronously write to the
backing store instead.