HBASE-11053- Change DeleteTracker APIs to work with Cell (Ram)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1589963 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
ramkrishna 2014-04-25 09:43:05 +00:00
parent 8ac8a0e56f
commit 0b64b9288f
4 changed files with 96 additions and 75 deletions

View File

@ -19,6 +19,7 @@
package org.apache.hadoop.hbase.regionserver;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.Cell;
/**
* This interface is used for the tracking and enforcement of Deletes
@ -33,32 +34,21 @@ import org.apache.hadoop.classification.InterfaceAudience;
public interface DeleteTracker {
/**
* Add the specified KeyValue to the list of deletes to check against for
* Add the specified cell to the list of deletes to check against for
* this row operation.
* <p>
* This is called when a Delete is encountered in a StoreFile.
* @param buffer KeyValue buffer
* @param qualifierOffset column qualifier offset
* @param qualifierLength column qualifier length
* @param timestamp timestamp
* @param type delete type as byte
* @param Cell cell
*/
void add(
byte[] buffer, int qualifierOffset, int qualifierLength, long timestamp, byte type
);
void add(Cell cell);
/**
* Check if the specified KeyValue buffer has been deleted by a previously
* Check if the specified cell buffer has been deleted by a previously
* seen delete.
* @param buffer KeyValue buffer
* @param qualifierOffset column qualifier offset
* @param qualifierLength column qualifier length
* @param timestamp timestamp
* @param Cell cell to check if deleted
* @return deleteResult The result tells whether the KeyValue is deleted and why
*/
DeleteResult isDeleted(
byte[] buffer, int qualifierOffset, int qualifierLength, long timestamp
);
DeleteResult isDeleted(Cell cell);
/**
* @return true if there are no current delete, false otherwise

View File

@ -23,6 +23,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.util.Bytes;
@ -72,8 +73,11 @@ public class ScanDeleteTracker implements DeleteTracker {
* @param type delete type as byte
*/
@Override
public void add(byte[] buffer, int qualifierOffset, int qualifierLength,
long timestamp, byte type) {
public void add(Cell cell) {
long timestamp = cell.getTimestamp();
int qualifierOffset = cell.getQualifierOffset();
int qualifierLength = cell.getQualifierLength();
byte type = cell.getTypeByte();
if (!hasFamilyStamp || timestamp > familyStamp) {
if (type == KeyValue.Type.DeleteFamily.getCode()) {
hasFamilyStamp = true;
@ -87,12 +91,12 @@ public class ScanDeleteTracker implements DeleteTracker {
if (deleteBuffer != null && type < deleteType) {
// same column, so ignore less specific delete
if (Bytes.equals(deleteBuffer, deleteOffset, deleteLength,
buffer, qualifierOffset, qualifierLength)){
cell.getQualifierArray(), qualifierOffset, qualifierLength)){
return;
}
}
// new column, or more general delete type
deleteBuffer = buffer;
deleteBuffer = cell.getQualifierArray();
deleteOffset = qualifierOffset;
deleteLength = qualifierLength;
deleteType = type;
@ -105,15 +109,14 @@ public class ScanDeleteTracker implements DeleteTracker {
* Check if the specified KeyValue buffer has been deleted by a previously
* seen delete.
*
* @param buffer KeyValue buffer
* @param qualifierOffset column qualifier offset
* @param qualifierLength column qualifier length
* @param timestamp timestamp
* @param Cell cell
* @return deleteResult
*/
@Override
public DeleteResult isDeleted(byte [] buffer, int qualifierOffset,
int qualifierLength, long timestamp) {
public DeleteResult isDeleted(Cell cell) {
long timestamp = cell.getTimestamp();
int qualifierOffset = cell.getQualifierOffset();
int qualifierLength = cell.getQualifierLength();
if (hasFamilyStamp && timestamp <= familyStamp) {
return DeleteResult.FAMILY_DELETED;
}
@ -124,7 +127,7 @@ public class ScanDeleteTracker implements DeleteTracker {
if (deleteBuffer != null) {
int ret = Bytes.compareTo(deleteBuffer, deleteOffset, deleteLength,
buffer, qualifierOffset, qualifierLength);
cell.getQualifierArray(), qualifierOffset, qualifierLength);
if (ret == 0) {
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
@ -147,7 +150,7 @@ public class ScanDeleteTracker implements DeleteTracker {
throw new IllegalStateException("isDelete failed: deleteBuffer="
+ Bytes.toStringBinary(deleteBuffer, deleteOffset, deleteLength)
+ ", qualifier="
+ Bytes.toStringBinary(buffer, qualifierOffset, qualifierLength)
+ Bytes.toStringBinary(cell.getQualifierArray(), qualifierOffset, qualifierLength)
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
}
}

View File

@ -315,8 +315,7 @@ public class ScanQueryMatcher {
tr.withinOrAfterTimeRange(timestamp);
if (includeDeleteMarker
&& mvccVersion <= maxReadPointToTrackVersions) {
this.deletes.add(cell.getQualifierArray(), qualifierOffset,
qualifierLength, timestamp, typeByte);
this.deletes.add(cell);
}
// Can't early out now, because DelFam come before any other keys
}
@ -349,8 +348,7 @@ public class ScanQueryMatcher {
// note the following next else if...
// delete marker are not subject to other delete markers
} else if (!this.deletes.isEmpty()) {
DeleteResult deleteResult = deletes.isDeleted(cell.getQualifierArray(),
qualifierOffset, qualifierLength, timestamp);
DeleteResult deleteResult = deletes.isDeleted(cell);
switch (deleteResult) {
case FAMILY_DELETED:
case COLUMN_DELETED:

View File

@ -19,7 +19,9 @@
package org.apache.hadoop.hbase.regionserver;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.HBaseTestCase;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.regionserver.DeleteTracker.DeleteResult;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.experimental.categories.Category;
@ -38,32 +40,32 @@ public class TestScanDeleteTracker extends HBaseTestCase {
}
public void testDeletedBy_Delete() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.Delete.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
Bytes.toBytes("qualifier"), timestamp, KeyValue.Type.Delete);
sdt.add(kv);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.VERSION_DELETED, ret);
}
public void testDeletedBy_DeleteColumn() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.DeleteColumn.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
Bytes.toBytes("qualifier"), timestamp, KeyValue.Type.DeleteColumn);
sdt.add(kv);
timestamp -= 5;
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
Bytes.toBytes("qualifier"), timestamp , KeyValue.Type.DeleteColumn);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.COLUMN_DELETED, ret);
}
public void testDeletedBy_DeleteFamily() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.DeleteFamily.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
Bytes.toBytes("qualifier"), timestamp, KeyValue.Type.DeleteFamily);
sdt.add(kv);
timestamp -= 5;
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
Bytes.toBytes("qualifier"), timestamp , KeyValue.Type.DeleteColumn);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.FAMILY_DELETED, ret);
}
@ -73,25 +75,40 @@ public class TestScanDeleteTracker extends HBaseTestCase {
byte [] qualifier3 = Bytes.toBytes("qualifier3");
byte [] qualifier4 = Bytes.toBytes("qualifier4");
deleteType = KeyValue.Type.DeleteFamilyVersion.getCode();
sdt.add(null, 0, 0, timestamp, deleteType);
DeleteResult ret = sdt.isDeleted(qualifier1, 0, qualifier1.length, timestamp);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
null, timestamp, KeyValue.Type.DeleteFamilyVersion);
sdt.add(kv);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier1, timestamp, KeyValue.Type.DeleteFamilyVersion);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
ret = sdt.isDeleted(qualifier2, 0, qualifier2.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier2, timestamp, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
ret = sdt.isDeleted(qualifier3, 0, qualifier3.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier3, timestamp, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
ret = sdt.isDeleted(qualifier4, 0, qualifier4.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier4, timestamp, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
ret = sdt.isDeleted(qualifier1, 0, qualifier1.length, timestamp + 3);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier1, timestamp + 3, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.NOT_DELETED, ret);
ret = sdt.isDeleted(qualifier2, 0, qualifier2.length, timestamp - 2);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier2, timestamp - 2, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.NOT_DELETED, ret);
ret = sdt.isDeleted(qualifier3, 0, qualifier3.length, timestamp - 5);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier3, timestamp - 5, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.NOT_DELETED, ret);
ret = sdt.isDeleted(qualifier4, 0, qualifier4.length, timestamp + 8);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier4, timestamp + 8, KeyValue.Type.DeleteFamilyVersion);
ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.NOT_DELETED, ret);
}
@ -99,15 +116,20 @@ public class TestScanDeleteTracker extends HBaseTestCase {
public void testDelete_DeleteColumn() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.Delete.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.Delete);
sdt.add(kv);
timestamp -= 5;
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.DeleteColumn);
deleteType = KeyValue.Type.DeleteColumn.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
sdt.add(kv);
timestamp -= 5;
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.DeleteColumn);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.COLUMN_DELETED, ret);
}
@ -115,14 +137,17 @@ public class TestScanDeleteTracker extends HBaseTestCase {
public void testDeleteColumn_Delete() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.DeleteColumn.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.DeleteColumn);
sdt.add(kv);
qualifier = Bytes.toBytes("qualifier1");
deleteType = KeyValue.Type.Delete.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.Delete);
sdt.add(kv);
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals( DeleteResult.VERSION_DELETED, ret);
}
@ -132,9 +157,10 @@ public class TestScanDeleteTracker extends HBaseTestCase {
public void testDelete_KeepDelete(){
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.Delete.getCode();
sdt.add(qualifier, 0, qualifier.length, timestamp, deleteType);
sdt.isDeleted(qualifier, 0, qualifier.length, timestamp);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, timestamp, KeyValue.Type.Delete);
sdt.add(kv);
sdt.isDeleted(kv);
assertEquals(false ,sdt.isEmpty());
}
@ -146,8 +172,12 @@ public class TestScanDeleteTracker extends HBaseTestCase {
long valueTimestamp = 0;
sdt.reset();
sdt.add(qualifier, 0, qualifier.length, deleteTimestamp, deleteType);
DeleteResult ret = sdt.isDeleted(qualifier, 0, qualifier.length, valueTimestamp);
KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, deleteTimestamp, KeyValue.Type.Delete);
sdt.add(kv);
kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"),
qualifier, valueTimestamp, KeyValue.Type.Delete);
DeleteResult ret = sdt.isDeleted(kv);
assertEquals(DeleteResult.NOT_DELETED, ret);
}