hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From st...@apache.org
Subject [5/6] hbase git commit: HBASE-18995 Move methods that are for internal usage from CellUtil to Private util class (Ramkrishna Vasudevan)
Date Sat, 28 Oct 2017 00:49:17 GMT
http://git-wip-us.apache.org/repos/asf/hbase/blob/f6c2490b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
index 12f6a30..20c217f 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java
@@ -18,7 +18,6 @@
 
 package org.apache.hadoop.hbase;
 
-import static org.apache.hadoop.hbase.HConstants.EMPTY_BYTE_ARRAY;
 import static org.apache.hadoop.hbase.Tag.TAG_LENGTH_SIZE;
 import static org.apache.hadoop.hbase.KeyValue.COLUMN_FAMILY_DELIMITER;
 import static org.apache.hadoop.hbase.KeyValue.getDelimiter;
@@ -28,9 +27,7 @@ import java.io.DataOutput;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.math.BigDecimal;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
@@ -38,25 +35,20 @@ import java.util.Map.Entry;
 import java.util.NavigableMap;
 
 import org.apache.hadoop.hbase.KeyValue.Type;
-import org.apache.hadoop.hbase.filter.ByteArrayComparable;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.yetus.audience.InterfaceAudience.Private;
 
 import com.google.common.annotations.VisibleForTesting;
 
 import org.apache.hadoop.hbase.io.HeapSize;
-import org.apache.hadoop.hbase.io.TagCompressionContext;
-import org.apache.hadoop.hbase.io.util.Dictionary;
-import org.apache.hadoop.hbase.io.util.StreamUtils;
 import org.apache.hadoop.hbase.util.ByteBufferUtils;
 import org.apache.hadoop.hbase.util.ByteRange;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.ClassSize;
 
 /**
- * Utility methods helpful slinging {@link Cell} instances.
- * Some methods below are for internal use only and are marked InterfaceAudience.Private at the
- * method level.
+ * Utility methods helpful for slinging {@link Cell} instances. Some methods below are for internal
+ * use only and are marked InterfaceAudience.Private at the method level. Note that all such methods
+ * have been marked deprecated in HBase-2.0 which will be subsequently removed in HBase-3.0
  */
 @InterfaceAudience.Public
 public final class CellUtil {
@@ -64,74 +56,96 @@ public final class CellUtil {
   /**
    * Private constructor to keep this class from being instantiated.
    */
-  private CellUtil(){}
+  private CellUtil() {
+  }
 
   /******************* ByteRange *******************************/
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static ByteRange fillRowRange(Cell cell, ByteRange range) {
-    return range.set(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
+    return PrivateCellUtil.fillRowRange(cell, range);
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static ByteRange fillFamilyRange(Cell cell, ByteRange range) {
-    return range.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
+    return PrivateCellUtil.fillFamilyRange(cell, range);
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static ByteRange fillQualifierRange(Cell cell, ByteRange range) {
-    return range.set(cell.getQualifierArray(), cell.getQualifierOffset(),
-      cell.getQualifierLength());
+    return PrivateCellUtil.fillQualifierRange(cell, range);
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static ByteRange fillValueRange(Cell cell, ByteRange range) {
-    return range.set(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
+    return PrivateCellUtil.fillValueRange(cell, range);
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static ByteRange fillTagRange(Cell cell, ByteRange range) {
-    return range.set(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength());
+    return PrivateCellUtil.fillTagRange(cell, range);
   }
 
   /***************** get individual arrays for tests ************/
 
-  public static byte[] cloneRow(Cell cell){
+  public static byte[] cloneRow(Cell cell) {
     byte[] output = new byte[cell.getRowLength()];
     copyRowTo(cell, output, 0);
     return output;
   }
 
-  public static byte[] cloneFamily(Cell cell){
+  public static byte[] cloneFamily(Cell cell) {
     byte[] output = new byte[cell.getFamilyLength()];
     copyFamilyTo(cell, output, 0);
     return output;
   }
 
-  public static byte[] cloneQualifier(Cell cell){
+  public static byte[] cloneQualifier(Cell cell) {
     byte[] output = new byte[cell.getQualifierLength()];
     copyQualifierTo(cell, output, 0);
     return output;
   }
 
-  public static byte[] cloneValue(Cell cell){
+  public static byte[] cloneValue(Cell cell) {
     byte[] output = new byte[cell.getValueLength()];
     copyValueTo(cell, output, 0);
     return output;
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static byte[] cloneTags(Cell cell) {
-    byte[] output = new byte[cell.getTagsLength()];
-    copyTagTo(cell, output, 0);
-    return output;
+    return PrivateCellUtil.cloneTags(cell);
   }
 
   /**
-   * Returns tag value in a new byte array. If server-side, use
-   * {@link Tag#getValueArray()} with appropriate {@link Tag#getValueOffset()} and
-   * {@link Tag#getValueLength()} instead to save on allocations.
+   * Returns tag value in a new byte array. If server-side, use {@link Tag#getValueArray()} with
+   * appropriate {@link Tag#getValueOffset()} and {@link Tag#getValueLength()} instead to save on
+   * allocations.
    * @param cell
    * @return tag value in a new byte array.
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0
    */
-  public static byte[] getTagArray(Cell cell){
-    byte[] output = new byte[cell.getTagsLength()];
-    copyTagTo(cell, output, 0);
-    return output;
+  @Deprecated
+  public static byte[] getTagArray(Cell cell) {
+    return PrivateCellUtil.getTagsArray(cell);
   }
 
   /**
@@ -142,7 +156,7 @@ public final class CellUtil {
    * @param qualifier
    * @return family:qualifier
    */
-  public static byte [] makeColumn(byte [] family, byte [] qualifier) {
+  public static byte[] makeColumn(byte[] family, byte[] qualifier) {
     return Bytes.add(family, COLUMN_FAMILY_DELIM_ARRAY, qualifier);
   }
 
@@ -159,20 +173,20 @@ public final class CellUtil {
    * @param c The column.
    * @return The parsed column.
    */
-  public static byte [][] parseColumn(byte [] c) {
+  public static byte[][] parseColumn(byte[] c) {
     final int index = getDelimiter(c, 0, c.length, COLUMN_FAMILY_DELIMITER);
     if (index == -1) {
       // If no delimiter, return array of size 1
-      return new byte [][] { c };
-    } else if(index == c.length - 1) {
+      return new byte[][] { c };
+    } else if (index == c.length - 1) {
       // family with empty qualifier, return array size 2
-      byte [] family = new byte[c.length-1];
+      byte[] family = new byte[c.length - 1];
       System.arraycopy(c, 0, family, 0, family.length);
-      return new byte [][] { family, HConstants.EMPTY_BYTE_ARRAY};
+      return new byte[][] { family, HConstants.EMPTY_BYTE_ARRAY };
     }
     // Family and column, return array size 2
-    final byte [][] result = new byte [2][];
-    result[0] = new byte [index];
+    final byte[][] result = new byte[2][];
+    result[0] = new byte[index];
     System.arraycopy(c, 0, result[0], 0, index);
     final int len = c.length - (index + 1);
     result[1] = new byte[len];
@@ -182,27 +196,40 @@ public final class CellUtil {
 
   /******************** copyTo **********************************/
 
+  /**
+   * Copies the row to the given byte[]
+   * @param cell the cell whose row has to be copied
+   * @param destination the destination byte[] to which the row has to be copied
+   * @param destinationOffset the offset in the destination byte[]
+   * @return the offset of the byte[] after the copy has happened
+   */
   public static int copyRowTo(Cell cell, byte[] destination, int destinationOffset) {
     short rowLen = cell.getRowLength();
     if (cell instanceof ByteBufferCell) {
-      ByteBufferUtils.copyFromBufferToArray(destination,
-          ((ByteBufferCell) cell).getRowByteBuffer(),
-          ((ByteBufferCell) cell).getRowPosition(), destinationOffset, rowLen);
+      ByteBufferUtils.copyFromBufferToArray(destination, ((ByteBufferCell) cell).getRowByteBuffer(),
+        ((ByteBufferCell) cell).getRowPosition(), destinationOffset, rowLen);
     } else {
       System.arraycopy(cell.getRowArray(), cell.getRowOffset(), destination, destinationOffset,
-          rowLen);
+        rowLen);
     }
     return destinationOffset + rowLen;
   }
 
+  /**
+   * Copies the row to the given bytebuffer
+   * @param cell cell the cell whose row has to be copied
+   * @param destination the destination bytebuffer to which the row has to be copied
+   * @param destinationOffset the offset in the destination byte[]
+   * @return the offset of the bytebuffer after the copy has happened
+   */
   public static int copyRowTo(Cell cell, ByteBuffer destination, int destinationOffset) {
     short rowLen = cell.getRowLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferCell) cell).getRowByteBuffer(),
-          destination, ((ByteBufferCell) cell).getRowPosition(), destinationOffset, rowLen);
+        destination, ((ByteBufferCell) cell).getRowPosition(), destinationOffset, rowLen);
     } else {
       ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getRowArray(),
-          cell.getRowOffset(), rowLen);
+        cell.getRowOffset(), rowLen);
     }
     return destinationOffset + rowLen;
   }
@@ -223,77 +250,119 @@ public final class CellUtil {
     }
   }
 
+  /**
+   * Copies the family to the given byte[]
+   * @param cell the cell whose family has to be copied
+   * @param destination the destination byte[] to which the family has to be copied
+   * @param destinationOffset the offset in the destination byte[]
+   * @return the offset of the byte[] after the copy has happened
+   */
   public static int copyFamilyTo(Cell cell, byte[] destination, int destinationOffset) {
     byte fLen = cell.getFamilyLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToArray(destination,
-          ((ByteBufferCell) cell).getFamilyByteBuffer(),
-          ((ByteBufferCell) cell).getFamilyPosition(), destinationOffset, fLen);
+        ((ByteBufferCell) cell).getFamilyByteBuffer(), ((ByteBufferCell) cell).getFamilyPosition(),
+        destinationOffset, fLen);
     } else {
       System.arraycopy(cell.getFamilyArray(), cell.getFamilyOffset(), destination,
-          destinationOffset, fLen);
+        destinationOffset, fLen);
     }
     return destinationOffset + fLen;
   }
 
+  /**
+   * Copies the family to the given bytebuffer
+   * @param cell the cell whose family has to be copied
+   * @param destination the destination bytebuffer to which the family has to be copied
+   * @param destinationOffset the offset in the destination bytebuffer
+   * @return the offset of the bytebuffer after the copy has happened
+   */
   public static int copyFamilyTo(Cell cell, ByteBuffer destination, int destinationOffset) {
     byte fLen = cell.getFamilyLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferCell) cell).getFamilyByteBuffer(),
-          destination, ((ByteBufferCell) cell).getFamilyPosition(), destinationOffset, fLen);
+        destination, ((ByteBufferCell) cell).getFamilyPosition(), destinationOffset, fLen);
     } else {
       ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getFamilyArray(),
-          cell.getFamilyOffset(), fLen);
+        cell.getFamilyOffset(), fLen);
     }
     return destinationOffset + fLen;
   }
 
+  /**
+   * Copies the qualifier to the given byte[]
+   * @param cell the cell whose qualifier has to be copied
+   * @param destination the destination byte[] to which the qualifier has to be copied
+   * @param destinationOffset the offset in the destination byte[]
+   * @return the offset of the byte[] after the copy has happened
+   */
   public static int copyQualifierTo(Cell cell, byte[] destination, int destinationOffset) {
     int qlen = cell.getQualifierLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToArray(destination,
-          ((ByteBufferCell) cell).getQualifierByteBuffer(),
-          ((ByteBufferCell) cell).getQualifierPosition(), destinationOffset, qlen);
+        ((ByteBufferCell) cell).getQualifierByteBuffer(),
+        ((ByteBufferCell) cell).getQualifierPosition(), destinationOffset, qlen);
     } else {
       System.arraycopy(cell.getQualifierArray(), cell.getQualifierOffset(), destination,
-          destinationOffset, qlen);
+        destinationOffset, qlen);
     }
     return destinationOffset + qlen;
   }
 
+  /**
+   * Copies the qualifier to the given bytebuffer
+   * @param cell the cell whose qualifier has to be copied
+   * @param destination the destination bytebuffer to which the qualifier has to be copied
+   * @param destinationOffset the offset in the destination bytebuffer
+   * @return the offset of the bytebuffer after the copy has happened
+   */
   public static int copyQualifierTo(Cell cell, ByteBuffer destination, int destinationOffset) {
     int qlen = cell.getQualifierLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferCell) cell).getQualifierByteBuffer(),
-          destination, ((ByteBufferCell) cell).getQualifierPosition(), destinationOffset, qlen);
+        destination, ((ByteBufferCell) cell).getQualifierPosition(), destinationOffset, qlen);
     } else {
       ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset,
-          cell.getQualifierArray(), cell.getQualifierOffset(), qlen);
+        cell.getQualifierArray(), cell.getQualifierOffset(), qlen);
     }
     return destinationOffset + qlen;
   }
 
+  /**
+   * Copies the value to the given byte[]
+   * @param cell the cell whose value has to be copied
+   * @param destination the destination byte[] to which the value has to be copied
+   * @param destinationOffset the offset in the destination byte[]
+   * @return the offset of the byte[] after the copy has happened
+   */
   public static int copyValueTo(Cell cell, byte[] destination, int destinationOffset) {
     int vlen = cell.getValueLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToArray(destination,
-          ((ByteBufferCell) cell).getValueByteBuffer(),
-          ((ByteBufferCell) cell).getValuePosition(), destinationOffset, vlen);
+        ((ByteBufferCell) cell).getValueByteBuffer(), ((ByteBufferCell) cell).getValuePosition(),
+        destinationOffset, vlen);
     } else {
       System.arraycopy(cell.getValueArray(), cell.getValueOffset(), destination, destinationOffset,
-          vlen);
+        vlen);
     }
     return destinationOffset + vlen;
   }
 
+  /**
+   * Copies the value to the given bytebuffer
+   * @param cell the cell whose value has to be copied
+   * @param destination the destination bytebuffer to which the value has to be copied
+   * @param destinationOffset the offset in the destination bytebuffer
+   * @return the offset of the bytebuffer after the copy has happened
+   */
   public static int copyValueTo(Cell cell, ByteBuffer destination, int destinationOffset) {
     int vlen = cell.getValueLength();
     if (cell instanceof ByteBufferCell) {
       ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferCell) cell).getValueByteBuffer(),
-          destination, ((ByteBufferCell) cell).getValuePosition(), destinationOffset, vlen);
+        destination, ((ByteBufferCell) cell).getValuePosition(), destinationOffset, vlen);
     } else {
       ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getValueArray(),
-          cell.getValueOffset(), vlen);
+        cell.getValueOffset(), vlen);
     }
     return destinationOffset + vlen;
   }
@@ -304,56 +373,43 @@ public final class CellUtil {
    * @param destination
    * @param destinationOffset
    * @return position after tags
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
    */
+  @Deprecated
   public static int copyTagTo(Cell cell, byte[] destination, int destinationOffset) {
-    int tlen = cell.getTagsLength();
-    if (cell instanceof ByteBufferCell) {
-      ByteBufferUtils.copyFromBufferToArray(destination,
-          ((ByteBufferCell) cell).getTagsByteBuffer(),
-          ((ByteBufferCell) cell).getTagsPosition(), destinationOffset, tlen);
-    } else {
-      System.arraycopy(cell.getTagsArray(), cell.getTagsOffset(), destination, destinationOffset,
-          tlen);
-    }
-    return destinationOffset + tlen;
+    return PrivateCellUtil.copyTagsTo(cell, destination, destinationOffset);
   }
 
+  /**
+   * Copies the tags info into the tag portion of the cell
+   * @param cell
+   * @param destination
+   * @param destinationOffset
+   * @return position after tags
+   * @deprecated As of HBase-2.0. Will be removed in 3.0.
+   */
+  @Deprecated
   public static int copyTagTo(Cell cell, ByteBuffer destination, int destinationOffset) {
-    int tlen = cell.getTagsLength();
-    if (cell instanceof ByteBufferCell) {
-      ByteBufferUtils.copyFromBufferToBuffer(((ByteBufferCell) cell).getTagsByteBuffer(),
-          destination, ((ByteBufferCell) cell).getTagsPosition(), destinationOffset, tlen);
-    } else {
-      ByteBufferUtils.copyFromArrayToBuffer(destination, destinationOffset, cell.getTagsArray(),
-          cell.getTagsOffset(), tlen);
-    }
-    return destinationOffset + tlen;
+    return PrivateCellUtil.copyTagsTo(cell, destination, destinationOffset);
   }
 
   /********************* misc *************************************/
 
   @Private
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in HBase-3.0.
+   */
+  @Deprecated
   public static byte getRowByte(Cell cell, int index) {
-    if (cell instanceof ByteBufferCell) {
-      return ((ByteBufferCell) cell).getRowByteBuffer().get(
-          ((ByteBufferCell) cell).getRowPosition() + index);
-    }
-    return cell.getRowArray()[cell.getRowOffset() + index];
-  }
-
-  @Private
-  public static byte getQualifierByte(Cell cell, int index) {
-    if (cell instanceof ByteBufferCell) {
-      return ((ByteBufferCell) cell).getQualifierByteBuffer().get(
-          ((ByteBufferCell) cell).getQualifierPosition() + index);
-    }
-    return cell.getQualifierArray()[cell.getQualifierOffset() + index];
+    return PrivateCellUtil.getRowByte(cell, index);
   }
 
+  /**
+   * @deprecated As of HBase-2.0. Will be removed in 3.0.
+   */
+  @Deprecated
   public static ByteBuffer getValueBufferShallowCopy(Cell cell) {
-    ByteBuffer buffer = ByteBuffer.wrap(cell.getValueArray(), cell.getValueOffset(),
-      cell.getValueLength());
-    return buffer;
+    return PrivateCellUtil.getValueBufferShallowCopy(cell);
   }
 
   /**
@@ -365,17 +421,17 @@ public final class CellUtil {
   public static ByteBuffer getQualifierBufferShallowCopy(Cell cell) {
     // No usage of this in code.
     ByteBuffer buffer = ByteBuffer.wrap(cell.getQualifierArray(), cell.getQualifierOffset(),
-        cell.getQualifierLength());
+      cell.getQualifierLength());
     return buffer;
   }
 
   /**
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link CellBuilder} instead
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder}
+   *             instead
    */
   @Deprecated
-  public static Cell createCell(final byte [] row, final byte [] family, final byte [] qualifier,
-      final long timestamp, final byte type, final byte [] value) {
+  public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier,
+      final long timestamp, final byte type, final byte[] value) {
     return ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY)
             .setRow(row)
             .setFamily(family)
@@ -388,13 +444,13 @@ public final class CellUtil {
 
   /**
    * Creates a cell with deep copy of all passed bytes.
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link CellBuilder} instead
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder}
+   *             instead
    */
   @Deprecated
-  public static Cell createCell(final byte [] rowArray, final int rowOffset, final int rowLength,
-      final byte [] familyArray, final int familyOffset, final int familyLength,
-      final byte [] qualifierArray, final int qualifierOffset, final int qualifierLength) {
+  public static Cell createCell(final byte[] rowArray, final int rowOffset, final int rowLength,
+      final byte[] familyArray, final int familyOffset, final int familyLength,
+      final byte[] qualifierArray, final int qualifierOffset, final int qualifierLength) {
     // See createCell(final byte [] row, final byte [] value) for why we default Maximum type.
     return ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY)
             .setRow(rowArray, rowOffset, rowLength)
@@ -408,10 +464,10 @@ public final class CellUtil {
 
   /**
    * Marked as audience Private as of 1.2.0.
-   * Creating a Cell with a memstoreTS/mvcc is an internal implementation detail not for
-   * public use.
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link ExtendedCellBuilder} instead
+   * Creating a Cell with a memstoreTS/mvcc is an internal
+   * implementation detail not for public use.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
+   *             {@link ExtendedCellBuilder} instead
    */
   @InterfaceAudience.Private
   @Deprecated
@@ -422,10 +478,10 @@ public final class CellUtil {
 
   /**
    * Marked as audience Private as of 1.2.0.
-   * Creating a Cell with tags and a memstoreTS/mvcc is an internal implementation detail not for
-   * public use.
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link ExtendedCellBuilder} instead
+   * Creating a Cell with tags and a memstoreTS/mvcc is an
+   * internal implementation detail not for public use.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
+   *             {@link ExtendedCellBuilder} instead
    */
   @InterfaceAudience.Private
   @Deprecated
@@ -446,43 +502,41 @@ public final class CellUtil {
 
   /**
    * Marked as audience Private as of 1.2.0.
-   * Creating a Cell with tags is an internal implementation detail not for
-   * public use.
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link ExtendedCellBuilder} instead
+   * Creating a Cell with tags is an internal implementation detail not for public use.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
+   *             {@link ExtendedCellBuilder} instead
    */
   @InterfaceAudience.Private
   @Deprecated
   public static Cell createCell(final byte[] row, final byte[] family, final byte[] qualifier,
       final long timestamp, Type type, final byte[] value, byte[] tags) {
-    return createCell(row, family, qualifier, timestamp, type.getCode(), value,
-            tags, 0);
+    return createCell(row, family, qualifier, timestamp, type.getCode(), value, tags, 0);
   }
 
   /**
-   * Create a Cell with specific row.  Other fields defaulted.
+   * Create a Cell with specific row. Other fields defaulted.
    * @param row
    * @return Cell with passed row but all other fields are arbitrary
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link CellBuilder} instead
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder}
+   *             instead
    */
   @Deprecated
-  public static Cell createCell(final byte [] row) {
+  public static Cell createCell(final byte[] row) {
     return createCell(row, HConstants.EMPTY_BYTE_ARRAY);
   }
 
   /**
-   * Create a Cell with specific row and value.  Other fields are defaulted.
+   * Create a Cell with specific row and value. Other fields are defaulted.
    * @param row
    * @param value
    * @return Cell with passed row and value but all other fields are arbitrary
-   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Use {@link CellBuilder} instead
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use {@link CellBuilder}
+   *             instead
    */
   @Deprecated
-  public static Cell createCell(final byte [] row, final byte [] value) {
+  public static Cell createCell(final byte[] row, final byte[] value) {
     // An empty family + empty qualifier + Type.Minimum is used as flag to indicate last on row.
-    // See the CellComparator and KeyValue comparator.  Search for compareWithoutRow.
+    // See the CellComparator and KeyValue comparator. Search for compareWithoutRow.
     // Lets not make a last-on-row key as default but at same time, if you are making a key
     // without specifying type, etc., flag it as weird by setting type to be Maximum.
     return createCell(row, HConstants.EMPTY_BYTE_ARRAY, HConstants.EMPTY_BYTE_ARRAY,
@@ -517,3112 +571,889 @@ public final class CellUtil {
    */
   public static Cell createCell(Cell cell, byte[] tags) {
     if (cell instanceof ByteBufferCell) {
-      return new TagRewriteByteBufferCell((ByteBufferCell) cell, tags);
+      return new PrivateCellUtil.TagRewriteByteBufferCell((ByteBufferCell) cell, tags);
     }
-    return new TagRewriteCell(cell, tags);
+    return new PrivateCellUtil.TagRewriteCell(cell, tags);
   }
 
   public static Cell createCell(Cell cell, byte[] value, byte[] tags) {
     if (cell instanceof ByteBufferCell) {
-      return new ValueAndTagRewriteByteBufferCell((ByteBufferCell) cell, value, tags);
+      return new PrivateCellUtil.ValueAndTagRewriteByteBufferCell((ByteBufferCell) cell, value,
+          tags);
     }
-    return new ValueAndTagRewriteCell(cell, value, tags);
+    return new PrivateCellUtil.ValueAndTagRewriteCell(cell, value, tags);
   }
 
   /**
-   * This can be used when a Cell has to change with addition/removal of one or more tags. This is an
-   * efficient way to do so in which only the tags bytes part need to recreated and copied. All other
-   * parts, refer to the original Cell.
+   * @param cellScannerables
+   * @return CellScanner interface over <code>cellIterables</code>
    */
-  @InterfaceAudience.Private
-  private static class TagRewriteCell implements ExtendedCell {
-    protected Cell cell;
-    protected byte[] tags;
-    private static final long HEAP_SIZE_OVERHEAD = ClassSize.OBJECT + 2 * ClassSize.REFERENCE;
-
-    /**
-     * @param cell The original Cell which it rewrites
-     * @param tags the tags bytes. The array suppose to contain the tags bytes alone.
-     */
-    public TagRewriteCell(Cell cell, byte[] tags) {
-      assert cell instanceof ExtendedCell;
-      assert tags != null;
-      this.cell = cell;
-      this.tags = tags;
-      // tag offset will be treated as 0 and length this.tags.length
-      if (this.cell instanceof TagRewriteCell) {
-        // Cleaning the ref so that the byte[] can be GCed
-        ((TagRewriteCell) this.cell).tags = null;
+  public static CellScanner createCellScanner(
+      final List<? extends CellScannable> cellScannerables) {
+    return new CellScanner() {
+      private final Iterator<? extends CellScannable> iterator = cellScannerables.iterator();
+      private CellScanner cellScanner = null;
+
+      @Override
+      public Cell current() {
+        return this.cellScanner != null? this.cellScanner.current(): null;
       }
-    }
 
-    @Override
-    public byte[] getRowArray() {
-      return cell.getRowArray();
-    }
+      @Override
+      public boolean advance() throws IOException {
+        while (true) {
+          if (this.cellScanner == null) {
+            if (!this.iterator.hasNext()) return false;
+            this.cellScanner = this.iterator.next().cellScanner();
+          }
+          if (this.cellScanner.advance()) return true;
+          this.cellScanner = null;
+        }
+      }
+    };
+  }
 
-    @Override
-    public int getRowOffset() {
-      return cell.getRowOffset();
-    }
+  /**
+   * @param cellIterable
+   * @return CellScanner interface over <code>cellIterable</code>
+   */
+  public static CellScanner createCellScanner(final Iterable<Cell> cellIterable) {
+    if (cellIterable == null) return null;
+    return createCellScanner(cellIterable.iterator());
+  }
 
-    @Override
-    public short getRowLength() {
-      return cell.getRowLength();
-    }
+  /**
+   * @param cells
+   * @return CellScanner interface over <code>cellIterable</code> or null if <code>cells</code> is
+   * null
+   */
+  public static CellScanner createCellScanner(final Iterator<Cell> cells) {
+    if (cells == null) return null;
+    return new CellScanner() {
+      private final Iterator<Cell> iterator = cells;
+      private Cell current = null;
 
-    @Override
-    public byte[] getFamilyArray() {
-      return cell.getFamilyArray();
-    }
+      @Override
+      public Cell current() {
+        return this.current;
+      }
 
-    @Override
-    public int getFamilyOffset() {
-      return cell.getFamilyOffset();
-    }
+      @Override
+      public boolean advance() {
+        boolean hasNext = this.iterator.hasNext();
+        this.current = hasNext? this.iterator.next(): null;
+        return hasNext;
+      }
+    };
+  }
 
-    @Override
-    public byte getFamilyLength() {
-      return cell.getFamilyLength();
-    }
+  /**
+   * @param cellArray
+   * @return CellScanner interface over <code>cellArray</code>
+   */
+  public static CellScanner createCellScanner(final Cell[] cellArray) {
+    return new CellScanner() {
+      private final Cell [] cells = cellArray;
+      private int index = -1;
 
-    @Override
-    public byte[] getQualifierArray() {
-      return cell.getQualifierArray();
-    }
+      @Override
+      public Cell current() {
+        if (cells == null) return null;
+        return (index < 0)? null: this.cells[index];
+      }
 
-    @Override
-    public int getQualifierOffset() {
-      return cell.getQualifierOffset();
-    }
+      @Override
+      public boolean advance() {
+        if (cells == null) return false;
+        return ++index < this.cells.length;
+      }
+    };
+  }
 
-    @Override
-    public int getQualifierLength() {
-      return cell.getQualifierLength();
-    }
+  /**
+   * Flatten the map of cells out under the CellScanner
+   * @param map Map of Cell Lists; for example, the map of families to Cells that is used
+   * inside Put, etc., keeping Cells organized by family.
+   * @return CellScanner interface over <code>cellIterable</code>
+   */
+  public static CellScanner createCellScanner(final NavigableMap<byte [], List<Cell>> map) {
+    return new CellScanner() {
+      private final Iterator<Entry<byte[], List<Cell>>> entries = map.entrySet().iterator();
+      private Iterator<Cell> currentIterator = null;
+      private Cell currentCell;
 
-    @Override
-    public long getTimestamp() {
-      return cell.getTimestamp();
-    }
+      @Override
+      public Cell current() {
+        return this.currentCell;
+      }
 
-    @Override
-    public byte getTypeByte() {
-      return cell.getTypeByte();
-    }
+      @Override
+      public boolean advance() {
+        while(true) {
+          if (this.currentIterator == null) {
+            if (!this.entries.hasNext()) return false;
+            this.currentIterator = this.entries.next().getValue().iterator();
+          }
+          if (this.currentIterator.hasNext()) {
+            this.currentCell = this.currentIterator.next();
+            return true;
+          }
+          this.currentCell = null;
+          this.currentIterator = null;
+        }
+      }
+    };
+  }
 
-    @Override
-    public long getSequenceId() {
-      return cell.getSequenceId();
-    }
+  /**
+   * @param left
+   * @param right
+   * @return True if the rows in <code>left</code> and <code>right</code> Cells match
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Instead use {@link #matchingRows(Cell, Cell)}
+   */
+  @Deprecated
+  public static boolean matchingRow(final Cell left, final Cell right) {
+    return matchingRows(left, right);
+  }
 
-    @Override
-    public byte[] getValueArray() {
-      return cell.getValueArray();
-    }
+  /**
+   *  @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   *             Instead use {@link #matchingRows(Cell, byte[])}
+   */
+  @Deprecated
+  public static boolean matchingRow(final Cell left, final byte[] buf) {
+    return matchingRows(left, buf);
+  }
 
-    @Override
-    public int getValueOffset() {
-      return cell.getValueOffset();
+  public static boolean matchingRows(final Cell left, final byte[] buf) {
+    if (buf == null) {
+      return left.getRowLength() == 0;
     }
+    return PrivateCellUtil.matchingRows(left, buf, 0, buf.length);
+  }
 
-    @Override
-    public int getValueLength() {
-      return cell.getValueLength();
-    }
+  public static boolean matchingRow(final Cell left, final byte[] buf, final int offset,
+      final int length) {
+    return PrivateCellUtil.matchingRows(left, buf, offset, length);
+  }
 
-    @Override
-    public byte[] getTagsArray() {
-      return this.tags;
+  public static boolean matchingFamily(final Cell left, final Cell right) {
+    byte lfamlength = left.getFamilyLength();
+    byte rfamlength = right.getFamilyLength();
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getFamilyByteBuffer(),
+          ((ByteBufferCell) left).getFamilyPosition(), lfamlength,
+          ((ByteBufferCell) right).getFamilyByteBuffer(),
+          ((ByteBufferCell) right).getFamilyPosition(), rfamlength);
     }
-
-    @Override
-    public int getTagsOffset() {
-      return 0;
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getFamilyByteBuffer(),
+          ((ByteBufferCell) left).getFamilyPosition(), lfamlength,
+          right.getFamilyArray(), right.getFamilyOffset(), rfamlength);
     }
-
-    @Override
-    public int getTagsLength() {
-      if (null == this.tags) {
-        // Nulled out tags array optimization in constructor
-        return 0;
-      }
-      return this.tags.length;
+    if (right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) right).getFamilyByteBuffer(),
+          ((ByteBufferCell) right).getFamilyPosition(), rfamlength,
+          left.getFamilyArray(), left.getFamilyOffset(), lfamlength);
     }
+    return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), lfamlength,
+        right.getFamilyArray(), right.getFamilyOffset(), rfamlength);
+  }
 
-    @Override
-    public long heapSize() {
-      long sum = HEAP_SIZE_OVERHEAD + CellUtil.estimatedHeapSizeOf(cell);
-      if (this.tags != null) {
-        sum += ClassSize.sizeOf(this.tags);
-      }
-      return sum;
+  public static boolean matchingFamily(final Cell left, final byte[] buf) {
+    if (buf == null) {
+      return left.getFamilyLength() == 0;
     }
+    return matchingFamily(left, buf, 0, buf.length);
+  }
 
-    @Override
-    public void setTimestamp(long ts) throws IOException {
-      // The incoming cell is supposed to be SettableTimestamp type.
-      CellUtil.setTimestamp(cell, ts);
-    }
-
-    @Override
-    public void setTimestamp(byte[] ts, int tsOffset) throws IOException {
-      // The incoming cell is supposed to be SettableTimestamp type.
-      CellUtil.setTimestamp(cell, ts, tsOffset);
-    }
-
-    @Override
-    public void setSequenceId(long seqId) throws IOException {
-      // The incoming cell is supposed to be SettableSequenceId type.
-      CellUtil.setSequenceId(cell, seqId);
-    }
-
-    @Override
-    public int write(OutputStream out, boolean withTags) throws IOException {
-      int len = ((ExtendedCell) this.cell).write(out, false);
-      if (withTags && this.tags != null) {
-        // Write the tagsLength 2 bytes
-        out.write((byte) (0xff & (this.tags.length >> 8)));
-        out.write((byte) (0xff & this.tags.length));
-        out.write(this.tags);
-        len += KeyValue.TAGS_LENGTH_SIZE + this.tags.length;
-      }
-      return len;
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean matchingFamily(final Cell left, final byte[] buf, final int offset,
+      final int length) {
+    return PrivateCellUtil.matchingFamily(left, buf, offset, length);
+  }
 
-    @Override
-    public int getSerializedSize(boolean withTags) {
-      int len = ((ExtendedCell) this.cell).getSerializedSize(false);
-      if (withTags && this.tags != null) {
-        len += KeyValue.TAGS_LENGTH_SIZE + this.tags.length;
-      }
-      return len;
+  public static boolean matchingQualifier(final Cell left, final Cell right) {
+    int lqlength = left.getQualifierLength();
+    int rqlength = right.getQualifierLength();
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getQualifierByteBuffer(),
+          ((ByteBufferCell) left).getQualifierPosition(), lqlength,
+          ((ByteBufferCell) right).getQualifierByteBuffer(),
+          ((ByteBufferCell) right).getQualifierPosition(), rqlength);
     }
-
-    @Override
-    public void write(ByteBuffer buf, int offset) {
-      offset = KeyValueUtil.appendTo(this.cell, buf, offset, false);
-      int tagsLen = this.tags == null ? 0 : this.tags.length;
-      if (tagsLen > 0) {
-        offset = ByteBufferUtils.putAsShort(buf, offset, tagsLen);
-        ByteBufferUtils.copyFromArrayToBuffer(buf, offset, this.tags, 0, tagsLen);
-      }
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getQualifierByteBuffer(),
+          ((ByteBufferCell) left).getQualifierPosition(), lqlength,
+          right.getQualifierArray(), right.getQualifierOffset(), rqlength);
     }
-
-    @Override
-    public ExtendedCell deepClone() {
-      Cell clonedBaseCell = ((ExtendedCell) this.cell).deepClone();
-      return new TagRewriteCell(clonedBaseCell, this.tags);
+    if (right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) right).getQualifierByteBuffer(),
+          ((ByteBufferCell) right).getQualifierPosition(), rqlength,
+          left.getQualifierArray(), left.getQualifierOffset(), lqlength);
     }
+    return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(),
+        lqlength, right.getQualifierArray(), right.getQualifierOffset(),
+        rqlength);
   }
 
-  @InterfaceAudience.Private
-  private static class TagRewriteByteBufferCell extends ByteBufferCell implements ExtendedCell {
-
-    protected ByteBufferCell cell;
-    protected byte[] tags;
-    private static final long HEAP_SIZE_OVERHEAD = ClassSize.OBJECT + 2 * ClassSize.REFERENCE;
-
-    /**
-     * @param cell The original ByteBufferCell which it rewrites
-     * @param tags the tags bytes. The array suppose to contain the tags bytes alone.
-     */
-    public TagRewriteByteBufferCell(ByteBufferCell cell, byte[] tags) {
-      assert cell instanceof ExtendedCell;
-      assert tags != null;
-      this.cell = cell;
-      this.tags = tags;
-      // tag offset will be treated as 0 and length this.tags.length
-      if (this.cell instanceof TagRewriteByteBufferCell) {
-        // Cleaning the ref so that the byte[] can be GCed
-        ((TagRewriteByteBufferCell) this.cell).tags = null;
-      }
+  /**
+   * Finds if the qualifier part of the cell and the KV serialized
+   * byte[] are equal
+   * @param left
+   * @param buf the serialized keyvalue format byte[]
+   * @return true if the qualifier matches, false otherwise
+   */
+  public static boolean matchingQualifier(final Cell left, final byte[] buf) {
+    if (buf == null) {
+      return left.getQualifierLength() == 0;
     }
+    return matchingQualifier(left, buf, 0, buf.length);
+  }
 
-    @Override
-    public byte[] getRowArray() {
-      return this.cell.getRowArray();
-    }
+  /**
+   * Finds if the qualifier part of the cell and the KV serialized
+   * byte[] are equal
+   * @param left
+   * @param buf the serialized keyvalue format byte[]
+   * @param offset the offset of the qualifier in the byte[]
+   * @param length the length of the qualifier in the byte[]
+   * @return true if the qualifier matches, false otherwise
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean matchingQualifier(final Cell left, final byte[] buf, final int offset,
+      final int length) {
+    return PrivateCellUtil.matchingQualifier(left, buf, offset, length);
+  }
 
-    @Override
-    public int getRowOffset() {
-      return this.cell.getRowOffset();
-    }
+  public static boolean matchingColumn(final Cell left, final byte[] fam, final byte[] qual) {
+    if (!matchingFamily(left, fam))
+      return false;
+    return matchingQualifier(left, qual);
+  }
 
-    @Override
-    public short getRowLength() {
-      return this.cell.getRowLength();
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean matchingColumn(final Cell left, final byte[] fam, final int foffset,
+      final int flength, final byte[] qual, final int qoffset, final int qlength) {
+    return PrivateCellUtil.matchingColumn(left, fam, foffset, flength, qual, qoffset, qlength);
+  }
 
-    @Override
-    public byte[] getFamilyArray() {
-      return this.cell.getFamilyArray();
-    }
+  public static boolean matchingColumn(final Cell left, final Cell right) {
+    if (!matchingFamily(left, right))
+      return false;
+    return matchingQualifier(left, right);
+  }
 
-    @Override
-    public int getFamilyOffset() {
-      return this.cell.getFamilyOffset();
-    }
+  public static boolean matchingValue(final Cell left, final Cell right) {
+    return matchingValue(left, right, left.getValueLength(), right.getValueLength());
+  }
 
-    @Override
-    public byte getFamilyLength() {
-      return this.cell.getFamilyLength();
+  public static boolean matchingValue(final Cell left, final Cell right, int lvlength,
+      int rvlength) {
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getValueByteBuffer(),
+        ((ByteBufferCell) left).getValuePosition(), lvlength,
+        ((ByteBufferCell) right).getValueByteBuffer(),
+        ((ByteBufferCell) right).getValuePosition(), rvlength);
     }
-
-    @Override
-    public byte[] getQualifierArray() {
-      return this.cell.getQualifierArray();
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) left).getValueByteBuffer(),
+        ((ByteBufferCell) left).getValuePosition(), lvlength, right.getValueArray(),
+        right.getValueOffset(), rvlength);
     }
-
-    @Override
-    public int getQualifierOffset() {
-      return this.cell.getQualifierOffset();
+    if (right instanceof ByteBufferCell) {
+      return ByteBufferUtils.equals(((ByteBufferCell) right).getValueByteBuffer(),
+        ((ByteBufferCell) right).getValuePosition(), rvlength, left.getValueArray(),
+        left.getValueOffset(), lvlength);
     }
+    return Bytes.equals(left.getValueArray(), left.getValueOffset(), lvlength,
+      right.getValueArray(), right.getValueOffset(), rvlength);
+  }
 
-    @Override
-    public int getQualifierLength() {
-      return this.cell.getQualifierLength();
+  public static boolean matchingValue(final Cell left, final byte[] buf) {
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) left).getValueByteBuffer(),
+          ((ByteBufferCell) left).getValuePosition(), left.getValueLength(), buf, 0,
+          buf.length) == 0;
     }
+    return Bytes.equals(left.getValueArray(), left.getValueOffset(), left.getValueLength(), buf, 0,
+        buf.length);
+  }
 
-    @Override
-    public long getTimestamp() {
-      return this.cell.getTimestamp();
-    }
+  /**
+   * @return True if a delete type, a {@link KeyValue.Type#Delete} or a
+   *         {KeyValue.Type#DeleteFamily} or a
+   *         {@link KeyValue.Type#DeleteColumn} KeyValue type.
+   */
+  public static boolean isDelete(final Cell cell) {
+    return PrivateCellUtil.isDelete(cell.getTypeByte());
+  }
 
-    @Override
-    public byte getTypeByte() {
-      return this.cell.getTypeByte();
-    }
+  /**
+   * @return True if a delete type, a {@link KeyValue.Type#Delete} or a
+   *         {KeyValue.Type#DeleteFamily} or a
+   *         {@link KeyValue.Type#DeleteColumn} KeyValue type.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean isDelete(final byte type) {
+    return Type.Delete.getCode() <= type
+        && type <= Type.DeleteFamily.getCode();
+  }
 
-    @Override
-    public long getSequenceId() {
-      return this.cell.getSequenceId();
-    }
+  /**
+   * @return True if this cell is a {@link KeyValue.Type#Delete} type.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean isDeleteType(Cell cell) {
+    return cell.getTypeByte() == Type.Delete.getCode();
+  }
 
-    @Override
-    public byte[] getValueArray() {
-      return this.cell.getValueArray();
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 
+   */
+  @Deprecated
+  public static boolean isDeleteFamily(final Cell cell) {
+    return cell.getTypeByte() == Type.DeleteFamily.getCode();
+  }
 
-    @Override
-    public int getValueOffset() {
-      return this.cell.getValueOffset();
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 
+   */
+  @Deprecated
+  public static boolean isDeleteFamilyVersion(final Cell cell) {
+    return cell.getTypeByte() == Type.DeleteFamilyVersion.getCode();
+  }
 
-    @Override
-    public int getValueLength() {
-      return this.cell.getValueLength();
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 
+   */
+  @Deprecated
+  public static boolean isDeleteColumns(final Cell cell) {
+    return cell.getTypeByte() == Type.DeleteColumn.getCode();
+  }
 
-    @Override
-    public byte[] getTagsArray() {
-      return this.tags;
-    }
+  /**
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. 
+   */
+  @Deprecated
+  public static boolean isDeleteColumnVersion(final Cell cell) {
+    return cell.getTypeByte() == Type.Delete.getCode();
+  }
 
-    @Override
-    public int getTagsOffset() {
-      return 0;
-    }
+  /**
+   *
+   * @return True if this cell is a delete family or column type.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static boolean isDeleteColumnOrFamily(Cell cell) {
+    int t = cell.getTypeByte();
+    return t == Type.DeleteColumn.getCode() || t == Type.DeleteFamily.getCode();
+  }
 
-    @Override
-    public int getTagsLength() {
-      if (null == this.tags) {
-        // Nulled out tags array optimization in constructor
-        return 0;
-      }
-      return this.tags.length;
-    }
+  /**
+   * Estimate based on keyvalue's serialization format in the RPC layer. Note that there is an extra
+   * SIZEOF_INT added to the size here that indicates the actual length of the cell for cases where
+   * cell's are serialized in a contiguous format (For eg in RPCs).
+   * @param cell
+   * @return Estimate of the <code>cell</code> size in bytes plus an extra SIZEOF_INT indicating the
+   *         actual cell length.
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static int estimatedSerializedSizeOf(final Cell cell) {
+    return PrivateCellUtil.estimatedSerializedSizeOf(cell);
+  }
 
-    @Override
-    public void setSequenceId(long seqId) throws IOException {
-      CellUtil.setSequenceId(this.cell, seqId);
-    }
+  /**
+   * Calculates the serialized key size. We always serialize in the KeyValue's serialization
+   * format.
+   * @param cell the cell for which the key size has to be calculated.
+   * @return the key size
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static int estimatedSerializedSizeOfKey(final Cell cell) {
+    return PrivateCellUtil.estimatedSerializedSizeOfKey(cell);
+  }
 
-    @Override
-    public void setTimestamp(long ts) throws IOException {
-      CellUtil.setTimestamp(this.cell, ts);
-    }
+  /**
+   * This is an estimate of the heap space occupied by a cell. When the cell is of type
+   * {@link HeapSize} we call {@link HeapSize#heapSize()} so cell can give a correct value. In other
+   * cases we just consider the bytes occupied by the cell components ie. row, CF, qualifier,
+   * timestamp, type, value and tags.
+   * @param cell
+   * @return estimate of the heap space
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static long estimatedHeapSizeOf(final Cell cell) {
+    return PrivateCellUtil.estimatedHeapSizeOf(cell);
+  }
 
-    @Override
-    public void setTimestamp(byte[] ts, int tsOffset) throws IOException {
-      CellUtil.setTimestamp(this.cell, ts, tsOffset);
-    }
+  /********************* tags *************************************/
+  /**
+   * Util method to iterate through the tags
+   *
+   * @param tags
+   * @param offset
+   * @param length
+   * @return iterator for the tags
+   * @deprecated As of 2.0.0 and will be removed in 3.0.0
+   *             Instead use {@link #tagsIterator(Cell)}
+   */
+  @Deprecated
+  public static Iterator<Tag> tagsIterator(final byte[] tags, final int offset, final int length) {
+    return new Iterator<Tag>() {
+      private int pos = offset;
+      private int endOffset = offset + length - 1;
 
-    @Override
-    public long heapSize() {
-      long sum = HEAP_SIZE_OVERHEAD + CellUtil.estimatedHeapSizeOf(cell);
-      // this.tags is on heap byte[]
-      if (this.tags != null) {
-        sum += ClassSize.sizeOf(this.tags);
+      @Override
+      public boolean hasNext() {
+        return this.pos < endOffset;
       }
-      return sum;
-    }
 
-    @Override
-    public int write(OutputStream out, boolean withTags) throws IOException {
-      int len = ((ExtendedCell) this.cell).write(out, false);
-      if (withTags && this.tags != null) {
-        // Write the tagsLength 2 bytes
-        out.write((byte) (0xff & (this.tags.length >> 8)));
-        out.write((byte) (0xff & this.tags.length));
-        out.write(this.tags);
-        len += KeyValue.TAGS_LENGTH_SIZE + this.tags.length;
+      @Override
+      public Tag next() {
+        if (hasNext()) {
+          int curTagLen = Bytes.readAsInt(tags, this.pos, Tag.TAG_LENGTH_SIZE);
+          Tag tag = new ArrayBackedTag(tags, pos, curTagLen + TAG_LENGTH_SIZE);
+          this.pos += Bytes.SIZEOF_SHORT + curTagLen;
+          return tag;
+        }
+        return null;
       }
-      return len;
-    }
 
-    @Override
-    public int getSerializedSize(boolean withTags) {
-      int len = ((ExtendedCell) this.cell).getSerializedSize(false);
-      if (withTags && this.tags != null) {
-        len += KeyValue.TAGS_LENGTH_SIZE + this.tags.length;
-      }
-      return len;
-    }
-
-    @Override
-    public void write(ByteBuffer buf, int offset) {
-      offset = KeyValueUtil.appendTo(this.cell, buf, offset, false);
-      int tagsLen = this.tags == null ? 0 : this.tags.length;
-      if (tagsLen > 0) {
-        offset = ByteBufferUtils.putAsShort(buf, offset, tagsLen);
-        ByteBufferUtils.copyFromArrayToBuffer(buf, offset, this.tags, 0, tagsLen);
-      }
-    }
-
-    @Override
-    public ExtendedCell deepClone() {
-      Cell clonedBaseCell = ((ExtendedCell) this.cell).deepClone();
-      if (clonedBaseCell instanceof ByteBufferCell) {
-        return new TagRewriteByteBufferCell((ByteBufferCell) clonedBaseCell, this.tags);
+      @Override
+      public void remove() {
+        throw new UnsupportedOperationException();
       }
-      return new TagRewriteCell(clonedBaseCell, this.tags);
-    }
-
-    @Override
-    public ByteBuffer getRowByteBuffer() {
-      return this.cell.getRowByteBuffer();
-    }
-
-    @Override
-    public int getRowPosition() {
-      return this.cell.getRowPosition();
-    }
-
-    @Override
-    public ByteBuffer getFamilyByteBuffer() {
-      return this.cell.getFamilyByteBuffer();
-    }
-
-    @Override
-    public int getFamilyPosition() {
-      return this.cell.getFamilyPosition();
-    }
-
-    @Override
-    public ByteBuffer getQualifierByteBuffer() {
-      return this.cell.getQualifierByteBuffer();
-    }
-
-    @Override
-    public int getQualifierPosition() {
-      return this.cell.getQualifierPosition();
-    }
-
-    @Override
-    public ByteBuffer getValueByteBuffer() {
-      return this.cell.getValueByteBuffer();
-    }
-
-    @Override
-    public int getValuePosition() {
-      return this.cell.getValuePosition();
-    }
-
-    @Override
-    public ByteBuffer getTagsByteBuffer() {
-      return this.tags == null ? HConstants.EMPTY_BYTE_BUFFER : ByteBuffer.wrap(this.tags);
-    }
-
-    @Override
-    public int getTagsPosition() {
-      return 0;
-    }
+    };
   }
 
-  @InterfaceAudience.Private
-  private static class ValueAndTagRewriteCell extends TagRewriteCell {
-
-    protected byte[] value;
-
-    public ValueAndTagRewriteCell(Cell cell, byte[] value, byte[] tags) {
-      super(cell, tags);
-      this.value = value;
-    }
-
-    @Override
-    public byte[] getValueArray() {
-      return this.value;
-    }
-
-    @Override
-    public int getValueOffset() {
-      return 0;
-    }
-
-    @Override
-    public int getValueLength() {
-      return this.value == null ? 0 : this.value.length;
-    }
-
-    @Override
-    public long heapSize() {
-      long sum = ClassSize.REFERENCE + super.heapSize();
-      if (this.value != null) {
-        sum += ClassSize.sizeOf(this.value);
-      }
-      return sum;
-    }
-
-    @Override
-    public int write(OutputStream out, boolean withTags) throws IOException {
-      return write(out, withTags, this.cell, this.value, this.tags);
-    }
-
-    // Made into a static method so as to reuse the logic within ValueAndTagRewriteByteBufferCell
-    static int write(OutputStream out, boolean withTags, Cell cell, byte[] value, byte[] tags)
-        throws IOException {
-      int valLen = value == null ? 0 : value.length;
-      ByteBufferUtils.putInt(out, KeyValueUtil.keyLength(cell));// Key length
-      ByteBufferUtils.putInt(out, valLen);// Value length
-      int len = 2 * Bytes.SIZEOF_INT;
-      len += CellUtil.writeFlatKey(cell, out);// Key
-      if (valLen > 0) out.write(value);// Value
-      len += valLen;
-      if (withTags && tags != null) {
-        // Write the tagsLength 2 bytes
-        out.write((byte) (0xff & (tags.length >> 8)));
-        out.write((byte) (0xff & tags.length));
-        out.write(tags);
-        len += KeyValue.TAGS_LENGTH_SIZE + tags.length;
-      }
-      return len;
-    }
-
-    @Override
-    public int getSerializedSize(boolean withTags) {
-      return super.getSerializedSize(withTags) - this.cell.getValueLength() + this.value.length;
-    }
-
-    @Override
-    public void write(ByteBuffer buf, int offset) {
-      write(buf, offset, this.cell, this.value, this.tags);
-    }
-
-    // Made into a static method so as to reuse the logic within ValueAndTagRewriteByteBufferCell
-    static void write(ByteBuffer buf, int offset, Cell cell, byte[] value, byte[] tags) {
-      offset = ByteBufferUtils.putInt(buf, offset, KeyValueUtil.keyLength(cell));// Key length
-      offset = ByteBufferUtils.putInt(buf, offset, value.length);// Value length
-      offset = KeyValueUtil.appendKeyTo(cell, buf, offset);
-      ByteBufferUtils.copyFromArrayToBuffer(buf, offset, value, 0, value.length);
-      offset += value.length;
-      int tagsLen = tags == null ? 0 : tags.length;
-      if (tagsLen > 0) {
-        offset = ByteBufferUtils.putAsShort(buf, offset, tagsLen);
-        ByteBufferUtils.copyFromArrayToBuffer(buf, offset, tags, 0, tagsLen);
-      }
-    }
-
-    @Override
-    public ExtendedCell deepClone() {
-      Cell clonedBaseCell = ((ExtendedCell) this.cell).deepClone();
-      return new ValueAndTagRewriteCell(clonedBaseCell, this.value, this.tags);
-    }
+  /**
+   * @param cell The Cell
+   * @return Tags in the given Cell as a List
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static List<Tag> getTags(Cell cell) {
+    return PrivateCellUtil.getTags(cell);
   }
 
-  @InterfaceAudience.Private
-  private static class ValueAndTagRewriteByteBufferCell extends TagRewriteByteBufferCell {
-
-    protected byte[] value;
-
-    public ValueAndTagRewriteByteBufferCell(ByteBufferCell cell, byte[] value, byte[] tags) {
-      super(cell, tags);
-      this.value = value;
-    }
-
-    @Override
-    public byte[] getValueArray() {
-      return this.value;
-    }
-
-    @Override
-    public int getValueOffset() {
-      return 0;
-    }
-
-    @Override
-    public int getValueLength() {
-      return this.value == null ? 0 : this.value.length;
-    }
-
-    @Override
-    public ByteBuffer getValueByteBuffer() {
-      return ByteBuffer.wrap(this.value);
-    }
-
-    @Override
-    public int getValuePosition() {
-      return 0;
-    }
-
-    @Override
-    public long heapSize() {
-      long sum = ClassSize.REFERENCE + super.heapSize();
-      if (this.value != null) {
-        sum += ClassSize.sizeOf(this.value);
-      }
-      return sum;
-    }
-
-    @Override
-    public int write(OutputStream out, boolean withTags) throws IOException {
-      return ValueAndTagRewriteCell.write(out, withTags, this.cell, this.value, this.tags);
-    }
-
-    @Override
-    public int getSerializedSize(boolean withTags) {
-      return super.getSerializedSize(withTags) - this.cell.getValueLength() + this.value.length;
-    }
-
-    @Override
-    public void write(ByteBuffer buf, int offset) {
-      ValueAndTagRewriteCell.write(buf, offset, this.cell, this.value, this.tags);
-    }
-
-    @Override
-    public ExtendedCell deepClone() {
-      Cell clonedBaseCell = ((ExtendedCell) this.cell).deepClone();
-      if (clonedBaseCell instanceof ByteBufferCell) {
-        return new ValueAndTagRewriteByteBufferCell((ByteBufferCell) clonedBaseCell, this.value,
-            this.tags);
-      }
-      return new ValueAndTagRewriteCell(clonedBaseCell, this.value, this.tags);
-    }
+  /**
+   * Retrieve Cell's first tag, matching the passed in type
+   *
+   * @param cell The Cell
+   * @param type Type of the Tag to retrieve
+   * @return null if there is no tag of the passed in tag type
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
+   */
+  @Deprecated
+  public static Tag getTag(Cell cell, byte type){
+    return PrivateCellUtil.getTag(cell, type);
   }
 
   /**
-   * @param cellScannerables
-   * @return CellScanner interface over <code>cellIterables</code>
+   * Returns true if the first range start1...end1 overlaps with the second range
+   * start2...end2, assuming the byte arrays represent row keys
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
    */
-  public static CellScanner createCellScanner(
-      final List<? extends CellScannable> cellScannerables) {
-    return new CellScanner() {
-      private final Iterator<? extends CellScannable> iterator = cellScannerables.iterator();
-      private CellScanner cellScanner = null;
-
-      @Override
-      public Cell current() {
-        return this.cellScanner != null? this.cellScanner.current(): null;
-      }
-
-      @Override
-      public boolean advance() throws IOException {
-        while (true) {
-          if (this.cellScanner == null) {
-            if (!this.iterator.hasNext()) return false;
-            this.cellScanner = this.iterator.next().cellScanner();
-          }
-          if (this.cellScanner.advance()) return true;
-          this.cellScanner = null;
-        }
-      }
-    };
+  @Deprecated
+  public static boolean overlappingKeys(final byte[] start1, final byte[] end1,
+      final byte[] start2, final byte[] end2) {
+    return PrivateCellUtil.overlappingKeys(start1, end1, start2, end2);
   }
 
   /**
-   * @param cellIterable
-   * @return CellScanner interface over <code>cellIterable</code>
+   * Sets the given seqId to the cell.
+   * Marked as audience Private as of 1.2.0.
+   * Setting a Cell sequenceid is an internal implementation detail not for general public use.
+   * @param cell
+   * @param seqId
+   * @throws IOException when the passed cell is not of type {@link SettableSequenceId}
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
    */
-  public static CellScanner createCellScanner(final Iterable<Cell> cellIterable) {
-    if (cellIterable == null) return null;
-    return createCellScanner(cellIterable.iterator());
+  @Deprecated
+  public static void setSequenceId(Cell cell, long seqId) throws IOException {
+    PrivateCellUtil.setSequenceId(cell, seqId);
   }
 
   /**
-   * @param cells
-   * @return CellScanner interface over <code>cellIterable</code> or null if <code>cells</code> is
-   * null
+   * Sets the given timestamp to the cell.
+   * @param cell
+   * @param ts
+   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
    */
-  public static CellScanner createCellScanner(final Iterator<Cell> cells) {
-    if (cells == null) return null;
-    return new CellScanner() {
-      private final Iterator<Cell> iterator = cells;
-      private Cell current = null;
-
-      @Override
-      public Cell current() {
-        return this.current;
-      }
-
-      @Override
-      public boolean advance() {
-        boolean hasNext = this.iterator.hasNext();
-        this.current = hasNext? this.iterator.next(): null;
-        return hasNext;
-      }
-    };
+  @Deprecated
+  public static void setTimestamp(Cell cell, long ts) throws IOException {
+    PrivateCellUtil.setTimestamp(cell, ts);
   }
 
   /**
-   * @param cellArray
-   * @return CellScanner interface over <code>cellArray</code>
+   * Sets the given timestamp to the cell.
+   * @param cell
+   * @param ts buffer containing the timestamp value
+   * @param tsOffset offset to the new timestamp
+   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
    */
-  public static CellScanner createCellScanner(final Cell[] cellArray) {
-    return new CellScanner() {
-      private final Cell [] cells = cellArray;
-      private int index = -1;
-
-      @Override
-      public Cell current() {
-        if (cells == null) return null;
-        return (index < 0)? null: this.cells[index];
-      }
-
-      @Override
-      public boolean advance() {
-        if (cells == null) return false;
-        return ++index < this.cells.length;
-      }
-    };
+  @Deprecated
+  public static void setTimestamp(Cell cell, byte[] ts, int tsOffset) throws IOException {
+    PrivateCellUtil.setTimestamp(cell, ts, tsOffset);
   }
 
   /**
-   * Flatten the map of cells out under the CellScanner
-   * @param map Map of Cell Lists; for example, the map of families to Cells that is used
-   * inside Put, etc., keeping Cells organized by family.
-   * @return CellScanner interface over <code>cellIterable</code>
+   * Sets the given timestamp to the cell iff current timestamp is
+   * {@link HConstants#LATEST_TIMESTAMP}.
+   * @param cell
+   * @param ts
+   * @return True if cell timestamp is modified.
+   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
+   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
    */
-  public static CellScanner createCellScanner(final NavigableMap<byte [], List<Cell>> map) {
-    return new CellScanner() {
-      private final Iterator<Entry<byte[], List<Cell>>> entries = map.entrySet().iterator();
-      private Iterator<Cell> currentIterator = null;
-      private Cell currentCell;
-
-      @Override
-      public Cell current() {
-        return this.currentCell;
-      }
-
-      @Override
-      public boolean advance() {
-        while(true) {
-          if (this.currentIterator == null) {
-            if (!this.entries.hasNext()) return false;
-            this.currentIterator = this.entries.next().getValue().iterator();
-          }
-          if (this.currentIterator.hasNext()) {
-            this.currentCell = this.currentIterator.next();
-            return true;
-          }
-          this.currentCell = null;
-          this.currentIterator = null;
-        }
-      }
-    };
+  @Deprecated
+  public static boolean updateLatestStamp(Cell cell, long ts) throws IOException {
+    return PrivateCellUtil.updateLatestStamp(cell, ts);
   }
 
   /**
-   * @param left
-   * @param right
-   * @return True if the rows in <code>left</code> and <code>right</code> Cells match
+   * Sets the given timestamp to the cell iff current timestamp is
+   * {@link HConstants#LATEST_TIMESTAMP}.
+   * @param cell
+   * @param ts buffer containing the timestamp value
+   * @param tsOffset offset to the new timestamp
+   * @return True if cell timestamp is modified.
+   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
    * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0.
-   *             Instead use {@link #matchingRows(Cell, Cell)}
    */
   @Deprecated
-  public static boolean matchingRow(final Cell left, final Cell right) {
-    return matchingRows(left, right);
+  public static boolean updateLatestStamp(Cell cell, byte[] ts, int tsOffset) throws IOException {
+    return PrivateCellUtil.updateLatestStamp(cell, ts, tsOffset);
   }
 
-  public static boolean matchingRow(final Cell left, final byte[] buf) {
-    if (buf == null) {
-      return left.getRowLength() == 0;
-    }
-    return matchingRow(left, buf, 0, buf.length);
-  }
-
-  public static boolean matchingRow(final Cell left, final byte[] buf, final int offset,
-      final int length) {
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getRowByteBuffer(),
-          ((ByteBufferCell) left).getRowPosition(), left.getRowLength(), buf, offset,
-          length);
-    }
-    return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(), buf, offset,
-        length);
-  }
-
-  public static boolean matchingFamily(final Cell left, final Cell right) {
-    byte lfamlength = left.getFamilyLength();
-    byte rfamlength = right.getFamilyLength();
-    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getFamilyByteBuffer(),
-          ((ByteBufferCell) left).getFamilyPosition(), lfamlength,
-          ((ByteBufferCell) right).getFamilyByteBuffer(),
-          ((ByteBufferCell) right).getFamilyPosition(), rfamlength);
-    }
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getFamilyByteBuffer(),
-          ((ByteBufferCell) left).getFamilyPosition(), lfamlength,
-          right.getFamilyArray(), right.getFamilyOffset(), rfamlength);
-    }
-    if (right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) right).getFamilyByteBuffer(),
-          ((ByteBufferCell) right).getFamilyPosition(), rfamlength,
-          left.getFamilyArray(), left.getFamilyOffset(), lfamlength);
-    }
-    return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), lfamlength,
-        right.getFamilyArray(), right.getFamilyOffset(), rfamlength);
-  }
-
-  public static boolean matchingFamily(final Cell left, final byte[] buf) {
-    if (buf == null) {
-      return left.getFamilyLength() == 0;
-    }
-    return matchingFamily(left, buf, 0, buf.length);
-  }
-
-  public static boolean matchingFamily(final Cell left, final byte[] buf, final int offset,
-      final int length) {
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getFamilyByteBuffer(),
-          ((ByteBufferCell) left).getFamilyPosition(), left.getFamilyLength(), buf,
-          offset, length);
-    }
-    return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(), buf,
-        offset, length);
-  }
-
-  public static boolean matchingQualifier(final Cell left, final Cell right) {
-    int lqlength = left.getQualifierLength();
-    int rqlength = right.getQualifierLength();
-    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getQualifierByteBuffer(),
-          ((ByteBufferCell) left).getQualifierPosition(), lqlength,
-          ((ByteBufferCell) right).getQualifierByteBuffer(),
-          ((ByteBufferCell) right).getQualifierPosition(), rqlength);
-    }
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getQualifierByteBuffer(),
-          ((ByteBufferCell) left).getQualifierPosition(), lqlength,
-          right.getQualifierArray(), right.getQualifierOffset(), rqlength);
-    }
-    if (right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) right).getQualifierByteBuffer(),
-          ((ByteBufferCell) right).getQualifierPosition(), rqlength,
-          left.getQualifierArray(), left.getQualifierOffset(), lqlength);
-    }
-    return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(),
-        lqlength, right.getQualifierArray(), right.getQualifierOffset(),
-        rqlength);
-  }
-
-  /**
-   * Finds if the qualifier part of the cell and the KV serialized
-   * byte[] are equal
-   * @param left
-   * @param buf the serialized keyvalue format byte[]
-   * @return true if the qualifier matches, false otherwise
-   */
-  public static boolean matchingQualifier(final Cell left, final byte[] buf) {
-    if (buf == null) {
-      return left.getQualifierLength() == 0;
-    }
-    return matchingQualifier(left, buf, 0, buf.length);
-  }
-
-  /**
-   * Finds if the qualifier part of the cell and the KV serialized
-   * byte[] are equal
-   * @param left
-   * @param buf the serialized keyvalue format byte[]
-   * @param offset the offset of the qualifier in the byte[]
-   * @param length the length of the qualifier in the byte[]
-   * @return true if the qualifier matches, false otherwise
-   */
-  public static boolean matchingQualifier(final Cell left, final byte[] buf, final int offset,
-      final int length) {
-    if (buf == null) {
-      return left.getQualifierLength() == 0;
-    }
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getQualifierByteBuffer(),
-          ((ByteBufferCell) left).getQualifierPosition(), left.getQualifierLength(),
-          buf, offset, length);
-    }
-    return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(),
-        left.getQualifierLength(), buf, offset, length);
-  }
-
-  public static boolean matchingColumn(final Cell left, final byte[] fam, final byte[] qual) {
-    if (!matchingFamily(left, fam))
-      return false;
-    return matchingQualifier(left, qual);
-  }
-
-  public static boolean matchingColumn(final Cell left, final byte[] fam, final int foffset,
-      final int flength, final byte[] qual, final int qoffset, final int qlength) {
-    if (!matchingFamily(left, fam, foffset, flength))
-      return false;
-    return matchingQualifier(left, qual, qoffset, qlength);
-  }
-
-  public static boolean matchingColumn(final Cell left, final Cell right) {
-    if (!matchingFamily(left, right))
-      return false;
-    return matchingQualifier(left, right);
-  }
-
-  public static boolean matchingValue(final Cell left, final Cell right) {
-    return matchingValue(left, right, left.getValueLength(), right.getValueLength());
-  }
-
-  public static boolean matchingValue(final Cell left, final Cell right, int lvlength,
-      int rvlength) {
-    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getValueByteBuffer(),
-        ((ByteBufferCell) left).getValuePosition(), lvlength,
-        ((ByteBufferCell) right).getValueByteBuffer(),
-        ((ByteBufferCell) right).getValuePosition(), rvlength);
-    }
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) left).getValueByteBuffer(),
-        ((ByteBufferCell) left).getValuePosition(), lvlength, right.getValueArray(),
-        right.getValueOffset(), rvlength);
-    }
-    if (right instanceof ByteBufferCell) {
-      return ByteBufferUtils.equals(((ByteBufferCell) right).getValueByteBuffer(),
-        ((ByteBufferCell) right).getValuePosition(), rvlength, left.getValueArray(),
-        left.getValueOffset(), lvlength);
-    }
-    return Bytes.equals(left.getValueArray(), left.getValueOffset(), lvlength,
-      right.getValueArray(), right.getValueOffset(), rvlength);
-  }
-
-  public static boolean matchingValue(final Cell left, final byte[] buf) {
-    if (left instanceof ByteBufferCell) {
-      return ByteBufferUtils.compareTo(((ByteBufferCell) left).getValueByteBuffer(),
-          ((ByteBufferCell) left).getValuePosition(), left.getValueLength(), buf, 0,
-          buf.length) == 0;
-    }
-    return Bytes.equals(left.getValueArray(), left.getValueOffset(), left.getValueLength(), buf, 0,
-        buf.length);
-  }
-
-  /**
-   * @return True if a delete type, a {@link KeyValue.Type#Delete} or a
-   *         {KeyValue.Type#DeleteFamily} or a
-   *         {@link KeyValue.Type#DeleteColumn} KeyValue type.
-   */
-  public static boolean isDelete(final Cell cell) {
-    return isDelete(cell.getTypeByte());
-  }
-
-  /**
-   * @return True if a delete type, a {@link KeyValue.Type#Delete} or a
-   *         {KeyValue.Type#DeleteFamily} or a
-   *         {@link KeyValue.Type#DeleteColumn} KeyValue type.
-   */
-  public static boolean isDelete(final byte type) {
-    return Type.Delete.getCode() <= type
-        && type <= Type.DeleteFamily.getCode();
-  }
-
-  /**
-   * @return True if this cell is a {@link KeyValue.Type#Delete} type.
-   */
-  public static boolean isDeleteType(Cell cell) {
-    return cell.getTypeByte() == Type.Delete.getCode();
-  }
-
-  public static boolean isDeleteFamily(final Cell cell) {
-    return cell.getTypeByte() == Type.DeleteFamily.getCode();
-  }
-
-  public static boolean isDeleteFamilyVersion(final Cell cell) {
-    return cell.getTypeByte() == Type.DeleteFamilyVersion.getCode();
-  }
-
-  public static boolean isDeleteColumns(final Cell cell) {
-    return cell.getTypeByte() == Type.DeleteColumn.getCode();
-  }
-
-  public static boolean isDeleteColumnVersion(final Cell cell) {
-    return cell.getTypeByte() == Type.Delete.getCode();
-  }
-
-  /**
-   *
-   * @return True if this cell is a delete family or column type.
-   */
-  public static boolean isDeleteColumnOrFamily(Cell cell) {
-    int t = cell.getTypeByte();
-    return t == Type.DeleteColumn.getCode() || t == Type.DeleteFamily.getCode();
-  }
-
-  /**
-   * Estimate based on keyvalue's serialization format in the RPC layer. Note that there is an extra
-   * SIZEOF_INT added to the size here that indicates the actual length of the cell for cases where
-   * cell's are serialized in a contiguous format (For eg in RPCs).
-   * @param cell
-   * @return Estimate of the <code>cell</code> size in bytes plus an extra SIZEOF_INT indicating the
-   *         actual cell length.
-   */
-  public static int estimatedSerializedSizeOf(final Cell cell) {
-    if (cell instanceof ExtendedCell) {
-      return ((ExtendedCell) cell).getSerializedSize(true) + Bytes.SIZEOF_INT;
-    }
-
-    return getSumOfCellElementLengths(cell) +
-      // Use the KeyValue's infrastructure size presuming that another implementation would have
-      // same basic cost.
-      KeyValue.ROW_LENGTH_SIZE + KeyValue.FAMILY_LENGTH_SIZE +
-      // Serialization is probably preceded by a length (it is in the KeyValueCodec at least).
-      Bytes.SIZEOF_INT;
-  }
-
-  /**
-   * @param cell
-   * @return Sum of the lengths of all the elements in a Cell; does not count in any infrastructure
-   */
-  private static int getSumOfCellElementLengths(final Cell cell) {
-    return getSumOfCellKeyElementLengths(cell) + cell.getValueLength() + cell.getTagsLength();
-  }
-
-  /**
-   * @param cell
-   * @return Sum of all elements that make up a key; does not include infrastructure, tags or
-   * values.
-   */
-  private static int getSumOfCellKeyElementLengths(final Cell cell) {
-    return cell.getRowLength() + cell.getFamilyLength() +
-    cell.getQualifierLength() +
-    KeyValue.TIMESTAMP_TYPE_SIZE;
-  }
-
-  /**
-   * Calculates the serialized key size. We always serialize in the KeyValue's serialization
-   * format.
-   * @param cell the cell for which the key size has to be calculated.
-   * @return the key size
-   */
-  public static int estimatedSerializedSizeOfKey(final Cell cell) {
-    if (cell instanceof KeyValue) return ((KeyValue)cell).getKeyLength();
-    return cell.getRowLength() + cell.getFamilyLength() +
-        cell.getQualifierLength() +
-        KeyValue.KEY_INFRASTRUCTURE_SIZE;
-  }
-
-  /**
-   * This is an estimate of the heap space occupied by a cell. When the cell is of type
-   * {@link HeapSize} we call {@link HeapSize#heapSize()} so cell can give a correct value. In other
-   * cases we just consider the bytes occupied by the cell components ie. row, CF, qualifier,
-   * timestamp, type, value and tags.
-   * @param cell
-   * @return estimate of the heap space
-   */
-  public static long estimatedHeapSizeOf(final Cell cell) {
-    if (cell instanceof HeapSize) {
-      return ((HeapSize) cell).heapSize();
-    }
-    // TODO: Add sizing of references that hold the row, family, etc., arrays.
-    return estimatedSerializedSizeOf(cell);
-  }
-
-  /********************* tags *************************************/
-  /**
-   * Util method to iterate through the tags
-   *
-   * @param tags
-   * @param offset
-   * @param length
-   * @return iterator for the tags
-   * @deprecated As of 2.0.0 and will be removed in 3.0.0
-   *             Instead use {@link #tagsIterator(Cell)}
-   */
-  @Deprecated
-  public static Iterator<Tag> tagsIterator(final byte[] tags, final int offset, final int length) {
-    return new Iterator<Tag>() {
-      private int pos = offset;
-      private int endOffset = offset + length - 1;
-
-      @Override
-      public boolean hasNext() {
-        return this.pos < endOffset;
-      }
-
-      @Override
-      public Tag next() {
-        if (hasNext()) {
-          int curTagLen = Bytes.readAsInt(tags, this.pos, Tag.TAG_LENGTH_SIZE);
-          Tag tag = new ArrayBackedTag(tags, pos, curTagLen + TAG_LENGTH_SIZE);
-          this.pos += Bytes.SIZEOF_SHORT + curTagLen;
-          return tag;
-        }
-        return null;
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    };
-  }
-
-  private static Iterator<Tag> tagsIterator(final ByteBuffer tags, final int offset,
-      final int length) {
-    return new Iterator<Tag>() {
-      private int pos = offset;
-      private int endOffset = offset + length - 1;
-
-      @Override
-      public boolean hasNext() {
-        return this.pos < endOffset;
-      }
-
-      @Override
-      public Tag next() {
-        if (hasNext()) {
-          int curTagLen = ByteBufferUtils.readAsInt(tags, this.pos, Tag.TAG_LENGTH_SIZE);
-          Tag tag = new ByteBufferTag(tags, pos, curTagLen + Tag.TAG_LENGTH_SIZE);
-          this.pos += Bytes.SIZEOF_SHORT + curTagLen;
-          return tag;
-        }
-        return null;
-      }
-
-      @Override
-      public void remove() {
-        throw new UnsupportedOperationException();
-      }
-    };
-  }
-
-  /**
-   * Util method to iterate through the tags in the given cell.
-   *
-   * @param cell The Cell over which tags iterator is needed.
-   * @return iterator for the tags
-   */
-  public static Iterator<Tag> tagsIterator(final Cell cell) {
-    final int tagsLength = cell.getTagsLength();
-    // Save an object allocation where we can
-    if (tagsLength == 0) {
-      return TagUtil.EMPTY_TAGS_ITR;
-    }
-    if (cell instanceof ByteBufferCell) {
-      return tagsIterator(((ByteBufferCell) cell).getTagsByteBuffer(),
-          ((ByteBufferCell) cell).getTagsPosition(), tagsLength);
-    }
-    return tagsIterator(cell.getTagsArray(), cell.getTagsOffset(), tagsLength);
-  }
-
-  /**
-   * @param cell The Cell
-   * @return Tags in the given Cell as a List
-   */
-  public static List<Tag> getTags(Cell cell) {
-    List<Tag> tags = new ArrayList<>();
-    Iterator<Tag> tagsItr = tagsIterator(cell);
-    while (tagsItr.hasNext()) {
-      tags.add(tagsItr.next());
-    }
-    return tags;
-  }
-
-  /**
-   * Retrieve Cell's first tag, matching the passed in type
-   *
-   * @param cell The Cell
-   * @param type Type of the Tag to retrieve
-   * @return null if there is no tag of the passed in tag type
-   */
-  public static Tag getTag(Cell cell, byte type){
-    boolean bufferBacked = cell instanceof ByteBufferCell;
-    int length = cell.getTagsLength();
-    int offset = bufferBacked? ((ByteBufferCell)cell).getTagsPosition():cell.getTagsOffset();
-    int pos = offset;
-    while (pos < offset + length) {
-      int tagLen;
-      if (bufferBacked) {
-        ByteBuffer tagsBuffer = ((ByteBufferCell)cell).getTagsByteBuffer();
-        tagLen = ByteBufferUtils.readAsInt(tagsBuffer, pos, TAG_LENGTH_SIZE);
-        if (ByteBufferUtils.toByte(tagsBuffer, pos + TAG_LENGTH_SIZE) == type) {
-          return new ByteBufferTag(tagsBuffer, pos, tagLen + TAG_LENGTH_SIZE);
-        }
-      } else {
-        tagLen = Bytes.readAsInt(cell.getTagsArray(), pos, TAG_LENGTH_SIZE);
-        if (cell.getTagsArray()[pos + TAG_LENGTH_SIZE] == type) {
-          return new ArrayBackedTag(cell.getTagsArray(), pos, tagLen + TAG_LENGTH_SIZE);
-        }
-      }
-      pos += TAG_LENGTH_SIZE + tagLen;
-    }
-    return null;
-  }
-
-  /**
-   * Returns true if the first range start1...end1 overlaps with the second range
-   * start2...end2, assuming the byte arrays represent row keys
-   */
-  public static boolean overlappingKeys(final byte[] start1, final byte[] end1,
-      final byte[] start2, final byte[] end2) {
-    return (end2.length == 0 || start1.length == 0 || Bytes.compareTo(start1,
-        end2) < 0)
-        && (end1.length == 0 || start2.length == 0 || Bytes.compareTo(start2,
-            end1) < 0);
-  }
-
-  /**
-   * Sets the given seqId to the cell.
-   * Marked as audience Private as of 1.2.0.
-   * Setting a Cell sequenceid is an internal implementation detail not for general public use.
-   * @param cell
-   * @param seqId
-   * @throws IOException when the passed cell is not of type {@link SettableSequenceId}
-   */
-  @InterfaceAudience.Private
-  public static void setSequenceId(Cell cell, long seqId) throws IOException {
-    if (cell instanceof SettableSequenceId) {
-      ((SettableSequenceId) cell).setSequenceId(seqId);
-    } else {
-      throw new IOException(new UnsupportedOperationException("Cell is not of type "
-          + SettableSequenceId.class.getName()));
-    }
-  }
-
-  /**
-   * Sets the given timestamp to the cell.
-   * @param cell
-   * @param ts
-   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
-   */
-  public static void setTimestamp(Cell cell, long ts) throws IOException {
-    if (cell instanceof SettableTimestamp) {
-      ((SettableTimestamp) cell).setTimestamp(ts);
-    } else {
-      throw new IOException(new UnsupportedOperationException("Cell is not of type "
-          + SettableTimestamp.class.getName()));
-    }
-  }
-
-  /**
-   * Sets the given timestamp to the cell.
-   * @param cell
-   * @param ts buffer containing the timestamp value
-   * @param tsOffset offset to the new timestamp
-   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
-   */
-  public static void setTimestamp(Cell cell, byte[] ts, int tsOffset) throws IOException {
-    if (cell instanceof SettableTimestamp) {
-      ((SettableTimestamp) cell).setTimestamp(ts, tsOffset);
-    } else {
-      throw new IOException(new UnsupportedOperationException("Cell is not of type "
-          + SettableTimestamp.class.getName()));
-    }
-  }
-
-  /**
-   * Sets the given timestamp to the cell iff current timestamp is
-   * {@link HConstants#LATEST_TIMESTAMP}.
-   * @param cell
-   * @param ts
-   * @return True if cell timestamp is modified.
-   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
-   */
-  public static boolean updateLatestStamp(Cell cell, long ts) throws IOException {
-    if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) {
-      setTimestamp(cell, ts);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Sets the given timestamp to the cell iff current timestamp is
-   * {@link HConstants#LATEST_TIMESTAMP}.
-   * @param cell
-   * @param ts buffer containing the timestamp value
-   * @param tsOffset offset to the new timestamp
-   * @return True if cell timestamp is modified.
-   * @throws IOException when the passed cell is not of type {@link SettableTimestamp}
-   */
-  public static boolean updateLatestStamp(Cell cell, byte[] ts, int tsOffset) throws IOException {
-    if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP) {
-      setTimestamp(cell, ts, tsOffset);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Writes the Cell's key part as it would have serialized in a KeyValue. The format is &lt;2 bytes
-   * rk len&gt;&lt;rk&gt;&lt;1 byte cf len&gt;&lt;cf&gt;&lt;qualifier&gt;&lt;8 bytes
-   * timestamp&gt;&lt;1 byte type&gt;
-   * @param cell
-   * @param out
-   * @throws IOException
-   */
-  public static void writeFlatKey(Cell cell, DataOutput out) throws IOException {
-    short rowLen = cell.getRowLength();
-    byte fLen = cell.getFamilyLength();
-    int qLen = cell.getQualifierLength();
-    // Using just one if/else loop instead of every time checking before writing every
-    // component of cell
-    if (cell instanceof ByteBufferCell) {
-      out.writeShort(rowLen);
-      ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getRowByteBuffer(),
-        ((ByteBufferCell) cell).getRowPosition(), rowLen);
-      out.writeByte(fLen);
-      ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getFamilyByteBuffer(),
-        ((ByteBufferCell) cell).getFamilyPosition(), fLen);
-      ByteBufferUtils.copyBufferToStream(out, ((ByteBufferCell) cell).getQualifierByteBuffer(),
-        ((ByteBufferCell) cell).getQualifierPosition(), qLen);
-    } else {
-      out.writeShort(rowLen);
-      out.write(cell.getRowArray(), cell.getRowOffset(), rowLen);
-      out.writeByte(fLen);
-      out.write(cell.getFamilyArray(), cell.getFamilyOffset(), fLen);
-      out.write(cell.getQualifierArray(), cell.getQualifierOffset(), qLen);
-    }
-    out.writeLong(cell.getTimestamp());
-    out.writeByte(cell.getTypeByte());
-  }
-
-  /**
-   * Deep clones the given cell if the cell supports deep cloning
- 

<TRUNCATED>

Mime
View raw message