public BucketEntry writeToCache(final IOEngine ioEngine, final BucketAllocator alloc,
      final LongAdder realCacheSize, Function<BucketEntry, Recycler> createRecycler,
      ByteBuffer metaBuff, final Long acceptableSize) throws IOException {
      int len = data.getSerializedLength();
      // This cacheable thing can't be serialized
      if (len == 0) {
        return null;
      }
      if (isCachePersistent && data instanceof HFileBlock) {
        len += Long.BYTES; // we need to record the cache time for consistency check in case of
                           // recovery
      }
      long offset = alloc.allocateBlock(len);
      // In the case of prefetch, we want to avoid freeSpace runs when the cache is full.
      // this makes the cache allocation more predictable, and is particularly important
      // when persistent cache is enabled, as it won't trigger evictions of the recovered blocks,
      // which are likely the most accessed and relevant blocks in the cache.
      if (isPrefetch() && alloc.getUsedSize() > acceptableSize) {
        alloc.freeBlock(offset, len);
        return null;
      }
      boolean succ = false;
      BucketEntry bucketEntry = null;
      try {
        int diskSizeWithHeader = (data instanceof HFileBlock)
          ? ((HFileBlock) data).getOnDiskSizeWithHeader()
          : data.getSerializedLength();
        bucketEntry = new BucketEntry(offset, len, diskSizeWithHeader, accessCounter, inMemory,
          createRecycler, getByteBuffAllocator());
        bucketEntry.setDeserializerReference(data.getDeserializer());
        if (data instanceof HFileBlock) {
          // If an instance of HFileBlock, save on some allocations.
          HFileBlock block = (HFileBlock) data;
          ByteBuff sliceBuf = block.getBufferReadOnly();
          block.getMetaData(metaBuff);
          // adds the cache time prior to the block and metadata part
          if (isCachePersistent) {
            ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
            buffer.putLong(bucketEntry.getCachedTime());
            buffer.rewind();
            ioEngine.write(buffer, offset);
            ioEngine.write(sliceBuf, (offset + Long.BYTES));
          } else {
            ioEngine.write(sliceBuf, offset);
          }
          ioEngine.write(metaBuff, offset + len - metaBuff.limit());
        } else {
          // Only used for testing.
          ByteBuffer bb = ByteBuffer.allocate(len);
          data.serialize(bb, true);
          ioEngine.write(bb, offset);
        }
        succ = true;
      } finally {
        if (!succ) {
          alloc.freeBlock(offset, len);
        }
      }
      realCacheSize.add(len);
      return bucketEntry;
    }
Block Entry stored in the memory with key,data and so on
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java