HBASE-5579 A Delete Version could mask other values (Daniel Ferro)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1301173 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Zhihong Yu 2012-03-15 20:03:47 +00:00
parent 273804e658
commit 4a5a27eac2
3 changed files with 22 additions and 8 deletions

View File

@ -22,7 +22,6 @@ package org.apache.hadoop.hbase.regionserver;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.regionserver.DeleteTracker.DeleteResult;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
/** /**
@ -43,7 +42,8 @@ import org.apache.hadoop.hbase.util.Bytes;
@InterfaceAudience.Private @InterfaceAudience.Private
public class ScanDeleteTracker implements DeleteTracker { public class ScanDeleteTracker implements DeleteTracker {
private long familyStamp = -1L; private boolean hasFamilyStamp = false;
private long familyStamp = 0L;
private byte [] deleteBuffer = null; private byte [] deleteBuffer = null;
private int deleteOffset = 0; private int deleteOffset = 0;
private int deleteLength = 0; private int deleteLength = 0;
@ -71,8 +71,9 @@ public class ScanDeleteTracker implements DeleteTracker {
@Override @Override
public void add(byte[] buffer, int qualifierOffset, int qualifierLength, public void add(byte[] buffer, int qualifierOffset, int qualifierLength,
long timestamp, byte type) { long timestamp, byte type) {
if (timestamp > familyStamp) { if (!hasFamilyStamp || timestamp > familyStamp) {
if (type == KeyValue.Type.DeleteFamily.getCode()) { if (type == KeyValue.Type.DeleteFamily.getCode()) {
hasFamilyStamp = true;
familyStamp = timestamp; familyStamp = timestamp;
return; return;
} }
@ -107,7 +108,7 @@ public class ScanDeleteTracker implements DeleteTracker {
@Override @Override
public DeleteResult isDeleted(byte [] buffer, int qualifierOffset, public DeleteResult isDeleted(byte [] buffer, int qualifierOffset,
int qualifierLength, long timestamp) { int qualifierLength, long timestamp) {
if (timestamp <= familyStamp) { if (hasFamilyStamp && timestamp <= familyStamp) {
return DeleteResult.FAMILY_DELETED; return DeleteResult.FAMILY_DELETED;
} }
@ -146,12 +147,13 @@ public class ScanDeleteTracker implements DeleteTracker {
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return deleteBuffer == null && familyStamp == 0; return deleteBuffer == null && !hasFamilyStamp;
} }
@Override @Override
// called between every row. // called between every row.
public void reset() { public void reset() {
hasFamilyStamp = false;
familyStamp = 0L; familyStamp = 0L;
deleteBuffer = null; deleteBuffer = null;
} }

View File

@ -377,11 +377,10 @@ public class TestCompaction extends HBaseTestCase {
deleteVersion.deleteColumn(fam2, col2, 1); deleteVersion.deleteColumn(fam2, col2, 1);
/* /*
* the table has 4 versions: 0, 1, 2, and 3. * the table has 4 versions: 0, 1, 2, and 3.
* 0 does not count.
* We delete 1. * We delete 1.
* Should have 2 remaining. * Should have 3 remaining.
*/ */
testMinorCompactionWithDelete(deleteVersion, 2); testMinorCompactionWithDelete(deleteVersion, 3);
} }
/* /*

View File

@ -110,6 +110,19 @@ public class TestScanDeleteTracker extends HBaseTestCase {
assertEquals(false ,sdt.isEmpty()); assertEquals(false ,sdt.isEmpty());
} }
public void testDelete_KeepVersionZero(){
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.Delete.getCode();
long deleteTimestamp = 10;
long valueTimestamp = 0;
sdt.reset();
sdt.add(qualifier, 0, qualifier.length, deleteTimestamp, deleteType);
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, valueTimestamp);
assertEquals(DeleteResult.NOT_DELETED, ret);
}
@org.junit.Rule @org.junit.Rule
public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =