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:
parent
8ac8a0e56f
commit
0b64b9288f
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue