HBASE-12413 Mismatch in the equals and hashcode methods of KeyValue (Jingcheng Du and Gariel Reid)

This commit is contained in:
tedyu 2015-03-28 06:31:28 -07:00
parent 5038fc76c9
commit bd837d47f7
3 changed files with 25 additions and 10 deletions

View File

@ -244,7 +244,6 @@ public class CellComparator implements Comparator<Cell>, Serializable {
/** /**
* Returns a hash code that is always the same for two Cells having a matching equals(..) result. * 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){ public static int hashCode(Cell cell){
if (cell == null) {// return 0 for empty Cell if (cell == null) {// return 0 for empty Cell
@ -258,8 +257,7 @@ public class CellComparator implements Comparator<Cell>, Serializable {
/** /**
* Returns a hash code that is always the same for two Cells having a matching * 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 * equals(..) result. Note : Ignore mvcc while calculating the hashcode
* necessary. Note : Ignore mvcc while calculating the hashcode
* *
* @param cell * @param cell
* @return hashCode * @return hashCode

View File

@ -1064,15 +1064,12 @@ public class KeyValue implements Cell, HeapSize, Cloneable, SettableSequenceId,
return CellComparator.equals(this, (Cell)other); return CellComparator.equals(this, (Cell)other);
} }
/**
* In line with {@link #equals(Object)}, only uses the key portion, not the value.
*/
@Override @Override
public int hashCode() { public int hashCode() {
byte[] b = getBuffer(); return CellComparator.hashCodeIgnoreMvcc(this);
int start = getOffset(), end = getOffset() + getLength();
int h = b[start++];
for (int i = start; i < end; i++) {
h = (h * 13) ^ b[i];
}
return h;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -35,6 +35,8 @@ import org.apache.hadoop.hbase.KeyValue.MetaComparator;
import org.apache.hadoop.hbase.KeyValue.Type; import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import static org.junit.Assert.assertNotEquals;
public class TestKeyValue extends TestCase { public class TestKeyValue extends TestCase {
private final Log LOG = LogFactory.getLog(this.getClass().getName()); private final Log LOG = LogFactory.getLog(this.getClass().getName());
@ -614,4 +616,22 @@ public class TestKeyValue extends TestCase {
b = new KeyValue(Bytes.toBytes("table,111,222,bbb"), now); b = new KeyValue(Bytes.toBytes("table,111,222,bbb"), now);
assertTrue(c.compare(a, b) < 0); assertTrue(c.compare(a, b) < 0);
} }
public void testEqualsAndHashCode() throws Exception {
KeyValue kvA1 = new KeyValue(Bytes.toBytes("key"), Bytes.toBytes("cf"),
Bytes.toBytes("qualA"), Bytes.toBytes("1"));
KeyValue kvA2 = new KeyValue(Bytes.toBytes("key"), Bytes.toBytes("cf"),
Bytes.toBytes("qualA"), Bytes.toBytes("2"));
// We set a different sequence id on kvA2 to demonstrate that the equals and hashCode also
// don't take this into account.
kvA2.setSequenceId(2);
KeyValue kvB = new KeyValue(Bytes.toBytes("key"), Bytes.toBytes("cf"),
Bytes.toBytes("qualB"), Bytes.toBytes("1"));
assertEquals(kvA1, kvA2);
assertNotEquals(kvA1, kvB);
assertEquals(kvA1.hashCode(), kvA2.hashCode());
assertNotEquals(kvA1.hashCode(), kvB.hashCode());
}
} }