protected void putIntoBackingMap(BlockCacheKey key, BucketEntry bucketEntry) {
    BucketEntry previousEntry = backingMap.put(key, bucketEntry);
    blocksByHFile.add(key);
    updateRegionCachedSize(key.getFilePath(), bucketEntry.getLength());
    if (previousEntry != null && previousEntry != bucketEntry) {
      previousEntry.withWriteLock(offsetLock, () -> {
        blockEvicted(key, previousEntry, false, false);
        return null;
      });
    }
  }
Put the new bucket entry into backingMap. Notice that we are allowed to replace the existing
cache with a new block for the same cache key. there's a corner case: one thread cache a block
in ramCache, copy to io-engine and add a bucket entry to backingMap. Caching another new block
with the same cache key do the same thing for the same cache key, so if not evict the previous
bucket entry, then memory leak happen because the previous bucketEntry is gone but the
bucketAllocator do not free its memory.
@see BlockCacheUtil#shouldReplaceExistingCacheBlock(BlockCache blockCache,BlockCacheKey
     cacheKey, Cacheable newBlock)
@param key         Block cache key
@param bucketEntry Bucket entry to put into backingMap.
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java