private void finishBlock() throws IOException {
      if (blockType == BlockType.DATA) {
        this.dataBlockEncoder.endBlockEncoding(dataBlockEncodingCtx, userDataStream,
          baosInMemory.getBuffer(), blockType);
        blockType = dataBlockEncodingCtx.getBlockType();
      }
      userDataStream.flush();
      prevOffset = prevOffsetByType[blockType.getId()];

      // We need to cache the unencoded/uncompressed size before changing the block state
      int rawBlockSize = 0;
      if (this.getEncodingState() != null) {
        rawBlockSize = encodedBlockSizeWritten();
      }
      // We need to set state before we can package the block up for cache-on-write. In a way, the
      // block is ready, but not yet encoded or compressed.
      state = State.BLOCK_READY;
      Bytes compressAndEncryptDat;
      if (blockType == BlockType.DATA || blockType == BlockType.ENCODED_DATA) {
        compressAndEncryptDat =
          dataBlockEncodingCtx.compressAndEncrypt(baosInMemory.getBuffer(), 0, baosInMemory.size());
      } else {
        compressAndEncryptDat = defaultBlockEncodingCtx.compressAndEncrypt(baosInMemory.getBuffer(),
          0, baosInMemory.size());
      }
      if (compressAndEncryptDat == null) {
        compressAndEncryptDat = new Bytes(baosInMemory.getBuffer(), 0, baosInMemory.size());
      }
      if (onDiskBlockBytesWithHeader == null) {
        onDiskBlockBytesWithHeader = new ByteArrayOutputStream(compressAndEncryptDat.getLength());
      }
      onDiskBlockBytesWithHeader.reset();
      onDiskBlockBytesWithHeader.write(compressAndEncryptDat.get(),
        compressAndEncryptDat.getOffset(), compressAndEncryptDat.getLength());
      // Update raw and compressed sizes in the predicate
      compressedSizePredicator.updateLatestBlockSizes(fileContext, rawBlockSize,
        onDiskBlockBytesWithHeader.size());

      // Calculate how many bytes we need for checksum on the tail of the block.
      int numBytes = (int) ChecksumUtil.numBytes(onDiskBlockBytesWithHeader.size(),
        fileContext.getBytesPerChecksum());

      // Put the header for the on disk bytes; header currently is unfilled-out
      putHeader(onDiskBlockBytesWithHeader, onDiskBlockBytesWithHeader.size() + numBytes,
        baosInMemory.size(), onDiskBlockBytesWithHeader.size());

      if (onDiskChecksum.length != numBytes) {
        onDiskChecksum = new byte[numBytes];
      }
      ChecksumUtil.generateChecksums(onDiskBlockBytesWithHeader.getBuffer(), 0,
        onDiskBlockBytesWithHeader.size(), onDiskChecksum, 0, fileContext.getChecksumType(),
        fileContext.getBytesPerChecksum());
    }
Finish up writing of the block. Flushes the compressing stream (if using compression), fills
out the header, does any compression/encryption of bytes to flush out to disk, and manages
the cache on write content, if applicable. Sets block write state to "block ready".
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java