Class LruBlockCache

  • All Implemented Interfaces:
    HeapSize, BlockCache

    public class LruBlockCache
    extends SynchronousLoadingBlockCache
    implements BlockCache, HeapSize
    A block cache implementation that is memory-aware using HeapSize, memory-bound using an LRU eviction algorithm, and concurrent: backed by a ConcurrentHashMap and with a non-blocking eviction thread giving constant-time cacheBlock(java.lang.String, byte[], boolean) and getBlock(java.lang.String) operations.

    Contains three levels of block priority to allow for scan-resistance and in-memory families. A block is added with an inMemory flag if necessary, otherwise a block becomes a single access priority. Once a blocked is accessed again, it changes to multiple access. This is used to prevent scans from thrashing the cache, adding a least-frequently-used element to the eviction algorithm.

    Each priority is given its own chunk of the total cache to ensure fairness during eviction. Each priority will retain close to its maximum size, however, if any priority is not using its entire chunk the others are able to grow beyond their chunk size.

    Instantiated at a minimum with the total size and average block size. All sizes are in bytes. The block size is not especially important as this cache is fully dynamic in its sizing of blocks. It is only used for pre-allocating data structures and in initial heap estimation of the map.

    The detailed constructor defines the sizes for the three priorities (they should total to the maximum size defined). It also sets the levels that trigger and control the eviction thread.

    The acceptable size is the cache size level which triggers the eviction process to start. It evicts enough blocks to get the size below the minimum size specified.

    Eviction happens in a separate thread and involves a single full-scan of the map. It determines how many bytes must be freed to reach the minimum size, and then while scanning determines the fewest least-recently-used blocks necessary from each of the three priorities (would be 3 times bytes to free). It then uses the priority chunk sizes to evict fairly according to the relative sizes and usage.

    • Field Detail

      • CACHE_FIXED_OVERHEAD

        public static final long CACHE_FIXED_OVERHEAD
    • Constructor Detail

      • LruBlockCache

        public LruBlockCache​(LruBlockCacheConfiguration conf)
        Default constructor. Specify maximum size and expected average block size (approximation is fine).

        All other factors will be calculated based on defaults specified in this class.

        Parameters:
        conf - block cache configuration
    • Method Detail

      • getOverhead

        public long getOverhead()
      • cacheBlock

        public CacheEntry cacheBlock​(String blockName,
                                     byte[] buf,
                                     boolean inMemory)
        Cache the block with the specified name and buffer.

        It is assumed this will NEVER be called on an already cached block. If that is done, it is assumed that you are reinserting the same exact block due to a race condition and will update the buffer but not modify the size of the cache.

        Parameters:
        blockName - block name
        buf - block buffer
        inMemory - if block is in-memory
      • cacheBlock

        public CacheEntry cacheBlock​(String blockName,
                                     byte[] buf)
        Cache the block with the specified name and buffer.

        It is assumed this will NEVER be called on an already cached block. If that is done, it is assumed that you are reinserting the same exact block due to a race condition and will update the buffer but not modify the size of the cache.

        Specified by:
        cacheBlock in interface BlockCache
        Parameters:
        blockName - block name
        buf - block buffer
      • getBlock

        public CacheEntry getBlock​(String blockName)
        Get the buffer of the block with the specified name.
        Specified by:
        getBlock in interface BlockCache
        Parameters:
        blockName - block name
        Returns:
        buffer of specified block name, or null if not in cache
      • evictBlock

        protected long evictBlock​(CachedBlock block)
      • getMaxHeapSize

        public long getMaxHeapSize()
        Description copied from interface: BlockCache
        Get the maximum amount of on heap memory this cache will use.
        Specified by:
        getMaxHeapSize in interface BlockCache
      • getMaxSize

        public long getMaxSize()
        Description copied from interface: BlockCache
        Get the maximum size of this cache.
        Specified by:
        getMaxSize in interface BlockCache
        Returns:
        max size in bytes
      • getCurrentSize

        public long getCurrentSize()
        Get the current size of this cache.
        Returns:
        current size in bytes
      • getFreeSize

        public long getFreeSize()
        Get the current size of this cache.
        Returns:
        current size in bytes
      • size

        public long size()
        Get the size of this cache (number of cached blocks)
        Returns:
        number of cached blocks
      • getEvictionCount

        public long getEvictionCount()
        Get the number of eviction runs that have occurred
      • getEvictedCount

        public long getEvictedCount()
        Get the number of blocks that have been evicted during the lifetime of this cache.
      • logStats

        public void logStats()
      • getStats

        public LruBlockCache.CacheStats getStats()
        Get counter statistics for this cache.

        Includes: total accesses, hits, misses, evicted blocks, and runs of the eviction processes.

        Specified by:
        getStats in interface BlockCache
        Returns:
        statistics
      • heapSize

        public long heapSize()
        Specified by:
        heapSize in interface HeapSize
        Returns:
        Approximate 'exclusive deep size' of implementing object. Includes count of payload and hosting object sizings.
      • calculateOverhead

        public static long calculateOverhead​(long maxSize,
                                             long blockSize,
                                             int concurrency)
      • shutdown

        public void shutdown()