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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShipped() throws IOException {
|
||||
super.beforeShipped();
|
||||
deletes.beforeShipped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNullColumnInQuery() {
|
||||
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.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
|
||||
|
@ -32,7 +33,7 @@ import org.apache.hadoop.hbase.Cell;
|
|||
* </ul>
|
||||
*/
|
||||
@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.
|
||||
|
|
|
@ -147,6 +147,12 @@ public class LegacyScanQueryMatcher extends ScanQueryMatcher {
|
|||
this.dropDeletesToRow = Preconditions.checkNotNull(dropDeletesToRow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShipped() throws IOException {
|
||||
super.beforeShipped();
|
||||
deletes.beforeShipped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchCode match(Cell cell) throws IOException {
|
||||
if (filter != null && filter.filterAllRemaining()) {
|
||||
|
|
|
@ -50,6 +50,12 @@ public abstract class NormalUserScanQueryMatcher extends UserScanQueryMatcher {
|
|||
this.seePastDeleteMarkers = scanInfo.getKeepDeletedCells() != KeepDeletedCells.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeShipped() throws IOException {
|
||||
super.beforeShipped();
|
||||
deletes.beforeShipped();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchCode match(Cell cell) throws IOException {
|
||||
if (filter != null && filter.filterAllRemaining()) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.apache.hadoop.hbase.regionserver.querymatcher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.SortedSet;
|
||||
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.CellUtil;
|
||||
import org.apache.hadoop.hbase.KeyValue;
|
||||
import org.apache.hadoop.hbase.KeyValueUtil;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
|
||||
/**
|
||||
|
@ -48,9 +50,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
protected boolean hasFamilyStamp = false;
|
||||
protected long familyStamp = 0L;
|
||||
protected SortedSet<Long> familyVersionStamps = new TreeSet<Long>();
|
||||
protected byte[] deleteBuffer = null;
|
||||
protected int deleteOffset = 0;
|
||||
protected int deleteLength = 0;
|
||||
protected Cell deleteCell = null;
|
||||
protected byte deleteType = 0;
|
||||
protected long deleteTimestamp = 0L;
|
||||
|
||||
|
@ -74,16 +74,14 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
return;
|
||||
}
|
||||
|
||||
if (deleteBuffer != null && type < deleteType) {
|
||||
if (deleteCell != null && type < deleteType) {
|
||||
// same column, so ignore less specific delete
|
||||
if (CellUtil.matchingQualifier(cell, deleteBuffer, deleteOffset, deleteLength)) {
|
||||
if (CellUtil.matchingQualifier(cell, deleteCell)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// new column, or more general delete type
|
||||
deleteBuffer = cell.getQualifierArray();
|
||||
deleteOffset = cell.getQualifierOffset();
|
||||
deleteLength = cell.getQualifierLength();
|
||||
deleteCell = cell;
|
||||
deleteType = type;
|
||||
deleteTimestamp = timestamp;
|
||||
}
|
||||
|
@ -106,8 +104,8 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
return DeleteResult.FAMILY_VERSION_DELETED;
|
||||
}
|
||||
|
||||
if (deleteBuffer != null) {
|
||||
int ret = -(CellComparator.compareQualifiers(cell, deleteBuffer, deleteOffset, deleteLength));
|
||||
if (deleteCell != null) {
|
||||
int ret = -(CellComparator.compareQualifiers(cell, deleteCell));
|
||||
if (ret == 0) {
|
||||
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
||||
return DeleteResult.COLUMN_DELETED;
|
||||
|
@ -121,13 +119,15 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
assert timestamp < deleteTimestamp;
|
||||
|
||||
// different timestamp, let's clear the buffer.
|
||||
deleteBuffer = null;
|
||||
deleteCell = null;
|
||||
} else if (ret < 0) {
|
||||
// Next column case.
|
||||
deleteBuffer = null;
|
||||
deleteCell = null;
|
||||
} else {
|
||||
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(),
|
||||
cell.getQualifierLength())
|
||||
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
||||
|
@ -139,7 +139,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return deleteBuffer == null && !hasFamilyStamp && familyVersionStamps.isEmpty();
|
||||
return deleteCell == null && !hasFamilyStamp && familyVersionStamps.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,7 +148,7 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
hasFamilyStamp = false;
|
||||
familyStamp = 0L;
|
||||
familyVersionStamps.clear();
|
||||
deleteBuffer = null;
|
||||
deleteCell = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,4 +156,11 @@ public class ScanDeleteTracker implements DeleteTracker {
|
|||
public void update() {
|
||||
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;
|
||||
}
|
||||
// new column, or more general delete type
|
||||
if (deleteBuffer != null) {
|
||||
if (!(CellUtil.matchingQualifier(delCell, deleteBuffer, deleteOffset, deleteLength))) {
|
||||
if (deleteCell != null) {
|
||||
if (!(CellUtil.matchingQualifier(delCell, deleteCell))) {
|
||||
// A case where there are deletes for a column qualifier but there are
|
||||
// no corresponding puts for them. Rare case.
|
||||
visibilityTagsDeleteColumns = null;
|
||||
|
@ -104,9 +104,7 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
|||
visiblityTagsDeleteColumnVersion = null;
|
||||
}
|
||||
}
|
||||
deleteBuffer = delCell.getQualifierArray();
|
||||
deleteOffset = delCell.getQualifierOffset();
|
||||
deleteLength = delCell.getQualifierLength();
|
||||
deleteCell = delCell;
|
||||
deleteType = type;
|
||||
deleteTimestamp = timestamp;
|
||||
extractDeleteCellVisTags(delCell, KeyValue.Type.codeToType(type));
|
||||
|
@ -243,8 +241,8 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (deleteBuffer != null) {
|
||||
int ret = CellComparator.compareQualifiers(cell, deleteBuffer, deleteOffset, deleteLength);
|
||||
if (deleteCell != null) {
|
||||
int ret = CellComparator.compareQualifiers(cell, deleteCell);
|
||||
if (ret == 0) {
|
||||
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
|
||||
if (visibilityTagsDeleteColumns != null) {
|
||||
|
@ -304,13 +302,15 @@ public class VisibilityScanDeleteTracker extends ScanDeleteTracker {
|
|||
}
|
||||
} else if (ret > 0) {
|
||||
// Next column case.
|
||||
deleteBuffer = null;
|
||||
deleteCell = null;
|
||||
// Can nullify this because we are moving to the next column
|
||||
visibilityTagsDeleteColumns = null;
|
||||
visiblityTagsDeleteColumnVersion = null;
|
||||
} else {
|
||||
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(),
|
||||
cell.getQualifierLength())
|
||||
+ ", timestamp=" + timestamp + ", comparison result: " + ret);
|
||||
|
|
Loading…
Reference in New Issue