@Override
  public String toString() {
    return MoreObjects.toStringHelper(this).add("blockCount", getBlockCount())
      .add("currentSize", getCurrentSize()).add("freeSize", getFreeSize()).add("maxSize", size())
      .add("heapSize", heapSize()).add("victimCache", (victimCache != null)).toString();
  }
The block cached in TinyLfuBlockCache will always be an heap block: on the one side, the heap
access will be more faster then off-heap, the small index block or meta block cached in
CombinedBlockCache will benefit a lot. on other side, the TinyLfuBlockCache size is always
calculated based on the total heap size, if caching an off-heap block in TinyLfuBlockCache, the
heap size will be messed up. Here we will clone the block into an heap block if it's an
off-heap block, otherwise just use the original block. The key point is maintain the refCnt of
the block (HBASE-22127): <br>
1. if cache the cloned heap block, its refCnt is an totally new one, it's easy to handle; <br>
2. if cache the original heap block, we're sure that it won't be tracked in ByteBuffAllocator's
reservoir, if both RPC and TinyLfuBlockCache release the block, then it can be garbage
collected by JVM, so need a retain here.
@param buf the original block
@return an block with an heap memory backend.
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/TinyLfuBlockCache.java