private void decode(boolean isFirst) {
      byte flag = currentBuffer.get();
      if ((flag & FLAG_SAME_KEY_LENGTH) == 0) {
        if (!isFirst) {
          System.arraycopy(current.keyBuffer,
            current.keyLength - current.prevTimestampAndType.length, current.prevTimestampAndType,
            0, current.prevTimestampAndType.length);
        }
        current.keyLength = ByteBuff.readCompressedInt(currentBuffer);
      }
      if ((flag & FLAG_SAME_VALUE_LENGTH) == 0) {
        current.valueLength = ByteBuff.readCompressedInt(currentBuffer);
      }
      current.lastCommonPrefix = ByteBuff.readCompressedInt(currentBuffer);

      current.ensureSpaceForKey();

      if (isFirst) {
        // copy everything
        currentBuffer.get(current.keyBuffer, current.lastCommonPrefix,
          current.keyLength - current.prevTimestampAndType.length);
        current.rowLengthWithSize = Bytes.toShort(current.keyBuffer, 0) + Bytes.SIZEOF_SHORT;
        current.familyLengthWithSize =
          current.keyBuffer[current.rowLengthWithSize] + Bytes.SIZEOF_BYTE;
      } else if (current.lastCommonPrefix < Bytes.SIZEOF_SHORT) {
        // length of row is different, copy everything except family

        // copy the row size
        int oldRowLengthWithSize = current.rowLengthWithSize;
        currentBuffer.get(current.keyBuffer, current.lastCommonPrefix,
          Bytes.SIZEOF_SHORT - current.lastCommonPrefix);
        current.rowLengthWithSize = Bytes.toShort(current.keyBuffer, 0) + Bytes.SIZEOF_SHORT;

        // move the column family
        System.arraycopy(current.keyBuffer, oldRowLengthWithSize, current.keyBuffer,
          current.rowLengthWithSize, current.familyLengthWithSize);

        // copy the rest of row
        currentBuffer.get(current.keyBuffer, Bytes.SIZEOF_SHORT,
          current.rowLengthWithSize - Bytes.SIZEOF_SHORT);

        // copy the qualifier
        currentBuffer.get(current.keyBuffer,
          current.rowLengthWithSize + current.familyLengthWithSize,
          current.keyLength - current.rowLengthWithSize - current.familyLengthWithSize
            - current.prevTimestampAndType.length);
      } else if (current.lastCommonPrefix < current.rowLengthWithSize) {
        // We have to copy part of row and qualifier, but the column family
        // is in the right place.

        // before column family (rest of row)
        currentBuffer.get(current.keyBuffer, current.lastCommonPrefix,
          current.rowLengthWithSize - current.lastCommonPrefix);

        // after column family (qualifier)
        currentBuffer.get(current.keyBuffer,
          current.rowLengthWithSize + current.familyLengthWithSize,
          current.keyLength - current.rowLengthWithSize - current.familyLengthWithSize
            - current.prevTimestampAndType.length);
      } else {
        // copy just the ending
        currentBuffer.get(current.keyBuffer, current.lastCommonPrefix,
          current.keyLength - current.prevTimestampAndType.length - current.lastCommonPrefix);
      }

      // timestamp
      int pos = current.keyLength - current.prevTimestampAndType.length;
      int commonTimestampPrefix = (flag & MASK_TIMESTAMP_LENGTH) >>> SHIFT_TIMESTAMP_LENGTH;
      if ((flag & FLAG_SAME_KEY_LENGTH) == 0) {
        System.arraycopy(current.prevTimestampAndType, 0, current.keyBuffer, pos,
          commonTimestampPrefix);
      }
      pos += commonTimestampPrefix;
      currentBuffer.get(current.keyBuffer, pos, Bytes.SIZEOF_LONG - commonTimestampPrefix);
      pos += Bytes.SIZEOF_LONG - commonTimestampPrefix;

      // type
      if ((flag & FLAG_SAME_TYPE) == 0) {
        currentBuffer.get(current.keyBuffer, pos, Bytes.SIZEOF_BYTE);
      } else if ((flag & FLAG_SAME_KEY_LENGTH) == 0) {
        current.keyBuffer[pos] = current.prevTimestampAndType[Bytes.SIZEOF_LONG];
      }

      // handle value
      if ((flag & FLAG_SAME_VALUE) == 0) {
        current.valueOffset = currentBuffer.position();
        currentBuffer.skip(current.valueLength);
      }

      if (includesTags()) {
        decodeTags();
      }
      if (includesMvcc()) {
        current.memstoreTS = ByteBufferUtils.readVLong(currentBuffer);
      } else {
        current.memstoreTS = 0;
      }
      current.nextKvOffset = currentBuffer.position();
    }
Copies the first key/value from the given stream, and initializes decompression state based
on it. Assumes that we have already read key and value lengths. Does not set
{@link #qualifierLength} (not used by decompression) or {@link #prevOffset} (set by the calle
afterwards).
hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/FastDiffDeltaEncoder.java