HBASE-17734 Guard against possibly copying the qualifier in the ScanDeleteTracker
Signed-off-by: tedyu <yuzhihong@gmail.com>
This commit is contained in:
parent
4beae9a56e
commit
81cb298014
|
@ -55,6 +55,12 @@ public abstract class CompactionScanQueryMatcher extends ScanQueryMatcher {
|
||||||
this.keepDeletedCells = scanInfo.getKeepDeletedCells();
|
this.keepDeletedCells = scanInfo.getKeepDeletedCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeShipped() throws IOException {
|
||||||
|
super.beforeShipped();
|
||||||
|
deletes.beforeShipped();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNullColumnInQuery() {
|
public boolean hasNullColumnInQuery() {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.regionserver.querymatcher;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.hbase.Cell;
|
import org.apache.hadoop.hbase.Cell;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.ShipperListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface is used for the tracking and enforcement of Deletes during the course of a Get or
|
* This interface is used for the tracking and enforcement of Deletes during the course of a Get or
|
||||||
|
@ -32,7 +33,7 @@ import org.apache.hadoop.hbase.Cell;
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public interface DeleteTracker {
|
public interface DeleteTracker extends ShipperListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the specified cell to the list of deletes to check against for this row operation.
|
* Add the specified cell to the list of deletes to check against for this row operation.
|
||||||
|
|
|
@ -147,6 +147,12 @@ public class LegacyScanQueryMatcher extends ScanQueryMatcher {
|
||||||
this.dropDeletesToRow = Preconditions.checkNotNull(dropDeletesToRow);
|
this.dropDeletesToRow = Preconditions.checkNotNull(dropDeletesToRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeShipped() throws IOException {
|
||||||
|
super.beforeShipped();
|
||||||
|
deletes.beforeShipped();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MatchCode match(Cell cell) throws IOException {
|
public MatchCode match(Cell cell) throws IOException {
|
||||||
if (filter != null && filter.filterAllRemaining()) {
|
if (filter != null && filter.filterAllRemaining()) {
|
||||||
|
|
|
@ -50,6 +50,12 @@ public abstract class NormalUserScanQueryMatcher extends UserScanQueryMatcher {
|
||||||
this.seePastDeleteMarkers = scanInfo.getKeepDeletedCells() != KeepDeletedCells.FALSE;
|
this.seePastDeleteMarkers = scanInfo.getKeepDeletedCells() != KeepDeletedCells.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeShipped() throws IOException {
|
||||||
|
super.beforeShipped();
|
||||||
|
deletes.beforeShipped();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MatchCode match(Cell cell) throws IOException {
|
public MatchCode match(Cell cell) throws IOException {
|
||||||
if (filter != null && filter.filterAllRemaining()) {
|
if (filter != null && filter.filterAllRemaining()) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.hbase.regionserver.querymatcher;
|
package org.apache.hadoop.hbase.regionserver.querymatcher;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ import org.apache.hadoop.hbase.Cell;
|
||||||
import org.apache.hadoop.hbase.CellComparator;
|
import org.apache.hadoop.hbase.CellComparator;
|
||||||
import org.apache.hadoop.hbase.CellUtil;
|
import org.apache.hadoop.hbase.CellUtil;
|
||||||
import org.apache.hadoop.hbase.KeyValue;
|
import org.apache.hadoop.hbase.KeyValue;
|
||||||
|
import org.apache.hadoop.hbase.KeyValueUtil;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,9 +50,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
protected boolean hasFamilyStamp = false;
|
protected boolean hasFamilyStamp = false;
|
||||||
protected long familyStamp = 0L;
|
protected long familyStamp = 0L;
|
||||||
protected SortedSet<Long> familyVersionStamps = new TreeSet<Long>();
|
protected SortedSet<Long> familyVersionStamps = new TreeSet<Long>();
|
||||||
protected byte[] deleteBuffer = null;
|
protected Cell deleteCell = null;
|
||||||
protected int deleteOffset = 0;
|
|
||||||
protected int deleteLength = 0;
|
|
||||||
protected byte deleteType = 0;
|
protected byte deleteType = 0;
|
||||||
protected long deleteTimestamp = 0L;
|
protected long deleteTimestamp = 0L;
|
||||||
|
|
||||||
|
@ -74,16 +74,14 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteBuffer != null && type < deleteType) {
|
if (deleteCell != null && type < deleteType) {
|
||||||
// same column, so ignore less specific delete
|
// same column, so ignore less specific delete
|
||||||
if (CellUtil.matchingQualifier(cell, deleteBuffer, deleteOffset, deleteLength)) {
|
if (CellUtil.matchingQualifier(cell, deleteCell)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// new column, or more general delete type
|
// new column, or more general delete type
|
||||||
deleteBuffer = cell.getQualifierArray();
|
deleteCell = cell;
|
||||||
deleteOffset = cell.getQualifierOffset();
|
|
||||||
deleteLength = cell.getQualifierLength();
|
|
||||||
deleteType = type;
|
deleteType = type;
|
||||||
deleteTimestamp = timestamp;
|
deleteTimestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +104,8 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
return DeleteResult.FAMILY_VERSION_DELETED;
|
return DeleteResult.FAMILY_VERSION_DELETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleteBuffer != null) {
|
if (deleteCell != null) {
|
||||||
int ret = -(CellComparator.compareQualifiers(cell, deleteBuffer, deleteOffset, deleteLength));
|
int ret = -(CellComparator.compareQualifiers(cell, deleteCell));
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
||||||
return DeleteResult.COLUMN_DELETED;
|
return DeleteResult.COLUMN_DELETED;
|
||||||
|
@ -121,13 +119,15 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
assert timestamp < deleteTimestamp;
|
assert timestamp < deleteTimestamp;
|
||||||
|
|
||||||
// different timestamp, let's clear the buffer.
|
// different timestamp, let's clear the buffer.
|
||||||
deleteBuffer = null;
|
deleteCell = null;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
// Next column case.
|
// Next column case.
|
||||||
deleteBuffer = null;
|
deleteCell = null;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("isDelete failed: deleteBuffer="
|
throw new IllegalStateException("isDelete failed: deleteBuffer="
|
||||||
+ Bytes.toStringBinary(deleteBuffer, deleteOffset, deleteLength) + ", qualifier="
|
+ Bytes.toStringBinary(deleteCell.getQualifierArray(),
|
||||||
|
deleteCell.getQualifierOffset(), deleteCell.getQualifierLength())
|
||||||
|
+ ", qualifier="
|
||||||
+ Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(),
|
+ Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(),
|
||||||
cell.getQualifierLength())
|
cell.getQualifierLength())
|
||||||
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
||||||
|
@ -139,7 +139,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return deleteBuffer == null && !hasFamilyStamp && familyVersionStamps.isEmpty();
|
return deleteCell == null && !hasFamilyStamp && familyVersionStamps.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -148,7 +148,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
hasFamilyStamp = false;
|
hasFamilyStamp = false;
|
||||||
familyStamp = 0L;
|
familyStamp = 0L;
|
||||||
familyVersionStamps.clear();
|
familyVersionStamps.clear();
|
||||||
deleteBuffer = null;
|
deleteCell = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -156,4 +156,11 @@ public class ScanDeleteTracker implements DeleteTracker {
|
||||||
public void update() {
|
public void update() {
|
||||||
this.reset();
|
this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeShipped() throws IOException {
|
||||||
|
if (deleteCell != null) {
|
||||||
|
deleteCell = KeyValueUtil.toNewKeyCell(deleteCell);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,8 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// new column, or more general delete type
|
// new column, or more general delete type
|
||||||
if (deleteBuffer != null) {
|
if (deleteCell != null) {
|
||||||
if (!(CellUtil.matchingQualifier(delCell, deleteBuffer, deleteOffset, deleteLength))) {
|
if (!(CellUtil.matchingQualifier(delCell, deleteCell))) {
|
||||||
// A case where there are deletes for a column qualifier but there are
|
// A case where there are deletes for a column qualifier but there are
|
||||||
// no corresponding puts for them. Rare case.
|
// no corresponding puts for them. Rare case.
|
||||||
visibilityTagsDeleteColumns = null;
|
visibilityTagsDeleteColumns = null;
|
||||||
|
@ -104,9 +104,7 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
||||||
visiblityTagsDeleteColumnVersion = null;
|
visiblityTagsDeleteColumnVersion = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deleteBuffer = delCell.getQualifierArray();
|
deleteCell = delCell;
|
||||||
deleteOffset = delCell.getQualifierOffset();
|
|
||||||
deleteLength = delCell.getQualifierLength();
|
|
||||||
deleteType = type;
|
deleteType = type;
|
||||||
deleteTimestamp = timestamp;
|
deleteTimestamp = timestamp;
|
||||||
extractDeleteCellVisTags(delCell, KeyValue.Type.codeToType(type));
|
extractDeleteCellVisTags(delCell, KeyValue.Type.codeToType(type));
|
||||||
|
@ -243,8 +241,8 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deleteBuffer != null) {
|
if (deleteCell != null) {
|
||||||
int ret = CellComparator.compareQualifiers(cell, deleteBuffer, deleteOffset, deleteLength);
|
int ret = CellComparator.compareQualifiers(cell, deleteCell);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
||||||
if (visibilityTagsDeleteColumns != null) {
|
if (visibilityTagsDeleteColumns != null) {
|
||||||
|
@ -304,13 +302,15 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
||||||
}
|
}
|
||||||
} else if (ret > 0) {
|
} else if (ret > 0) {
|
||||||
// Next column case.
|
// Next column case.
|
||||||
deleteBuffer = null;
|
deleteCell = null;
|
||||||
// Can nullify this because we are moving to the next column
|
// Can nullify this because we are moving to the next column
|
||||||
visibilityTagsDeleteColumns = null;
|
visibilityTagsDeleteColumns = null;
|
||||||
visiblityTagsDeleteColumnVersion = null;
|
visiblityTagsDeleteColumnVersion = null;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("isDeleted failed: deleteBuffer="
|
throw new IllegalStateException("isDeleted failed: deleteBuffer="
|
||||||
+ Bytes.toStringBinary(deleteBuffer, deleteOffset, deleteLength) + ", qualifier="
|
+ Bytes.toStringBinary(deleteCell.getQualifierArray(),
|
||||||
|
deleteCell.getQualifierOffset(), deleteCell.getQualifierLength())
|
||||||
|
+ ", qualifier="
|
||||||
+ Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(),
|
+ Bytes.toStringBinary(cell.getQualifierArray(), cell.getQualifierOffset(),
|
||||||
cell.getQualifierLength())
|
cell.getQualifierLength())
|
||||||
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
||||||
|
|
Loading…
Reference in New Issue