http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparatorImpl.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparatorImpl.java 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparatorImpl.java
new file mode 100644
index 0000000..264984a
--- /dev/null
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparatorImpl.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.KeyValue.Type;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.apache.yetus.audience.InterfaceStability;
+import org.apache.hadoop.hbase.util.ByteBufferUtils;
+import org.apache.hadoop.hbase.util.Bytes;
+
+import org.apache.hadoop.hbase.shaded.com.google.common.primitives.Longs;
+
+/**
+ * Compare two HBase cells.  Do not use this method comparing 
<code>-ROOT-</code> or
+ * <code>hbase:meta</code> cells.  Cells from these tables need a specialized 
comparator, one that
+ * takes account of the special formatting of the row where we have commas to 
delimit table from
+ * regionname, from row.  See KeyValue for how it has a special comparator to 
do hbase:meta cells
+ * and yet another for -ROOT-.
+ * While using this comparator for {{@link #compareRows(Cell, Cell)} et al, 
the hbase:meta cells
+ * format should be taken into consideration, for which the instance of this 
comparator
+ * should be used.  In all other cases the static APIs in this comparator 
would be enough
+ */
+@edu.umd.cs.findbugs.annotations.SuppressWarnings(
+    value="UNKNOWN",
+    justification="Findbugs doesn't like the way we are negating the result of 
a compare in below")
+@InterfaceAudience.Private
+@InterfaceStability.Evolving
+public class CellComparatorImpl implements CellComparator {
+  static final Log LOG = LogFactory.getLog(CellComparatorImpl.class);
+  /**
+   * Comparator for plain key/values; i.e. non-catalog table key/values. Works 
on Key portion
+   * of KeyValue only.
+   */
+  public static final CellComparatorImpl COMPARATOR = new CellComparatorImpl();
+  /**
+   * A {@link CellComparatorImpl} for <code>hbase:meta</code> catalog table
+   * {@link KeyValue}s.
+   */
+  public static final CellComparatorImpl META_COMPARATOR = new 
MetaCellComparator();
+
+  @Override
+  public int compare(Cell a, Cell b) {
+    return compare(a, b, false);
+  }
+
+  /**
+   * Compare cells.
+   * @param a
+   * @param b
+   * @param ignoreSequenceid True if we are to compare the key portion only 
and ignore
+   * the sequenceid. Set to false to compare key and consider sequenceid.
+   * @return 0 if equal, -1 if a &lt; b, and +1 if a &gt; b.
+   */
+  public final int compare(final Cell a, final Cell b, boolean 
ignoreSequenceid) {
+    // row
+    int c = compareRows(a, b);
+    if (c != 0) return c;
+
+    c = compareWithoutRow(a, b);
+    if(c != 0) return c;
+
+    if (!ignoreSequenceid) {
+      // Negate following comparisons so later edits show up first
+      // mvccVersion: later sorts first
+      return Longs.compare(b.getSequenceId(), a.getSequenceId());
+    } else {
+      return c;
+    }
+  }
+
+  /**
+   * Compares the family and qualifier part of the cell
+   * @param left the left cell
+   * @param right the right cell
+   * @return 0 if both cells are equal, 1 if left cell is bigger than right, 
-1 otherwise
+   */
+  public final int compareColumns(final Cell left, final Cell right) {
+    int diff = compareFamilies(left, right);
+    if (diff != 0) {
+      return diff;
+    }
+    return compareQualifiers(left, right);
+  }
+
+  /**
+   * Compare the families of left and right cell
+   * @param left
+   * @param right
+   * @return 0 if both cells are equal, 1 if left cell is bigger than right, 
-1 otherwise
+   */
+  @Override
+  public final int compareFamilies(Cell left, Cell right) {
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getFamilyByteBuffer(),
+          ((ByteBufferCell) left).getFamilyPosition(), left.getFamilyLength(),
+          ((ByteBufferCell) right).getFamilyByteBuffer(),
+          ((ByteBufferCell) right).getFamilyPosition(), 
right.getFamilyLength());
+    }
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getFamilyByteBuffer(),
+          ((ByteBufferCell) left).getFamilyPosition(), left.getFamilyLength(),
+          right.getFamilyArray(), right.getFamilyOffset(), 
right.getFamilyLength());
+    }
+    if (right instanceof ByteBufferCell) {
+      // Notice how we flip the order of the compare here. We used to negate 
the return value but
+      // see what FindBugs says
+      // 
http://findbugs.sourceforge.net/bugDescriptions.html#RV_NEGATING_RESULT_OF_COMPARETO
+      // It suggest flipping the order to get same effect and 'safer'.
+      return ByteBufferUtils.compareTo(
+          left.getFamilyArray(), left.getFamilyOffset(), 
left.getFamilyLength(),
+          ((ByteBufferCell)right).getFamilyByteBuffer(),
+          ((ByteBufferCell)right).getFamilyPosition(), 
right.getFamilyLength());
+    }
+    return Bytes.compareTo(left.getFamilyArray(), left.getFamilyOffset(), 
left.getFamilyLength(),
+        right.getFamilyArray(), right.getFamilyOffset(), 
right.getFamilyLength());
+  }
+
+  /**
+   * Compare the qualifiers part of the left and right cells.
+   * @param left
+   * @param right
+   * @return 0 if both cells are equal, 1 if left cell is bigger than right, 
-1 otherwise
+   */
+  @Override
+  public final int compareQualifiers(Cell left, Cell right) {
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils
+          .compareTo(((ByteBufferCell) left).getQualifierByteBuffer(),
+              ((ByteBufferCell) left).getQualifierPosition(),
+              left.getQualifierLength(), ((ByteBufferCell) 
right).getQualifierByteBuffer(),
+              ((ByteBufferCell) right).getQualifierPosition(),
+              right.getQualifierLength());
+    }
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getQualifierByteBuffer(),
+          ((ByteBufferCell) left).getQualifierPosition(), 
left.getQualifierLength(),
+          right.getQualifierArray(), right.getQualifierOffset(), 
right.getQualifierLength());
+    }
+    if (right instanceof ByteBufferCell) {
+      // Notice how we flip the order of the compare here. We used to negate 
the return value but
+      // see what FindBugs says
+      // 
http://findbugs.sourceforge.net/bugDescriptions.html#RV_NEGATING_RESULT_OF_COMPARETO
+      // It suggest flipping the order to get same effect and 'safer'.
+      return ByteBufferUtils.compareTo(left.getQualifierArray(),
+          left.getQualifierOffset(), left.getQualifierLength(),
+          ((ByteBufferCell)right).getQualifierByteBuffer(),
+          ((ByteBufferCell)right).getQualifierPosition(), 
right.getQualifierLength());
+    }
+    return Bytes.compareTo(left.getQualifierArray(), left.getQualifierOffset(),
+        left.getQualifierLength(), right.getQualifierArray(), 
right.getQualifierOffset(),
+        right.getQualifierLength());
+  }
+
+  /**
+   * Compares the rows of the left and right cell.
+   * For the hbase:meta case this method is overridden such that it can handle 
hbase:meta cells.
+   * The caller should ensure using the appropriate comparator for hbase:meta.
+   * @param left
+   * @param right
+   * @return 0 if both cells are equal, 1 if left cell is bigger than right, 
-1 otherwise
+   */
+  @Override
+  public int compareRows(final Cell left, final Cell right) {
+    // left and right can be exactly the same at the beginning of a row
+    if (left == right) {
+      return 0;
+    }
+    if (left instanceof ByteBufferCell && right instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getRowByteBuffer(),
+          ((ByteBufferCell) left).getRowPosition(), left.getRowLength(),
+          ((ByteBufferCell) right).getRowByteBuffer(),
+          ((ByteBufferCell) right).getRowPosition(), right.getRowLength());
+    }
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getRowByteBuffer(),
+          ((ByteBufferCell) left).getRowPosition(), left.getRowLength(),
+          right.getRowArray(), right.getRowOffset(), right.getRowLength());
+    }
+    if (right instanceof ByteBufferCell) {
+      // Notice how we flip the order of the compare here. We used to negate 
the return value but
+      // see what FindBugs says
+      // 
http://findbugs.sourceforge.net/bugDescriptions.html#RV_NEGATING_RESULT_OF_COMPARETO
+      // It suggest flipping the order to get same effect and 'safer'.
+      return ByteBufferUtils.compareTo(left.getRowArray(), 
left.getRowOffset(), left.getRowLength(),
+          ((ByteBufferCell)right).getRowByteBuffer(),
+          ((ByteBufferCell)right).getRowPosition(), right.getRowLength());
+    }
+    return Bytes.compareTo(left.getRowArray(), left.getRowOffset(), 
left.getRowLength(),
+        right.getRowArray(), right.getRowOffset(), right.getRowLength());
+  }
+
+  /**
+   * Compares the row part of the cell with a simple plain byte[] like the
+   * stopRow in Scan. This should be used with context where for hbase:meta
+   * cells the {{@link #META_COMPARATOR} should be used
+   *
+   * @param left
+   *          the cell to be compared
+   * @param right
+   *          the kv serialized byte[] to be compared with
+   * @param roffset
+   *          the offset in the byte[]
+   * @param rlength
+   *          the length in the byte[]
+   * @return 0 if both cell and the byte[] are equal, 1 if the cell is bigger
+   *         than byte[], -1 otherwise
+   */
+  @Override
+  public int compareRows(Cell left, byte[] right, int roffset, int rlength) {
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getRowByteBuffer(),
+          ((ByteBufferCell) left).getRowPosition(), left.getRowLength(), right,
+          roffset, rlength);
+    }
+    return Bytes.compareTo(left.getRowArray(), left.getRowOffset(), 
left.getRowLength(), right,
+        roffset, rlength);
+  }
+
+  @Override
+  public final int compareWithoutRow(final Cell left, final Cell right) {
+    // If the column is not specified, the "minimum" key type appears the
+    // latest in the sorted order, regardless of the timestamp. This is used
+    // for specifying the last key/value in a given row, because there is no
+    // "lexicographically last column" (it would be infinitely long). The
+    // "maximum" key type does not need this behavior.
+    // Copied from KeyValue. This is bad in that we can't do memcmp w/ special 
rules like this.
+    int lFamLength = left.getFamilyLength();
+    int rFamLength = right.getFamilyLength();
+    int lQualLength = left.getQualifierLength();
+    int rQualLength = right.getQualifierLength();
+    if (lFamLength + lQualLength == 0
+          && left.getTypeByte() == Type.Minimum.getCode()) {
+      // left is "bigger", i.e. it appears later in the sorted order
+      return 1;
+    }
+    if (rFamLength + rQualLength == 0
+        && right.getTypeByte() == Type.Minimum.getCode()) {
+      return -1;
+    }
+    if (lFamLength != rFamLength) {
+      // comparing column family is enough.
+      return compareFamilies(left, right);
+    }
+    // Compare cf:qualifier
+    int diff = compareColumns(left, right);
+    if (diff != 0) return diff;
+
+    diff = compareTimestamps(left, right);
+    if (diff != 0) return diff;
+
+    // Compare types. Let the delete types sort ahead of puts; i.e. types
+    // of higher numbers sort before those of lesser numbers. Maximum (255)
+    // appears ahead of everything, and minimum (0) appears after
+    // everything.
+    return (0xff & right.getTypeByte()) - (0xff & left.getTypeByte());
+  }
+
+  /**
+   * Compares cell's timestamps in DESCENDING order.
+   * The below older timestamps sorting ahead of newer timestamps looks
+   * wrong but it is intentional. This way, newer timestamps are first
+   * found when we iterate over a memstore and newer versions are the
+   * first we trip over when reading from a store file.
+   * @return 1 if left's timestamp &lt; right's timestamp
+   *         -1 if left's timestamp &gt; right's timestamp
+   *         0 if both timestamps are equal
+   */
+  @Override
+  public int compareTimestamps(final Cell left, final Cell right) {
+    return compareTimestamps(left.getTimestamp(), right.getTimestamp());
+  }
+
+
+  /**
+   * Compares timestamps in DESCENDING order.
+   * The below older timestamps sorting ahead of newer timestamps looks
+   * wrong but it is intentional. This way, newer timestamps are first
+   * found when we iterate over a memstore and newer versions are the
+   * first we trip over when reading from a store file.
+   * @return 1 if left timestamp &lt; right timestamp
+   *         -1 if left timestamp &gt; right timestamp
+   *         0 if both timestamps are equal
+   */
+  @Override
+  public int compareTimestamps(final long ltimestamp, final long rtimestamp) {
+    if (ltimestamp < rtimestamp) {
+      return 1;
+    } else if (ltimestamp > rtimestamp) {
+      return -1;
+    }
+    return 0;
+  }
+
+  /**
+   * A {@link CellComparatorImpl} for <code>hbase:meta</code> catalog table
+   * {@link KeyValue}s.
+   */
+  public static class MetaCellComparator extends CellComparatorImpl {
+
+    @Override
+    public int compareRows(final Cell left, final Cell right) {
+      return compareRows(left.getRowArray(), left.getRowOffset(), 
left.getRowLength(),
+          right.getRowArray(), right.getRowOffset(), right.getRowLength());
+    }
+
+    @Override
+    public int compareRows(Cell left, byte[] right, int roffset, int rlength) {
+      return compareRows(left.getRowArray(), left.getRowOffset(), 
left.getRowLength(), right,
+          roffset, rlength);
+    }
+
+    private int compareRows(byte[] left, int loffset, int llength, byte[] 
right, int roffset,
+        int rlength) {
+      int leftDelimiter = Bytes.searchDelimiterIndex(left, loffset, llength, 
HConstants.DELIMITER);
+      int rightDelimiter = Bytes
+          .searchDelimiterIndex(right, roffset, rlength, HConstants.DELIMITER);
+      // Compare up to the delimiter
+      int lpart = (leftDelimiter < 0 ? llength : leftDelimiter - loffset);
+      int rpart = (rightDelimiter < 0 ? rlength : rightDelimiter - roffset);
+      int result = Bytes.compareTo(left, loffset, lpart, right, roffset, 
rpart);
+      if (result != 0) {
+        return result;
+      } else {
+        if (leftDelimiter < 0 && rightDelimiter >= 0) {
+          return -1;
+        } else if (rightDelimiter < 0 && leftDelimiter >= 0) {
+          return 1;
+        } else if (leftDelimiter < 0 && rightDelimiter < 0) {
+          return 0;
+        }
+      }
+      // Compare middle bit of the row.
+      // Move past delimiter
+      leftDelimiter++;
+      rightDelimiter++;
+      int leftFarDelimiter = Bytes.searchDelimiterIndexInReverse(left, 
leftDelimiter, llength
+          - (leftDelimiter - loffset), HConstants.DELIMITER);
+      int rightFarDelimiter = Bytes.searchDelimiterIndexInReverse(right, 
rightDelimiter, rlength
+          - (rightDelimiter - roffset), HConstants.DELIMITER);
+      // Now compare middlesection of row.
+      lpart = (leftFarDelimiter < 0 ? llength + loffset : leftFarDelimiter) - 
leftDelimiter;
+      rpart = (rightFarDelimiter < 0 ? rlength + roffset : rightFarDelimiter) 
- rightDelimiter;
+      result = Bytes.compareTo(left, leftDelimiter, lpart, right, 
rightDelimiter, rpart);
+      if (result != 0) {
+        return result;
+      } else {
+        if (leftDelimiter < 0 && rightDelimiter >= 0) {
+          return -1;
+        } else if (rightDelimiter < 0 && leftDelimiter >= 0) {
+          return 1;
+        } else if (leftDelimiter < 0 && rightDelimiter < 0) {
+          return 0;
+        }
+      }
+      // Compare last part of row, the rowid.
+      leftFarDelimiter++;
+      rightFarDelimiter++;
+      result = Bytes.compareTo(left, leftFarDelimiter, llength - 
(leftFarDelimiter - loffset),
+          right, rightFarDelimiter, rlength - (rightFarDelimiter - roffset));
+      return result;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/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 58ebc33..12f6a30 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
@@ -38,8 +38,12 @@ 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;
@@ -2241,7 +2245,7 @@ public final class CellUtil {
   }
 
   public static boolean matchingTimestamp(Cell a, Cell b) {
-    return CellComparator.compareTimestamps(a.getTimestamp(), 
b.getTimestamp()) == 0;
+    return CellComparatorImpl.COMPARATOR.compareTimestamps(a.getTimestamp(), 
b.getTimestamp()) == 0;
   }
 
   public static boolean matchingType(Cell a, Cell b) {
@@ -2599,6 +2603,306 @@ public final class CellUtil {
     }
   }
 
+  /**
+   * Compares only the key portion of a cell. It does not include the sequence 
id/mvcc of the cell
+   * @param left
+   * @param right
+   * @return an int greater than 0 if left &gt; than right lesser than 0 if 
left &lt; than right
+   *         equal to 0 if left is equal to right
+   */
+  public static final int compareKeyIgnoresMvcc(CellComparator comparator, 
Cell left, Cell right) {
+    return ((CellComparatorImpl) comparator).compare(left, right, true);
+  }
+
+  /**
+   * Used to compare two cells based on the column hint provided. This is 
specifically
+   * used when we need to optimize the seeks based on the next indexed key. 
This is an
+   * advanced usage API specifically needed for some optimizations.
+   * @param nextIndexedCell the next indexed cell
+   * @param currentCell the cell to be compared
+   * @param foff the family offset of the currentCell
+   * @param flen the family length of the currentCell
+   * @param colHint the column hint provided - could be null
+   * @param coff the offset of the column hint if provided, if not offset of 
the currentCell's
+   * qualifier
+   * @param clen the length of the column hint if provided, if not length of 
the currentCell's
+   * qualifier
+   * @param ts the timestamp to be seeked
+   * @param type the type to be seeked
+   * @return an int based on the given column hint
+   * TODO : To be moved out of here because this is a special API used in scan
+   * optimization.
+   */
+  // compare a key against row/fam/qual/ts/type
+  @InterfaceAudience.Private
+  public static final int compareKeyBasedOnColHint(CellComparator comparator, 
Cell nextIndexedCell,
+      Cell currentCell, int foff, int flen, byte[] colHint, int coff, int 
clen, long ts,
+      byte type) {
+    int compare = comparator.compareRows(nextIndexedCell, currentCell);
+    if (compare != 0) {
+      return compare;
+    }
+    // If the column is not specified, the "minimum" key type appears the
+    // latest in the sorted order, regardless of the timestamp. This is used
+    // for specifying the last key/value in a given row, because there is no
+    // "lexicographically last column" (it would be infinitely long). The
+    // "maximum" key type does not need this behavior.
+    if (nextIndexedCell.getFamilyLength() + 
nextIndexedCell.getQualifierLength() == 0
+        && nextIndexedCell.getTypeByte() == Type.Minimum.getCode()) {
+      // left is "bigger", i.e. it appears later in the sorted order
+      return 1;
+    }
+    if (flen + clen == 0 && type == Type.Minimum.getCode()) {
+      return -1;
+    }
+
+    compare = comparator.compareFamilies(nextIndexedCell, currentCell);
+    if (compare != 0) {
+      return compare;
+    }
+    if (colHint == null) {
+      compare = comparator.compareQualifiers(nextIndexedCell, currentCell);
+    } else {
+      compare = compareQualifiers(nextIndexedCell, colHint, coff, clen);
+    }
+    if (compare != 0) {
+      return compare;
+    }
+    // Next compare timestamps.
+    compare = comparator.compareTimestamps(nextIndexedCell.getTimestamp(), ts);
+    if (compare != 0) {
+      return compare;
+    }
+
+    // Compare types. Let the delete types sort ahead of puts; i.e. types
+    // of higher numbers sort before those of lesser numbers. Maximum (255)
+    // appears ahead of everything, and minimum (0) appears after
+    // everything.
+    return (0xff & type) - (0xff & nextIndexedCell.getTypeByte());
+  }
+
+  /**
+   * Compares the cell's qualifier with the given byte[]
+   * @param left the cell for which the qualifier has to be compared
+   * @param right the byte[] having the qualifier
+   * @param rOffset the offset of the qualifier
+   * @param rLength the length of the qualifier
+   * @return greater than 0 if left cell's qualifier is bigger than byte[], 
lesser than 0 if left
+   *         cell's qualifier is lesser than byte[] and 0 otherwise
+   */
+  public final static int compareQualifiers(Cell left, byte[] right, int 
rOffset, int rLength) {
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getQualifierByteBuffer(),
+          ((ByteBufferCell) left).getQualifierPosition(), 
left.getQualifierLength(),
+          right, rOffset, rLength);
+    }
+    return Bytes.compareTo(left.getQualifierArray(), left.getQualifierOffset(),
+        left.getQualifierLength(), right, rOffset, rLength);
+  }
+
+  /**
+   * Compare cell's row against given comparator
+   * @param cell
+   * @param comparator
+   * @return result comparing cell's row
+   */
+  @InterfaceAudience.Private
+  public static int compareRow(Cell cell, ByteArrayComparable comparator) {
+    if (cell instanceof ByteBufferCell) {
+      return comparator.compareTo(((ByteBufferCell) cell).getRowByteBuffer(),
+        ((ByteBufferCell) cell).getRowPosition(), cell.getRowLength());
+    }
+    return comparator.compareTo(cell.getRowArray(), cell.getRowOffset(), 
cell.getRowLength());
+  }
+
+  /**
+   * Compare cell's column family against given comparator
+   * @param cell
+   * @param comparator
+   * @return result comparing cell's column family
+   */
+  @InterfaceAudience.Private
+  public static int compareFamily(Cell cell, ByteArrayComparable comparator) {
+    if (cell instanceof ByteBufferCell) {
+      return comparator.compareTo(((ByteBufferCell) 
cell).getFamilyByteBuffer(),
+        ((ByteBufferCell) cell).getFamilyPosition(), cell.getFamilyLength());
+    }
+    return comparator.compareTo(cell.getFamilyArray(), cell.getFamilyOffset(),
+      cell.getFamilyLength());
+  }
+
+  /**
+   * Compare cell's qualifier against given comparator
+   * @param cell
+   * @param comparator
+   * @return result comparing cell's qualifier
+   */
+  @InterfaceAudience.Private
+  public static int compareQualifier(Cell cell, ByteArrayComparable 
comparator) {
+    if (cell instanceof ByteBufferCell) {
+      return comparator.compareTo(((ByteBufferCell) 
cell).getQualifierByteBuffer(),
+        ((ByteBufferCell) cell).getQualifierPosition(), 
cell.getQualifierLength());
+    }
+    return comparator.compareTo(cell.getQualifierArray(), 
cell.getQualifierOffset(),
+      cell.getQualifierLength());
+  }
+
+  /**
+   * Compare cell's value against given comparator
+   * @param cell
+   * @param comparator
+   * @return result comparing cell's value
+   */
+  @InterfaceAudience.Private
+  public static int compareValue(Cell cell, ByteArrayComparable comparator) {
+    if (cell instanceof ByteBufferCell) {
+      return comparator.compareTo(((ByteBufferCell) cell).getValueByteBuffer(),
+        ((ByteBufferCell) cell).getValuePosition(), cell.getValueLength());
+    }
+    return comparator.compareTo(cell.getValueArray(), cell.getValueOffset(), 
cell.getValueLength());
+  }
+
+  /**
+   * Used when a cell needs to be compared with a key byte[] such as cases of
+   * finding the index from the index block, bloom keys from the bloom blocks
+   * This byte[] is expected to be serialized in the KeyValue serialization 
format
+   * If the KeyValue (Cell's) serialization format changes this method cannot 
be used.
+   * @param comparator the cell comparator
+   * @param left the cell to be compared
+   * @param key the serialized key part of a KeyValue
+   * @param offset the offset in the key byte[]
+   * @param length the length of the key byte[]
+   * @return an int greater than 0 if left is greater than right
+   *                lesser than 0 if left is lesser than right
+   *                equal to 0 if left is equal to right
+   */
+  @VisibleForTesting
+  public static final int compare(CellComparator comparator, Cell left, byte[] 
key, int offset,
+      int length) {
+    // row
+    short rrowlength = Bytes.toShort(key, offset);
+    int c = comparator.compareRows(left, key, offset + Bytes.SIZEOF_SHORT, 
rrowlength);
+    if (c != 0) return c;
+
+    // Compare the rest of the two KVs without making any assumptions about
+    // the common prefix. This function will not compare rows anyway, so we
+    // don't need to tell it that the common prefix includes the row.
+    return compareWithoutRow(comparator, left, key, offset, length, 
rrowlength);
+  }
+
+  /**
+   * Compare columnFamily, qualifier, timestamp, and key type (everything
+   * except the row). This method is used both in the normal comparator and
+   * the "same-prefix" comparator. Note that we are assuming that row portions
+   * of both KVs have already been parsed and found identical, and we don't
+   * validate that assumption here.
+   * @param commonPrefix
+   *          the length of the common prefix of the two key-values being
+   *          compared, including row length and row
+   */
+  private static final int compareWithoutRow(CellComparator comparator, Cell 
left,
+      byte[] right, int roffset, int rlength, short rowlength) {
+    /***
+     * KeyValue Format and commonLength:
+     * |_keyLen_|_valLen_|_rowLen_|_rowKey_|_famiLen_|_fami_|_Quali_|....
+     * ------------------|-------commonLength--------|--------------
+     */
+    int commonLength = KeyValue.ROW_LENGTH_SIZE + KeyValue.FAMILY_LENGTH_SIZE 
+ rowlength;
+
+    // commonLength + TIMESTAMP_TYPE_SIZE
+    int commonLengthWithTSAndType = KeyValue.TIMESTAMP_TYPE_SIZE + 
commonLength;
+    // ColumnFamily + Qualifier length.
+    int lcolumnlength = left.getFamilyLength() + left.getQualifierLength();
+    int rcolumnlength = rlength - commonLengthWithTSAndType;
+
+    byte ltype = left.getTypeByte();
+    byte rtype = right[roffset + (rlength - 1)];
+
+    // If the column is not specified, the "minimum" key type appears the
+    // latest in the sorted order, regardless of the timestamp. This is used
+    // for specifying the last key/value in a given row, because there is no
+    // "lexicographically last column" (it would be infinitely long). The
+    // "maximum" key type does not need this behavior.
+    if (lcolumnlength == 0 && ltype == Type.Minimum.getCode()) {
+      // left is "bigger", i.e. it appears later in the sorted order
+      return 1;
+    }
+    if (rcolumnlength == 0 && rtype == Type.Minimum.getCode()) {
+      return -1;
+    }
+
+    int rfamilyoffset = commonLength + roffset;
+
+    // Column family length.
+    int lfamilylength = left.getFamilyLength();
+    int rfamilylength = right[rfamilyoffset - 1];
+    // If left family size is not equal to right family size, we need not
+    // compare the qualifiers.
+    boolean sameFamilySize = (lfamilylength == rfamilylength);
+    if (!sameFamilySize) {
+      // comparing column family is enough.
+      return compareFamilies(left, right, rfamilyoffset, rfamilylength);
+    }
+    // Compare family & qualifier together.
+    // Families are same. Compare on qualifiers.
+    int comparison = compareColumns(left, right, rfamilyoffset, rfamilylength,
+      rfamilyoffset + rfamilylength, (rcolumnlength - rfamilylength));
+    if (comparison != 0) {
+      return comparison;
+    }
+
+    // //
+    // Next compare timestamps.
+    long rtimestamp = Bytes.toLong(right, roffset + (rlength - 
KeyValue.TIMESTAMP_TYPE_SIZE));
+    int compare = comparator.compareTimestamps(left.getTimestamp(), 
rtimestamp);
+    if (compare != 0) {
+      return compare;
+    }
+
+    // Compare types. Let the delete types sort ahead of puts; i.e. types
+    // of higher numbers sort before those of lesser numbers. Maximum (255)
+    // appears ahead of everything, and minimum (0) appears after
+    // everything.
+    return (0xff & rtype) - (0xff & ltype);
+  }
+
+  /**
+   * Compares the cell's family with the given byte[]
+   * @param left the cell for which the family has to be compared
+   * @param right the byte[] having the family
+   * @param roffset the offset of the family
+   * @param rlength the length of the family
+   * @return greater than 0 if left cell's family is bigger than byte[], 
lesser than 0 if left
+   *         cell's family is lesser than byte[] and 0 otherwise
+   */
+  public final static int compareFamilies(Cell left, byte[] right, int 
roffset, int rlength) {
+    if (left instanceof ByteBufferCell) {
+      return ByteBufferUtils.compareTo(((ByteBufferCell) 
left).getFamilyByteBuffer(),
+        ((ByteBufferCell) left).getFamilyPosition(), left.getFamilyLength(), 
right, roffset,
+        rlength);
+    }
+    return Bytes.compareTo(left.getFamilyArray(), left.getFamilyOffset(), 
left.getFamilyLength(),
+      right, roffset, rlength);
+  }
+
+  /**
+   * Compares the cell's column (family and qualifier) with the given byte[]
+   * @param left the cell for which the column has to be compared
+   * @param right the byte[] having the column
+   * @param rfoffset the offset of the family
+   * @param rflength the length of the family
+   * @param rqoffset the offset of the qualifier
+   * @param rqlength the length of the qualifier
+   * @return greater than 0 if left cell's column is bigger than byte[], 
lesser than 0 if left
+   *         cell's column is lesser than byte[] and 0 otherwise
+   */
+  public final static int compareColumns(Cell left, byte[] right, int 
rfoffset, int rflength,
+      int rqoffset, int rqlength) {
+    int diff = compareFamilies(left, right, rfoffset, rflength);
+    if (diff != 0) return diff;
+    return compareQualifiers(left, right, rqoffset, rqlength);
+  }
+
   @InterfaceAudience.Private
   /**
    * These cells are used in reseeks/seeks to improve the read performance.

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
index 66ff72a..6154045 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
@@ -28,7 +28,6 @@ import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -97,14 +96,14 @@ public class KeyValue implements ExtendedCell {
   /**
    * Comparator for plain key/values; i.e. non-catalog table key/values. Works 
on Key portion
    * of KeyValue only.
-   * @deprecated Use {@link CellComparator#COMPARATOR} instead. Deprecated for 
hbase 2.0, remove for hbase 3.0.
+   * @deprecated Use {@link CellComparatorImpl#COMPARATOR} instead. Deprecated 
for hbase 2.0, remove for hbase 3.0.
    */
   @Deprecated
   public static final KVComparator COMPARATOR = new KVComparator();
   /**
    * A {@link KVComparator} for <code>hbase:meta</code> catalog table
    * {@link KeyValue}s.
-   * @deprecated Use {@link CellComparator#META_COMPARATOR} instead. 
Deprecated for hbase 2.0, remove for hbase 3.0.
+   * @deprecated Use {@link CellComparatorImpl#META_COMPARATOR} instead. 
Deprecated for hbase 2.0, remove for hbase 3.0.
    */
   @Deprecated
   public static final KVComparator META_COMPARATOR = new MetaComparator();
@@ -1608,7 +1607,7 @@ public class KeyValue implements ExtendedCell {
   /**
    * A {@link KVComparator} for <code>hbase:meta</code> catalog table
    * {@link KeyValue}s.
-   * @deprecated : {@link CellComparator#META_COMPARATOR} to be used. 
Deprecated for hbase 2.0, remove for hbase 3.0.
+   * @deprecated : {@link CellComparatorImpl#META_COMPARATOR} to be used. 
Deprecated for hbase 2.0, remove for hbase 3.0.
    */
   @Deprecated
   public static class MetaComparator extends KVComparator {
@@ -1618,7 +1617,7 @@ public class KeyValue implements ExtendedCell {
      */
     @Override
     public int compare(final Cell left, final Cell right) {
-      return CellComparator.META_COMPARATOR.compareKeyIgnoresMvcc(left, right);
+      return 
CellUtil.compareKeyIgnoresMvcc(CellComparatorImpl.META_COMPARATOR, left, right);
     }
 
     @Override
@@ -1723,7 +1722,7 @@ public class KeyValue implements ExtendedCell {
    * Compare KeyValues.  When we compare KeyValues, we only compare the Key
    * portion.  This means two KeyValues with same Key but different Values are
    * considered the same as far as this Comparator is concerned.
-   * @deprecated : Use {@link CellComparator}. Deprecated for hbase 2.0, 
remove for hbase 3.0.
+   * @deprecated : Use {@link CellComparatorImpl}. Deprecated for hbase 2.0, 
remove for hbase 3.0.
    */
   @Deprecated
   public static class KVComparator implements RawComparator<Cell>, 
SamePrefixComparator<byte[]> {
@@ -1751,7 +1750,7 @@ public class KeyValue implements ExtendedCell {
      * @return 0 if equal, &lt;0 if left smaller, &gt;0 if right smaller
      */
     protected int compareRowKey(final Cell left, final Cell right) {
-      return CellComparator.COMPARATOR.compareRows(left, right);
+      return CellComparatorImpl.COMPARATOR.compareRows(left, right);
     }
 
     /**
@@ -1840,7 +1839,7 @@ public class KeyValue implements ExtendedCell {
     }
 
     public int compareOnlyKeyPortion(Cell left, Cell right) {
-      return CellComparator.COMPARATOR.compareKeyIgnoresMvcc(left, right);
+      return CellUtil.compareKeyIgnoresMvcc(CellComparatorImpl.COMPARATOR, 
left, right);
     }
 
     /**
@@ -1849,12 +1848,12 @@ public class KeyValue implements ExtendedCell {
      */
     @Override
     public int compare(final Cell left, final Cell right) {
-      int compare = CellComparator.COMPARATOR.compare(left, right);
+      int compare = CellComparatorImpl.COMPARATOR.compare(left, right);
       return compare;
     }
 
     public int compareTimestamps(final Cell left, final Cell right) {
-      return CellComparator.compareTimestamps(left, right);
+      return CellComparatorImpl.COMPARATOR.compareTimestamps(left, right);
     }
 
     /**
@@ -1884,7 +1883,7 @@ public class KeyValue implements ExtendedCell {
 
     int compareColumns(final Cell left, final short lrowlength, final Cell 
right,
         final short rrowlength) {
-      return CellComparator.compareColumns(left, right);
+      return CellComparatorImpl.COMPARATOR.compareColumns(left, right);
     }
 
     protected int compareColumns(

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java
 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java
index bc905e5..ec3bfd5 100644
--- 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java
+++ 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/BufferedDataBlockEncoder.java
@@ -25,6 +25,7 @@ import java.nio.ByteBuffer;
 import org.apache.hadoop.hbase.ByteBufferCell;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.ExtendedCell;
 import org.apache.hadoop.hbase.HConstants;
@@ -748,7 +749,7 @@ abstract class BufferedDataBlockEncoder extends 
AbstractDataBlockEncoder {
     @Override
     public int compareKey(CellComparator comparator, Cell key) {
       keyOnlyKV.setKey(current.keyBuffer, 0, current.keyLength);
-      return comparator.compareKeyIgnoresMvcc(key, keyOnlyKV);
+      return CellUtil.compareKeyIgnoresMvcc(comparator, key, keyOnlyKV);
     }
 
     @Override
@@ -880,7 +881,7 @@ abstract class BufferedDataBlockEncoder extends 
AbstractDataBlockEncoder {
                   qualCommonPrefix);
               comp = compareCommonQualifierPrefix(seekCell, keyOnlyKV, 
qualCommonPrefix);
               if (comp == 0) {
-                comp = CellComparator.compareTimestamps(seekCell, keyOnlyKV);
+                comp = 
CellComparatorImpl.COMPARATOR.compareTimestamps(seekCell, keyOnlyKV);
                 if (comp == 0) {
                   // Compare types. Let the delete types sort ahead of puts;
                   // i.e. types

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoder.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoder.java
 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoder.java
index dbb6adb..7b4036c 100644
--- 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoder.java
+++ 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/DataBlockEncoder.java
@@ -100,8 +100,7 @@ public interface DataBlockEncoder {
    * @param decodingCtx
    * @return A newly created seeker.
    */
-  EncodedSeeker createSeeker(CellComparator comparator, 
-      HFileBlockDecodingContext decodingCtx);
+  EncodedSeeker createSeeker(CellComparator comparator, 
HFileBlockDecodingContext decodingCtx);
 
   /**
    * Creates a encoder specific encoding context

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexCodecV1.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexCodecV1.java
 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexCodecV1.java
index eb783cd..530e673 100644
--- 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexCodecV1.java
+++ 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexCodecV1.java
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.yetus.audience.InterfaceAudience;
@@ -107,7 +108,7 @@ public class RowIndexCodecV1 extends 
AbstractDataBlockEncoder {
       dup.limit(sourceAsBuffer.position() + onDiskSize);
       return dup.slice();
     } else {
-      RowIndexSeekerV1 seeker = new RowIndexSeekerV1(CellComparator.COMPARATOR,
+      RowIndexSeekerV1 seeker = new 
RowIndexSeekerV1(CellComparatorImpl.COMPARATOR,
           decodingCtx);
       seeker.setCurrentBuffer(new SingleByteBuff(sourceAsBuffer));
       List<Cell> kvs = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexEncoderV1.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexEncoderV1.java
 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexEncoderV1.java
index 61928a7..fded0f6 100644
--- 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexEncoderV1.java
+++ 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexEncoderV1.java
@@ -17,6 +17,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.io.ByteArrayOutputStream;
 
@@ -57,7 +58,7 @@ public class RowIndexEncoderV1 {
       throw new IOException("Key cannot be null or empty");
     }
     if (lastCell != null) {
-      int keyComp = CellComparator.COMPARATOR.compareRows(lastCell, cell);
+      int keyComp = CellComparatorImpl.COMPARATOR.compareRows(lastCell, cell);
       if (keyComp > 0) {
         throw new IOException("Added a key not lexically larger than"
             + " previous. Current cell = " + cell + ", lastCell = " + 
lastCell);

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexSeekerV1.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexSeekerV1.java
 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexSeekerV1.java
index 75fca82..8611b34 100644
--- 
a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexSeekerV1.java
+++ 
b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/encoding/RowIndexSeekerV1.java
@@ -190,7 +190,7 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker 
{
     }
     do {
       int comp;
-      comp = comparator.compareKeyIgnoresMvcc(seekCell, current.currentKey);
+      comp = CellUtil.compareKeyIgnoresMvcc(comparator, seekCell, 
current.currentKey);
       if (comp == 0) { // exact match
         if (seekBefore) {
           if (!previous.isValid()) {
@@ -244,7 +244,7 @@ public class RowIndexSeekerV1 extends AbstractEncodedSeeker 
{
 
   @Override
   public int compareKey(CellComparator comparator, Cell key) {
-    return comparator.compareKeyIgnoresMvcc(key, current.currentKey);
+    return CellUtil.compareKeyIgnoresMvcc(comparator, key, current.currentKey);
   }
 
   protected void decodeFirst() {

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/test/java/org/apache/hadoop/hbase/TestCellComparator.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestCellComparator.java 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestCellComparator.java
index 2831b93..b4226ce 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestCellComparator.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestCellComparator.java
@@ -31,7 +31,7 @@ import org.junit.experimental.categories.Category;
 @Category({MiscTests.class, SmallTests.class})
 public class TestCellComparator {
 
-  private CellComparator comparator = CellComparator.COMPARATOR;
+  private CellComparatorImpl comparator = CellComparatorImpl.COMPARATOR;
   byte[] row1 = Bytes.toBytes("row1");
   byte[] row2 = Bytes.toBytes("row2");
   byte[] row_1_0 = Bytes.toBytes("row10");
@@ -53,7 +53,7 @@ public class TestCellComparator {
 
     kv1 = new KeyValue(row1, fam2, qual1, val);
     kv2 = new KeyValue(row1, fam1, qual1, val);
-    assertTrue((CellComparator.compareFamilies(kv1, kv2) > 0));
+    assertTrue((CellComparatorImpl.COMPARATOR.compareFamilies(kv1, kv2) > 0));
 
     kv1 = new KeyValue(row1, fam1, qual1, 1l, val);
     kv2 = new KeyValue(row1, fam1, qual1, 2l, val);
@@ -72,23 +72,23 @@ public class TestCellComparator {
   public void testCompareCellWithKey() throws Exception {
     KeyValue kv1 = new KeyValue(row1, fam1, qual1, val);
     KeyValue kv2 = new KeyValue(row2, fam1, qual1, val);
-    assertTrue((comparator.compare(kv1, kv2.getKey(), 0, kv2.getKey().length)) 
< 0);
+    assertTrue((CellUtil.compare(comparator, kv1, kv2.getKey(), 0, 
kv2.getKey().length)) < 0);
 
     kv1 = new KeyValue(row1, fam2, qual1, val);
     kv2 = new KeyValue(row1, fam1, qual1, val);
-    assertTrue((comparator.compare(kv1, kv2.getKey(), 0, kv2.getKey().length)) 
> 0);
+    assertTrue((CellUtil.compare(comparator, kv1, kv2.getKey(), 0, 
kv2.getKey().length)) > 0);
 
     kv1 = new KeyValue(row1, fam1, qual1, 1l, val);
     kv2 = new KeyValue(row1, fam1, qual1, 2l, val);
-    assertTrue((comparator.compare(kv1, kv2.getKey(), 0, kv2.getKey().length)) 
> 0);
+    assertTrue((CellUtil.compare(comparator, kv1, kv2.getKey(), 0, 
kv2.getKey().length)) > 0);
 
     kv1 = new KeyValue(row1, fam1, qual1, 1l, Type.Put);
     kv2 = new KeyValue(row1, fam1, qual1, 1l, Type.Maximum);
-    assertTrue((comparator.compare(kv1, kv2.getKey(), 0, kv2.getKey().length)) 
> 0);
+    assertTrue((CellUtil.compare(comparator, kv1, kv2.getKey(), 0, 
kv2.getKey().length)) > 0);
 
     kv1 = new KeyValue(row1, fam1, qual1, 1l, Type.Put);
     kv2 = new KeyValue(row1, fam1, qual1, 1l, Type.Put);
-    assertTrue((comparator.compare(kv1, kv2.getKey(), 0, kv2.getKey().length)) 
== 0);
+    assertTrue((CellUtil.compare(comparator, kv1, kv2.getKey(), 0, 
kv2.getKey().length)) == 0);
   }
 
   @Test
@@ -105,16 +105,16 @@ public class TestCellComparator {
     kv = new KeyValue(r2, f1, q1, v);
     buffer = ByteBuffer.wrap(kv.getBuffer());
     Cell bbCell2 = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
-    assertEquals(0, CellComparator.compareColumns(bbCell1, bbCell2));
-    assertEquals(0, CellComparator.compareColumns(bbCell1, kv));
+    assertEquals(0, CellComparatorImpl.COMPARATOR.compareColumns(bbCell1, 
bbCell2));
+    assertEquals(0, CellComparatorImpl.COMPARATOR.compareColumns(bbCell1, kv));
     kv = new KeyValue(r2, f1, q2, v);
     buffer = ByteBuffer.wrap(kv.getBuffer());
     Cell bbCell3 = new ByteBufferKeyValue(buffer, 0, buffer.remaining());
-    assertEquals(0, CellComparator.compareFamilies(bbCell2, bbCell3));
-    assertTrue(CellComparator.compareQualifiers(bbCell2, bbCell3) < 0);
-    assertTrue(CellComparator.compareColumns(bbCell2, bbCell3) < 0);
+    assertEquals(0, CellComparatorImpl.COMPARATOR.compareFamilies(bbCell2, 
bbCell3));
+    assertTrue(CellComparatorImpl.COMPARATOR.compareQualifiers(bbCell2, 
bbCell3) < 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compareColumns(bbCell2, bbCell3) 
< 0);
 
-    assertEquals(0, CellComparator.COMPARATOR.compareRows(bbCell2, bbCell3));
-    assertTrue(CellComparator.COMPARATOR.compareRows(bbCell1, bbCell2) < 0);
+    assertEquals(0, CellComparatorImpl.COMPARATOR.compareRows(bbCell2, 
bbCell3));
+    assertTrue(CellComparatorImpl.COMPARATOR.compareRows(bbCell1, bbCell2) < 
0);
   }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/test/java/org/apache/hadoop/hbase/TestKeyValue.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestKeyValue.java 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestKeyValue.java
index 562c008..b13a8d2 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/TestKeyValue.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/TestKeyValue.java
@@ -108,24 +108,24 @@ public class TestKeyValue extends TestCase {
     final byte [] qf = Bytes.toBytes("umn");
     KeyValue aaa = new KeyValue(a, fam, qf, a);
     KeyValue bbb = new KeyValue(b, fam, qf, b);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, bbb) < 0);
-    assertTrue(CellComparator.COMPARATOR.compare(bbb, aaa) > 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, bbb) < 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(bbb, aaa) > 0);
     // Compare breaks if passed same ByteBuffer as both left and right 
arguments.
-    assertTrue(CellComparator.COMPARATOR.compare(bbb, bbb) == 0);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, aaa) == 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(bbb, bbb) == 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, aaa) == 0);
     // Do compare with different timestamps.
     aaa = new KeyValue(a, fam, qf, 1, a);
     bbb = new KeyValue(a, fam, qf, 2, a);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, bbb) > 0);
-    assertTrue(CellComparator.COMPARATOR.compare(bbb, aaa) < 0);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, aaa) == 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, bbb) > 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(bbb, aaa) < 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, aaa) == 0);
     // Do compare with different types.  Higher numbered types -- Delete
     // should sort ahead of lower numbers; i.e. Put
     aaa = new KeyValue(a, fam, qf, 1, KeyValue.Type.Delete, a);
     bbb = new KeyValue(a, fam, qf, 1, a);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, bbb) < 0);
-    assertTrue(CellComparator.COMPARATOR.compare(bbb, aaa) > 0);
-    assertTrue(CellComparator.COMPARATOR.compare(aaa, aaa) == 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, bbb) < 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(bbb, aaa) > 0);
+    assertTrue(CellComparatorImpl.COMPARATOR.compare(aaa, aaa) == 0);
   }
 
   public void testMoreComparisons() throws Exception {
@@ -136,7 +136,7 @@ public class TestKeyValue extends TestCase {
         Bytes.toBytes("TestScanMultipleVersions,row_0500,1236020145502"), now);
     KeyValue bbb = new KeyValue(
         Bytes.toBytes("TestScanMultipleVersions,,99999999999999"), now);
-    CellComparator c = CellComparator.META_COMPARATOR;
+    CellComparator c = CellComparatorImpl.META_COMPARATOR;
     assertTrue(c.compare(bbb, aaa) < 0);
 
     KeyValue aaaa = new 
KeyValue(Bytes.toBytes("TestScanMultipleVersions,,1236023996656"),
@@ -151,13 +151,13 @@ public class TestKeyValue extends TestCase {
         Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1236034574912L,
         (byte[])null);
     assertTrue(c.compare(x, y) < 0);
-    comparisons(CellComparator.META_COMPARATOR);
-    comparisons(CellComparator.COMPARATOR);
-    metacomparisons(CellComparator.META_COMPARATOR);
+    comparisons(CellComparatorImpl.META_COMPARATOR);
+    comparisons(CellComparatorImpl.COMPARATOR);
+    metacomparisons(CellComparatorImpl.META_COMPARATOR);
   }
 
   public void testMetaComparatorTableKeysWithCommaOk() {
-    CellComparator c = CellComparator.META_COMPARATOR;
+    CellComparator c = CellComparatorImpl.META_COMPARATOR;
     long now = System.currentTimeMillis();
     // meta keys values are not quite right.  A users can enter illegal values
     // from shell when scanning meta.
@@ -178,17 +178,17 @@ public class TestKeyValue extends TestCase {
       Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
     KeyValue rowB = new 
KeyValue(Bytes.toBytes("testtable,www.hbase.org/%20,99999"),
         Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
-    assertTrue(CellComparator.META_COMPARATOR.compare(rowA, rowB) < 0);
+    assertTrue(CellComparatorImpl.META_COMPARATOR.compare(rowA, rowB) < 0);
 
     rowA = new KeyValue(Bytes.toBytes("testtable,,1234"), Bytes.toBytes("fam"),
         Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
     rowB = new KeyValue(Bytes.toBytes("testtable,$www.hbase.org/,99999"),
         Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
-    assertTrue(CellComparator.META_COMPARATOR.compare(rowA, rowB) < 0);
+    assertTrue(CellComparatorImpl.META_COMPARATOR.compare(rowA, rowB) < 0);
 
   }
 
-  private void metacomparisons(final CellComparator c) {
+  private void metacomparisons(final CellComparatorImpl c) {
     long now = System.currentTimeMillis();
     assertTrue(c.compare(new KeyValue(
         Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), 
now),
@@ -205,7 +205,7 @@ public class TestKeyValue extends TestCase {
           
Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), now)) > 
0);
   }
 
-  private void comparisons(final CellComparator c) {
+  private void comparisons(final CellComparatorImpl c) {
     long now = System.currentTimeMillis();
     assertTrue(c.compare(new KeyValue(
         Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,1"), now),
@@ -222,7 +222,7 @@ public class TestKeyValue extends TestCase {
   }
 
   public void testBinaryKeys() throws Exception {
-    Set<KeyValue> set = new TreeSet<>(CellComparator.COMPARATOR);
+    Set<KeyValue> set = new TreeSet<>(CellComparatorImpl.COMPARATOR);
     final byte [] fam = Bytes.toBytes("col");
     final byte [] qf = Bytes.toBytes("umn");
     final byte [] nb = new byte[0];
@@ -248,7 +248,7 @@ public class TestKeyValue extends TestCase {
     }
     assertTrue(assertion);
     // Make set with good comparator
-    set = new TreeSet<>(CellComparator.META_COMPARATOR);
+    set = new TreeSet<>(CellComparatorImpl.META_COMPARATOR);
     Collections.addAll(set, keys);
     count = 0;
     for (KeyValue k: set) {
@@ -288,7 +288,7 @@ public class TestKeyValue extends TestCase {
   }
 
   public void testCompareWithoutRow() {
-    final CellComparator c = CellComparator.COMPARATOR;
+    final CellComparator c = CellComparatorImpl.COMPARATOR;
     byte[] row = Bytes.toBytes("row");
 
     byte[] fa = Bytes.toBytes("fa");
@@ -335,7 +335,7 @@ public class TestKeyValue extends TestCase {
   }
 
   public void testFirstLastOnRow() {
-    final CellComparator c = CellComparator.COMPARATOR;
+    final CellComparator c = CellComparatorImpl.COMPARATOR;
     long ts = 1;
     byte[] bufferA = new byte[128];
     int offsetA = 0;
@@ -499,7 +499,7 @@ public class TestKeyValue extends TestCase {
   }
 
   public void testMetaKeyComparator() {
-    CellComparator c = CellComparator.META_COMPARATOR;
+    CellComparator c = CellComparatorImpl.META_COMPARATOR;
     long now = System.currentTimeMillis();
 
     KeyValue a = new KeyValue(Bytes.toBytes("table1"), now);

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-common/src/test/java/org/apache/hadoop/hbase/util/RedundantKVGenerator.java
----------------------------------------------------------------------
diff --git 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/RedundantKVGenerator.java
 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/RedundantKVGenerator.java
index 0f3ccb4..fb9205d 100644
--- 
a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/RedundantKVGenerator.java
+++ 
b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/RedundantKVGenerator.java
@@ -26,7 +26,7 @@ import java.util.Random;
 
 import org.apache.hadoop.hbase.ArrayBackedTag;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.ByteBufferKeyValue;
 import org.apache.hadoop.hbase.Tag;
@@ -287,7 +287,7 @@ public class RedundantKVGenerator {
       }
     }
 
-    Collections.sort(result, CellComparator.COMPARATOR);
+    Collections.sort(result, CellComparatorImpl.COMPARATOR);
 
     return result;
   }
@@ -383,7 +383,7 @@ public class RedundantKVGenerator {
       }
     }
 
-    Collections.sort(result, CellComparator.COMPARATOR);
+    Collections.sort(result, CellComparatorImpl.COMPARATOR);
 
     return result;
   }

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-it/src/test/java/org/apache/hadoop/hbase/mapreduce/IntegrationTestImportTsv.java
----------------------------------------------------------------------
diff --git 
a/hbase-it/src/test/java/org/apache/hadoop/hbase/mapreduce/IntegrationTestImportTsv.java
 
b/hbase-it/src/test/java/org/apache/hadoop/hbase/mapreduce/IntegrationTestImportTsv.java
index 246cb5b..ef26274 100644
--- 
a/hbase-it/src/test/java/org/apache/hadoop/hbase/mapreduce/IntegrationTestImportTsv.java
+++ 
b/hbase-it/src/test/java/org/apache/hadoop/hbase/mapreduce/IntegrationTestImportTsv.java
@@ -37,7 +37,7 @@ import org.apache.hadoop.conf.Configured;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.IntegrationTestingUtility;
 import org.apache.hadoop.hbase.KeyValue;
@@ -84,7 +84,7 @@ public class IntegrationTestImportTsv extends Configured 
implements Tool {
   public TestName name = new TestName();
 
   protected static final Set<KeyValue> simple_expected =
-      new TreeSet<KeyValue>(CellComparator.COMPARATOR) {
+      new TreeSet<KeyValue>(CellComparatorImpl.COMPARATOR) {
     private static final long serialVersionUID = 1L;
     {
       byte[] family = Bytes.toBytes("d");
@@ -163,7 +163,7 @@ public class IntegrationTestImportTsv extends Configured 
implements Tool {
           assertTrue(
             format("Scan produced surprising result. expected: <%s>, actual: 
%s",
               expected, actual),
-            CellComparator.COMPARATOR.compare(expected, actual) == 0);
+            CellComparatorImpl.COMPARATOR.compare(expected, actual) == 0);
         }
       }
       assertFalse("Did not consume all expected values.", 
expectedIt.hasNext());

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/CellSortReducer.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/CellSortReducer.java
 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/CellSortReducer.java
index c33ee15..5c2b41f 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/CellSortReducer.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/CellSortReducer.java
@@ -22,7 +22,7 @@ import java.io.IOException;
 import java.util.TreeSet;
 
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.MapReduceCell;
@@ -42,7 +42,7 @@ public class CellSortReducer
   protected void reduce(ImmutableBytesWritable row, Iterable<Cell> kvs,
       Reducer<ImmutableBytesWritable, Cell, ImmutableBytesWritable, 
Cell>.Context context)
   throws java.io.IOException, InterruptedException {
-    TreeSet<Cell> map = new TreeSet<>(CellComparator.COMPARATOR);
+    TreeSet<Cell> map = new TreeSet<>(CellComparatorImpl.COMPARATOR);
     for (Cell kv : kvs) {
       try {
         map.add(CellUtil.deepClone(kv));

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/HFileOutputFormat2.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/HFileOutputFormat2.java
 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/HFileOutputFormat2.java
index fdbe6c0..e666f90 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/HFileOutputFormat2.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/HFileOutputFormat2.java
@@ -46,7 +46,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
@@ -402,12 +402,12 @@ public class HFileOutputFormat2
           wl.writer =
               new StoreFileWriter.Builder(conf, new CacheConfig(tempConf), fs)
                   .withOutputDir(familydir).withBloomType(bloomType)
-                  
.withComparator(CellComparator.COMPARATOR).withFileContext(hFileContext).build();
+                  
.withComparator(CellComparatorImpl.COMPARATOR).withFileContext(hFileContext).build();
         } else {
           wl.writer =
               new StoreFileWriter.Builder(conf, new CacheConfig(tempConf), new 
HFileSystem(fs))
                   .withOutputDir(familydir).withBloomType(bloomType)
-                  
.withComparator(CellComparator.COMPARATOR).withFileContext(hFileContext)
+                  
.withComparator(CellComparatorImpl.COMPARATOR).withFileContext(hFileContext)
                   .withFavoredNodes(favoredNodes).build();
         }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
index 61835e4..acc3c62 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/Import.java
@@ -40,7 +40,7 @@ import org.apache.hadoop.conf.Configured;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.KeyValue;
@@ -147,7 +147,7 @@ public class Import extends Configured implements Tool {
     
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="EQ_COMPARETO_USE_OBJECT_EQUALS",
       justification="This is wrong, yes, but we should be purging Writables, 
not fixing them")
     public int compareTo(CellWritableComparable o) {
-      return CellComparator.COMPARATOR.compare(this.kv, 
((CellWritableComparable)o).kv);
+      return CellComparatorImpl.COMPARATOR.compare(this.kv, 
((CellWritableComparable)o).kv);
     }
 
     public static class CellWritableComparator extends WritableComparator {

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/PutSortReducer.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/PutSortReducer.java
 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/PutSortReducer.java
index bb935c3..6c36302 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/PutSortReducer.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/PutSortReducer.java
@@ -27,7 +27,7 @@ import java.util.TreeSet;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ArrayBackedTag;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.hadoop.hbase.Tag;
@@ -77,7 +77,7 @@ public class PutSortReducer extends
         "putsortreducer.row.threshold", 1L * (1<<30));
     Iterator<Put> iter = puts.iterator();
     while (iter.hasNext()) {
-      TreeSet<KeyValue> map = new TreeSet<>(CellComparator.COMPARATOR);
+      TreeSet<KeyValue> map = new TreeSet<>(CellComparatorImpl.COMPARATOR);
       long curSize = 0;
       // stop at the end or the RAM threshold
       List<Tag> tags = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/SyncTable.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/SyncTable.java
 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/SyncTable.java
index c72a0c3..3f5cc69 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/SyncTable.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/SyncTable.java
@@ -29,7 +29,7 @@ import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.TableName;
@@ -52,7 +52,6 @@ import org.apache.hadoop.util.Tool;
 import org.apache.hadoop.util.ToolRunner;
 
 import org.apache.hadoop.hbase.shaded.com.google.common.base.Throwables;
-import org.apache.hadoop.hbase.shaded.com.google.common.collect.Iterators;
 
 public class SyncTable extends Configured implements Tool {
 
@@ -588,18 +587,18 @@ public class SyncTable extends Configured implements Tool 
{
         return -1; // target missing cell
       }
 
-      int result = CellComparator.compareFamilies(c1, c2);
+      int result = CellComparatorImpl.COMPARATOR.compareFamilies(c1, c2);
       if (result != 0) {
         return result;
       }
 
-      result = CellComparator.compareQualifiers(c1, c2);
+      result = CellComparatorImpl.COMPARATOR.compareQualifiers(c1, c2);
       if (result != 0) {
         return result;
       }
 
       // note timestamp comparison is inverted - more recent cells first
-      return CellComparator.compareTimestamps(c1, c2);
+      return CellComparatorImpl.COMPARATOR.compareTimestamps(c1, c2);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TextSortReducer.java
----------------------------------------------------------------------
diff --git 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TextSortReducer.java
 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TextSortReducer.java
index 2aaa4eb..0f47032 100644
--- 
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TextSortReducer.java
+++ 
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TextSortReducer.java
@@ -27,7 +27,7 @@ import java.util.TreeSet;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ArrayBackedTag;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.hadoop.hbase.Tag;
@@ -144,7 +144,7 @@ public class TextSortReducer extends
         "reducer.row.threshold", 1L * (1<<30));
     Iterator<Text> iter = lines.iterator();
     while (iter.hasNext()) {
-      Set<KeyValue> kvs = new TreeSet<>(CellComparator.COMPARATOR);
+      Set<KeyValue> kvs = new TreeSet<>(CellComparatorImpl.COMPARATOR);
       long curSize = 0;
       // stop at the end or the RAM threshold
       while (iter.hasNext() && curSize < threshold) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeCodec.java
----------------------------------------------------------------------
diff --git 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeCodec.java
 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeCodec.java
index 4d8673c..4295035 100644
--- 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeCodec.java
+++ 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/PrefixTreeCodec.java
@@ -27,7 +27,7 @@ import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
 import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.CellComparator.MetaCellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl.MetaCellComparator;
 import org.apache.hadoop.hbase.KeyValueUtil;
 import org.apache.hadoop.hbase.codec.prefixtree.decode.DecoderFactory;
 import org.apache.hadoop.hbase.codec.prefixtree.decode.PrefixTreeArraySearcher;

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java
----------------------------------------------------------------------
diff --git 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java
 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java
index 09a87a8..44d2852 100644
--- 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java
+++ 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeArrayScanner.java
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.codec.prefixtree.decode;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellScanner;
+import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.codec.prefixtree.PrefixTreeBlockMeta;
 import org.apache.hadoop.hbase.codec.prefixtree.decode.column.ColumnReader;
 import org.apache.hadoop.hbase.codec.prefixtree.decode.row.RowNodeReader;
@@ -419,7 +420,7 @@ public class PrefixTreeArrayScanner extends PrefixTreeCell 
implements CellScanne
 
   protected int populateNonRowFieldsAndCompareTo(int cellNum, Cell key) {
     populateNonRowFields(cellNum);
-    return comparator.compareKeyIgnoresMvcc(this, key);
+    return CellUtil.compareKeyIgnoresMvcc(comparator, this, key);
   }
 
   protected void populateFirstNonRowFields() {

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeCell.java
----------------------------------------------------------------------
diff --git 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeCell.java
 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeCell.java
index e63bb97..ca8c378 100644
--- 
a/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeCell.java
+++ 
b/hbase-prefix-tree/src/main/java/org/apache/hadoop/hbase/codec/prefixtree/decode/PrefixTreeCell.java
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
 import org.apache.hadoop.hbase.ByteBufferCell;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValueUtil;
@@ -42,7 +43,7 @@ import org.apache.hadoop.hbase.util.ObjectIntPair;
 public class PrefixTreeCell extends ByteBufferCell implements 
SettableSequenceId,
     Comparable<Cell> {
   // Create a reference here? Can be removed too
-  protected CellComparator comparator = CellComparator.COMPARATOR;
+  protected CellComparator comparator = CellComparatorImpl.COMPARATOR;
 
   /********************** static **********************/
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-prefix-tree/src/test/java/org/apache/hadoop/hbase/codec/prefixtree/row/data/TestRowDataNumberStrings.java
----------------------------------------------------------------------
diff --git 
a/hbase-prefix-tree/src/test/java/org/apache/hadoop/hbase/codec/prefixtree/row/data/TestRowDataNumberStrings.java
 
b/hbase-prefix-tree/src/test/java/org/apache/hadoop/hbase/codec/prefixtree/row/data/TestRowDataNumberStrings.java
index 255376a..5c4d008 100644
--- 
a/hbase-prefix-tree/src/test/java/org/apache/hadoop/hbase/codec/prefixtree/row/data/TestRowDataNumberStrings.java
+++ 
b/hbase-prefix-tree/src/test/java/org/apache/hadoop/hbase/codec/prefixtree/row/data/TestRowDataNumberStrings.java
@@ -21,7 +21,7 @@ package org.apache.hadoop.hbase.codec.prefixtree.row.data;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValue.Type;
 import org.apache.hadoop.hbase.codec.prefixtree.row.BaseTestRowData;
@@ -50,7 +50,7 @@ public class TestRowDataNumberStrings extends BaseTestRowData{
 
       d.add(new KeyValue(row, family, column, 0L, Type.Put, value));
     }
-    Collections.sort(d, CellComparator.COMPARATOR);
+    Collections.sort(d, CellComparatorImpl.COMPARATOR);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-server/src/main/java/org/apache/hadoop/hbase/io/HalfStoreFileReader.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/HalfStoreFileReader.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/HalfStoreFileReader.java
index 18ddb6a..fec17bc 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/HalfStoreFileReader.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/HalfStoreFileReader.java
@@ -30,6 +30,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.Scan;
@@ -209,11 +210,11 @@ public class HalfStoreFileReader extends StoreFileReader {
       @Override
       public int seekTo(Cell key) throws IOException {
         if (top) {
-          if (getComparator().compareKeyIgnoresMvcc(key, splitCell) < 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, splitCell) 
< 0) {
             return -1;
           }
         } else {
-          if (getComparator().compareKeyIgnoresMvcc(key, splitCell) >= 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, splitCell) 
>= 0) {
             // we would place the scanner in the second half.
             // it might be an error to return false here ever...
             boolean res = delegate.seekBefore(splitCell);
@@ -234,11 +235,11 @@ public class HalfStoreFileReader extends StoreFileReader {
         // except
         // that we call reseekTo (and not seekTo) on the delegate.
         if (top) {
-          if (getComparator().compareKeyIgnoresMvcc(key, splitCell) < 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, splitCell) 
< 0) {
             return -1;
           }
         } else {
-          if (getComparator().compareKeyIgnoresMvcc(key, splitCell) >= 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, splitCell) 
>= 0) {
             // we would place the scanner in the second half.
             // it might be an error to return false here ever...
             boolean res = delegate.seekBefore(splitCell);
@@ -260,13 +261,13 @@ public class HalfStoreFileReader extends StoreFileReader {
       public boolean seekBefore(Cell key) throws IOException {
         if (top) {
           Optional<Cell> fk = getFirstKey();
-          if (getComparator().compareKeyIgnoresMvcc(key, fk.get()) <= 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, fk.get()) 
<= 0) {
             return false;
           }
         } else {
           // The equals sign isn't strictly necessary just here to be 
consistent
           // with seekTo
-          if (getComparator().compareKeyIgnoresMvcc(key, splitCell) >= 0) {
+          if (CellUtil.compareKeyIgnoresMvcc(getComparator(), key, splitCell) 
>= 0) {
             boolean ret = this.delegate.seekBefore(splitCell);
             if (ret) {
               atEnd = false;

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.java
index d82dd17..115302e 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/FixedFileTrailer.java
@@ -28,7 +28,8 @@ import java.nio.ByteBuffer;
 
 import org.apache.hadoop.fs.FSDataInputStream;
 import org.apache.hadoop.hbase.CellComparator;
-import org.apache.hadoop.hbase.CellComparator.MetaCellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
+import org.apache.hadoop.hbase.CellComparatorImpl.MetaCellComparator;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.io.compress.Compression;
@@ -109,7 +110,7 @@ public class FixedFileTrailer {
 
   /** Raw key comparator class name in version 3 */
   // We could write the actual class name from 2.0 onwards and handle BC
-  private String comparatorClassName = 
CellComparator.COMPARATOR.getClass().getName();
+  private String comparatorClassName = 
CellComparatorImpl.COMPARATOR.getClass().getName();
 
   /** The encryption key */
   private byte[] encryptionKey;
@@ -559,11 +560,15 @@ public class FixedFileTrailer {
   private static Class<? extends CellComparator> getComparatorClass(String 
comparatorClassName)
       throws IOException {
     Class<? extends CellComparator> comparatorKlass;
+    // for BC
     if 
(comparatorClassName.equals(KeyValue.COMPARATOR.getLegacyKeyComparatorName())
-        || 
comparatorClassName.equals(KeyValue.COMPARATOR.getClass().getName())) {
-      comparatorKlass = CellComparator.class;
+        || comparatorClassName.equals(KeyValue.COMPARATOR.getClass().getName())
+        || 
(comparatorClassName.equals("org.apache.hadoop.hbase.CellComparator"))) {
+      comparatorKlass = CellComparatorImpl.class;
     } else if 
(comparatorClassName.equals(KeyValue.META_COMPARATOR.getLegacyKeyComparatorName())
-        || 
comparatorClassName.equals(KeyValue.META_COMPARATOR.getClass().getName())) {
+        || 
comparatorClassName.equals(KeyValue.META_COMPARATOR.getClass().getName())
+        || (comparatorClassName
+            
.equals("org.apache.hadoop.hbase.CellComparator$MetaCellComparator"))) {
       comparatorKlass = MetaCellComparator.class;
     } else if 
(comparatorClassName.equals("org.apache.hadoop.hbase.KeyValue.RawBytesComparator")
         || 
comparatorClassName.equals("org.apache.hadoop.hbase.util.Bytes$ByteArrayComparator"))
 {

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
index 35b741d..53ab9eb 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java
@@ -49,6 +49,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.fs.PathFilter;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.fs.HFileSystem;
@@ -276,7 +277,7 @@ public class HFile {
     protected Path path;
     protected FSDataOutputStream ostream;
     protected CellComparator comparator =
-        CellComparator.COMPARATOR;
+        CellComparatorImpl.COMPARATOR;
     protected InetSocketAddress[] favoredNodes;
     private HFileContext fileContext;
     protected boolean shouldDropBehind = false;

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java
index 24bc286..ead156b 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlockIndex.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.hbase.ByteBufferKeyOnlyKeyValue;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+//import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValue.KeyOnlyKeyValue;
@@ -766,7 +767,7 @@ public class HFileBlockIndex {
         // TODO avoid array call.
         nonRootIndex.asSubByteBuffer(midKeyOffset, midLength, pair);
         nonRootIndexkeyOnlyKV.setKey(pair.getFirst(), pair.getSecond(), 
midLength);
-        int cmp = comparator.compareKeyIgnoresMvcc(key, nonRootIndexkeyOnlyKV);
+        int cmp = CellUtil.compareKeyIgnoresMvcc(comparator, key, 
nonRootIndexkeyOnlyKV);
 
         // key lives above the midpoint
         if (cmp > 0)

http://git-wip-us.apache.org/repos/asf/hbase/blob/70f4c5da/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java
index eed73df..acb25fc 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java
@@ -53,7 +53,7 @@ import org.apache.hadoop.conf.Configured;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.CellUtil;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
@@ -379,7 +379,7 @@ public class HFilePrettyPrinter extends Configured 
implements Tool {
     do {
       Cell cell = scanner.getCell();
       if (row != null && row.length != 0) {
-        int result = CellComparator.COMPARATOR.compareRows(cell, row, 0, 
row.length);
+        int result = CellComparatorImpl.COMPARATOR.compareRows(cell, row, 0, 
row.length);
         if (result > 0) {
           break;
         } else if (result < 0) {
@@ -408,7 +408,7 @@ public class HFilePrettyPrinter extends Configured 
implements Tool {
       }
       // check if rows are in order
       if (checkRow && pCell != null) {
-        if (CellComparator.COMPARATOR.compareRows(pCell, cell) > 0) {
+        if (CellComparatorImpl.COMPARATOR.compareRows(pCell, cell) > 0) {
           err.println("WARNING, previous row is greater then"
               + " current row\n\tfilename -> " + file + "\n\tprevious -> "
               + CellUtil.getCellKeyAsString(pCell) + "\n\tcurrent  -> "
@@ -424,7 +424,7 @@ public class HFilePrettyPrinter extends Configured 
implements Tool {
               + "\n\tfilename -> " + file + "\n\tkeyvalue -> "
               + CellUtil.getCellKeyAsString(cell));
         }
-        if (pCell != null && CellComparator.compareFamilies(pCell, cell) != 0) 
{
+        if (pCell != null && 
CellComparatorImpl.COMPARATOR.compareFamilies(pCell, cell) != 0) {
           err.println("WARNING, previous kv has different family"
               + " compared to current key\n\tfilename -> " + file
               + "\n\tprevious -> " + CellUtil.getCellKeyAsString(pCell)
@@ -618,7 +618,7 @@ public class HFilePrettyPrinter extends Configured 
implements Tool {
     public void collect(Cell cell) {
       valLen.update(cell.getValueLength());
       if (prevCell != null &&
-          CellComparator.COMPARATOR.compareRows(prevCell, cell) != 0) {
+          CellComparatorImpl.COMPARATOR.compareRows(prevCell, cell) != 0) {
         // new row
         collectRow();
       }

Reply via email to