@Override
  public ByteBuffer decodeKeyValues(
      DataInputStream source, HFileBlockDecodingContext blkDecodingCtx) throws IOException {
    if (blkDecodingCtx.getClass() != HFileBlockDefaultDecodingContext.class) {
      throw new IOException(
          this.getClass().getName()
              + " only accepts "
              + HFileBlockDefaultDecodingContext.class.getName()
              + " as the decoding context.");
    }

    HFileBlockDefaultDecodingContext decodingCtx =
        (HFileBlockDefaultDecodingContext) blkDecodingCtx;
    if (decodingCtx.getHFileContext().isIncludesTags()
        && decodingCtx.getHFileContext().isCompressTags()) {
      if (decodingCtx.getTagCompressionContext() != null) {
        // It will be overhead to create the TagCompressionContext again and again for every block
        // decoding.
        decodingCtx.getTagCompressionContext().clear();
      } else {
        try {
          TagCompressionContext tagCompressionContext =
              new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE);
          decodingCtx.setTagCompressionContext(tagCompressionContext);
        } catch (Exception e) {
          throw new IOException("Failed to initialize TagCompressionContext", e);
        }
      }
    }
    return internalDecodeKeyValues(source, 0, 0, decodingCtx);
  }
 public BufferedEncodedSeeker(CellComparator comparator, HFileBlockDecodingContext decodingCtx) {
   this.comparator = comparator;
   this.decodingCtx = decodingCtx;
   if (decodingCtx.getHFileContext().isCompressTags()) {
     try {
       tagCompressionContext = new TagCompressionContext(LRUDictionary.class, Byte.MAX_VALUE);
     } catch (Exception e) {
       throw new RuntimeException("Failed to initialize TagCompressionContext", e);
     }
   }
   current = createSeekerState(); // always valid
   previous = createSeekerState(); // may not be valid
 }