org.apache.hbase.cell.CellComparator.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hbase.cell.CellComparator.java

Source

/*
 * 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.hbase.cell;

import java.io.Serializable;
import java.util.Comparator;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hbase.Cell;

import com.google.common.primitives.Longs;

/**
 * Compare two traditional HBase cells.
 *
 * Note: This comparator is not valid for -ROOT- and .META. tables.
 */
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class CellComparator implements Comparator<Cell>, Serializable {
    private static final long serialVersionUID = -8760041766259623329L;

    @Override
    public int compare(Cell a, Cell b) {
        return compareStatic(a, b);
    }

    public static int compareStatic(Cell a, Cell b) {
        //row
        int c = Bytes.compareTo(a.getRowArray(), a.getRowOffset(), a.getRowLength(), b.getRowArray(),
                b.getRowOffset(), b.getRowLength());
        if (c != 0)
            return c;

        //family
        c = Bytes.compareTo(a.getFamilyArray(), a.getFamilyOffset(), a.getFamilyLength(), b.getFamilyArray(),
                b.getFamilyOffset(), b.getFamilyLength());
        if (c != 0)
            return c;

        //qualifier
        c = Bytes.compareTo(a.getQualifierArray(), a.getQualifierOffset(), a.getQualifierLength(),
                b.getQualifierArray(), b.getQualifierOffset(), b.getQualifierLength());
        if (c != 0)
            return c;

        //timestamp: later sorts first
        c = -Longs.compare(a.getTimestamp(), b.getTimestamp());
        if (c != 0)
            return c;

        //type
        c = (0xff & a.getTypeByte()) - (0xff & b.getTypeByte());
        if (c != 0)
            return c;

        //mvccVersion: later sorts first
        return -Longs.compare(a.getMvccVersion(), b.getMvccVersion());
    }

    /**************** equals ****************************/

    public static boolean equals(Cell a, Cell b) {
        if (!areKeyLengthsEqual(a, b)) {
            return false;
        }
        //TODO compare byte[]'s in reverse since later bytes more likely to differ
        return 0 == compareStatic(a, b);
    }

    public static boolean equalsRow(Cell a, Cell b) {
        if (!areRowLengthsEqual(a, b)) {
            return false;
        }
        return 0 == Bytes.compareTo(a.getRowArray(), a.getRowOffset(), a.getRowLength(), b.getRowArray(),
                b.getRowOffset(), b.getRowLength());
    }

    /********************* hashCode ************************/

    /**
     * Returns a hash code that is always the same for two Cells having a matching equals(..) result.
     * Currently does not guard against nulls, but it could if necessary.
     */
    public static int hashCode(Cell cell) {
        if (cell == null) {// return 0 for empty Cell
            return 0;
        }

        //pre-calculate the 3 hashes made of byte ranges
        int rowHash = Bytes.hashCode(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
        int familyHash = Bytes.hashCode(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
        int qualifierHash = Bytes.hashCode(cell.getQualifierArray(), cell.getQualifierOffset(),
                cell.getQualifierLength());

        //combine the 6 sub-hashes
        int hash = 31 * rowHash + familyHash;
        hash = 31 * hash + qualifierHash;
        hash = 31 * hash + (int) cell.getTimestamp();
        hash = 31 * hash + cell.getTypeByte();
        hash = 31 * hash + (int) cell.getMvccVersion();
        return hash;
    }

    /******************** lengths *************************/

    public static boolean areKeyLengthsEqual(Cell a, Cell b) {
        return a.getRowLength() == b.getRowLength() && a.getFamilyLength() == b.getFamilyLength()
                && a.getQualifierLength() == b.getQualifierLength();
    }

    public static boolean areRowLengthsEqual(Cell a, Cell b) {
        return a.getRowLength() == b.getRowLength();
    }

    /***************** special cases ****************************/

    /**
     * special case for KeyValue.equals
     */
    private static int compareStaticIgnoreMvccVersion(Cell a, Cell b) {
        //row
        int c = Bytes.compareTo(a.getRowArray(), a.getRowOffset(), a.getRowLength(), b.getRowArray(),
                b.getRowOffset(), b.getRowLength());
        if (c != 0)
            return c;

        //family
        c = Bytes.compareTo(a.getFamilyArray(), a.getFamilyOffset(), a.getFamilyLength(), b.getFamilyArray(),
                b.getFamilyOffset(), b.getFamilyLength());
        if (c != 0)
            return c;

        //qualifier
        c = Bytes.compareTo(a.getQualifierArray(), a.getQualifierOffset(), a.getQualifierLength(),
                b.getQualifierArray(), b.getQualifierOffset(), b.getQualifierLength());
        if (c != 0)
            return c;

        //timestamp: later sorts first
        c = -Longs.compare(a.getTimestamp(), b.getTimestamp());
        if (c != 0)
            return c;

        //type
        c = (0xff & a.getTypeByte()) - (0xff & b.getTypeByte());
        return c;
    }

    /**
     * special case for KeyValue.equals
     */
    public static boolean equalsIgnoreMvccVersion(Cell a, Cell b) {
        return 0 == compareStaticIgnoreMvccVersion(a, b);
    }

}