You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2013/07/08 16:52:00 UTC
svn commit: r1500780 - in /hbase/trunk:
hbase-client/src/main/java/org/apache/hadoop/hbase/client/
hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/
hbase-common/src/main/java/org/apache/hadoop/hbase/
hbase-protocol/src/main/java/org/apache/...
Author: tedyu
Date: Mon Jul 8 14:52:00 2013
New Revision: 1500780
URL: http://svn.apache.org/r1500780
Log:
HBASE-8753 Provide new delete flag which can delete all cells under a column-family which have designated timestamp (Honghua)
Modified:
hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java
hbase/trunk/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
hbase/trunk/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/ClientProtos.java
hbase/trunk/hbase-protocol/src/main/protobuf/Client.proto
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java
Modified: hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java (original)
+++ hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Delete.java Mon Jul 8 14:52:00 2013
@@ -212,6 +212,25 @@ public class Delete extends Mutation imp
}
/**
+ * Delete all columns of the specified family with a timestamp equal to
+ * the specified timestamp.
+ * @param family family name
+ * @param timestamp version timestamp
+ * @return this for invocation chaining
+ */
+ public Delete deleteFamilyVersion(byte [] family, long timestamp) {
+ List<? extends Cell> list = familyMap.get(family);
+ if(list == null) {
+ list = new ArrayList<Cell>();
+ }
+ ((List<KeyValue>)list).add(new KeyValue(row, family, null, timestamp,
+ KeyValue.Type.DeleteFamilyVersion));
+ familyMap.put(family, list);
+ return this;
+ }
+
+
+ /**
* Delete all versions of the specified column.
* @param family family name
* @param qualifier column qualifier
Modified: hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java (original)
+++ hbase/trunk/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java Mon Jul 8 14:52:00 2013
@@ -548,6 +548,8 @@ public final class ProtobufUtil {
delete.deleteColumn(family, qualifier, ts);
} else if (deleteType == DeleteType.DELETE_MULTIPLE_VERSIONS) {
delete.deleteColumns(family, qualifier, ts);
+ } else if (deleteType == DeleteType.DELETE_FAMILY_VERSION) {
+ delete.deleteFamilyVersion(family, ts);
} else {
delete.deleteFamily(family, ts);
}
@@ -1187,7 +1189,9 @@ public final class ProtobufUtil {
return DeleteType.DELETE_MULTIPLE_VERSIONS;
case DeleteFamily:
return DeleteType.DELETE_FAMILY;
- default:
+ case DeleteFamilyVersion:
+ return DeleteType.DELETE_FAMILY_VERSION;
+ default:
throw new IOException("Unknown delete type: " + type);
}
}
Modified: hbase/trunk/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java (original)
+++ hbase/trunk/hbase-common/src/main/java/org/apache/hadoop/hbase/KeyValue.java Mon Jul 8 14:52:00 2013
@@ -205,6 +205,7 @@ public class KeyValue implements Cell, H
Put((byte)4),
Delete((byte)8),
+ DeleteFamilyVersion((byte)10),
DeleteColumn((byte)12),
DeleteFamily((byte)14),
@@ -1372,6 +1373,13 @@ public class KeyValue implements Cell, H
}
/**
+ * @return True if this KV is a delete family-version type.
+ */
+ public boolean isDeleteFamilyVersion() {
+ return getType() == Type.DeleteFamilyVersion.getCode();
+ }
+
+ /**
*
* @return True if this KV is a delete family or column type.
*/
Modified: hbase/trunk/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/ClientProtos.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/ClientProtos.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/ClientProtos.java (original)
+++ hbase/trunk/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/ClientProtos.java Mon Jul 8 14:52:00 2013
@@ -6600,11 +6600,13 @@ public final class ClientProtos {
DELETE_ONE_VERSION(0, 0),
DELETE_MULTIPLE_VERSIONS(1, 1),
DELETE_FAMILY(2, 2),
+ DELETE_FAMILY_VERSION(3, 3),
;
public static final int DELETE_ONE_VERSION_VALUE = 0;
public static final int DELETE_MULTIPLE_VERSIONS_VALUE = 1;
public static final int DELETE_FAMILY_VALUE = 2;
+ public static final int DELETE_FAMILY_VERSION_VALUE = 3;
public final int getNumber() { return value; }
@@ -6614,6 +6616,7 @@ public final class ClientProtos {
case 0: return DELETE_ONE_VERSION;
case 1: return DELETE_MULTIPLE_VERSIONS;
case 2: return DELETE_FAMILY;
+ case 3: return DELETE_FAMILY_VERSION;
default: return null;
}
}
@@ -6644,7 +6647,7 @@ public final class ClientProtos {
}
private static final DeleteType[] VALUES = {
- DELETE_ONE_VERSION, DELETE_MULTIPLE_VERSIONS, DELETE_FAMILY,
+ DELETE_ONE_VERSION, DELETE_MULTIPLE_VERSIONS, DELETE_FAMILY, DELETE_FAMILY_VERSION,
};
public static DeleteType valueOf(
@@ -21576,7 +21579,7 @@ public final class ClientProtos {
"\177\n\tCondition\022\013\n\003row\030\001 \002(\014\022\016\n\006family\030\002 \002(",
"\014\022\021\n\tqualifier\030\003 \002(\014\022!\n\013compareType\030\004 \002(" +
"\0162\014.CompareType\022\037\n\ncomparator\030\005 \002(\0132\013.Co" +
- "mparator\"\365\005\n\rMutationProto\022\013\n\003row\030\001 \001(\014\022" +
+ "mparator\"\220\006\n\rMutationProto\022\013\n\003row\030\001 \001(\014\022" +
"/\n\nmutateType\030\002 \001(\0162\033.MutationProto.Muta" +
"tionType\022/\n\013columnValue\030\003 \003(\0132\032.Mutation" +
"Proto.ColumnValue\022\021\n\ttimestamp\030\004 \001(\004\022!\n\t" +
@@ -21593,61 +21596,61 @@ public final class ClientProtos {
"\014\n\010SKIP_WAL\020\001\022\r\n\tASYNC_WAL\020\002\022\014\n\010SYNC_WAL" +
"\020\003\022\r\n\tFSYNC_WAL\020\004\">\n\014MutationType\022\n\n\006APP" +
"END\020\000\022\r\n\tINCREMENT\020\001\022\007\n\003PUT\020\002\022\n\n\006DELETE\020" +
- "\003\"U\n\nDeleteType\022\026\n\022DELETE_ONE_VERSION\020\000\022",
+ "\003\"p\n\nDeleteType\022\026\n\022DELETE_ONE_VERSION\020\000\022",
"\034\n\030DELETE_MULTIPLE_VERSIONS\020\001\022\021\n\rDELETE_" +
- "FAMILY\020\002\"r\n\rMutateRequest\022 \n\006region\030\001 \002(" +
- "\0132\020.RegionSpecifier\022 \n\010mutation\030\002 \002(\0132\016." +
- "MutationProto\022\035\n\tcondition\030\003 \001(\0132\n.Condi" +
- "tion\"<\n\016MutateResponse\022\027\n\006result\030\001 \001(\0132\007" +
- ".Result\022\021\n\tprocessed\030\002 \001(\010\"\362\002\n\004Scan\022\027\n\006c" +
- "olumn\030\001 \003(\0132\007.Column\022!\n\tattribute\030\002 \003(\0132" +
- "\016.NameBytesPair\022\020\n\010startRow\030\003 \001(\014\022\017\n\007sto" +
- "pRow\030\004 \001(\014\022\027\n\006filter\030\005 \001(\0132\007.Filter\022\035\n\tt" +
- "imeRange\030\006 \001(\0132\n.TimeRange\022\026\n\013maxVersion",
- "s\030\007 \001(\r:\0011\022\031\n\013cacheBlocks\030\010 \001(\010:\004true\022\021\n" +
- "\tbatchSize\030\t \001(\r\022\025\n\rmaxResultSize\030\n \001(\004\022" +
- "\022\n\nstoreLimit\030\013 \001(\r\022\023\n\013storeOffset\030\014 \001(\r" +
- "\022\"\n\032loadColumnFamiliesOnDemand\030\r \001(\010\022\024\n\014" +
- "cachingCount\030\016 \001(\r\022\023\n\013prefetching\030\017 \001(\010\"" +
- "\230\001\n\013ScanRequest\022 \n\006region\030\001 \001(\0132\020.Region" +
- "Specifier\022\023\n\004scan\030\002 \001(\0132\005.Scan\022\021\n\tscanne" +
- "rId\030\003 \001(\004\022\024\n\014numberOfRows\030\004 \001(\r\022\024\n\014close" +
- "Scanner\030\005 \001(\010\022\023\n\013nextCallSeq\030\006 \001(\004\"l\n\014Sc" +
- "anResponse\022\'\n\016resultCellMeta\030\001 \001(\0132\017.Res",
- "ultCellMeta\022\021\n\tscannerId\030\002 \001(\004\022\023\n\013moreRe" +
- "sults\030\003 \001(\010\022\013\n\003ttl\030\004 \001(\r\"%\n\016ResultCellMe" +
- "ta\022\023\n\013cellsLength\030\001 \003(\r\"\260\001\n\024BulkLoadHFil" +
- "eRequest\022 \n\006region\030\001 \002(\0132\020.RegionSpecifi" +
- "er\0224\n\nfamilyPath\030\002 \003(\0132 .BulkLoadHFileRe" +
- "quest.FamilyPath\022\024\n\014assignSeqNum\030\003 \001(\010\032*" +
- "\n\nFamilyPath\022\016\n\006family\030\001 \002(\014\022\014\n\004path\030\002 \002" +
- "(\t\"\'\n\025BulkLoadHFileResponse\022\016\n\006loaded\030\001 " +
- "\002(\010\"_\n\026CoprocessorServiceCall\022\013\n\003row\030\001 \002" +
- "(\014\022\023\n\013serviceName\030\002 \002(\t\022\022\n\nmethodName\030\003 ",
- "\002(\t\022\017\n\007request\030\004 \002(\014\"d\n\031CoprocessorServi" +
- "ceRequest\022 \n\006region\030\001 \002(\0132\020.RegionSpecif" +
- "ier\022%\n\004call\030\002 \002(\0132\027.CoprocessorServiceCa" +
- "ll\"]\n\032CoprocessorServiceResponse\022 \n\006regi" +
- "on\030\001 \002(\0132\020.RegionSpecifier\022\035\n\005value\030\002 \002(" +
- "\0132\016.NameBytesPair\"B\n\013MultiAction\022 \n\010muta" +
- "tion\030\001 \001(\0132\016.MutationProto\022\021\n\003get\030\002 \001(\0132" +
- "\004.Get\"I\n\014ActionResult\022\026\n\005value\030\001 \001(\0132\007.R" +
- "esult\022!\n\texception\030\002 \001(\0132\016.NameBytesPair" +
- "\"^\n\014MultiRequest\022 \n\006region\030\001 \002(\0132\020.Regio",
- "nSpecifier\022\034\n\006action\030\002 \003(\0132\014.MultiAction" +
- "\022\016\n\006atomic\030\003 \001(\010\".\n\rMultiResponse\022\035\n\006res" +
- "ult\030\001 \003(\0132\r.ActionResult2\342\002\n\rClientServi" +
- "ce\022 \n\003get\022\013.GetRequest\032\014.GetResponse\022/\n\010" +
- "multiGet\022\020.MultiGetRequest\032\021.MultiGetRes" +
- "ponse\022)\n\006mutate\022\016.MutateRequest\032\017.Mutate" +
- "Response\022#\n\004scan\022\014.ScanRequest\032\r.ScanRes" +
- "ponse\022>\n\rbulkLoadHFile\022\025.BulkLoadHFileRe" +
- "quest\032\026.BulkLoadHFileResponse\022F\n\013execSer" +
- "vice\022\032.CoprocessorServiceRequest\032\033.Copro",
- "cessorServiceResponse\022&\n\005multi\022\r.MultiRe" +
- "quest\032\016.MultiResponseBB\n*org.apache.hado" +
- "op.hbase.protobuf.generatedB\014ClientProto" +
- "sH\001\210\001\001\240\001\001"
+ "FAMILY\020\002\022\031\n\025DELETE_FAMILY_VERSION\020\003\"r\n\rM" +
+ "utateRequest\022 \n\006region\030\001 \002(\0132\020.RegionSpe" +
+ "cifier\022 \n\010mutation\030\002 \002(\0132\016.MutationProto" +
+ "\022\035\n\tcondition\030\003 \001(\0132\n.Condition\"<\n\016Mutat" +
+ "eResponse\022\027\n\006result\030\001 \001(\0132\007.Result\022\021\n\tpr" +
+ "ocessed\030\002 \001(\010\"\362\002\n\004Scan\022\027\n\006column\030\001 \003(\0132\007" +
+ ".Column\022!\n\tattribute\030\002 \003(\0132\016.NameBytesPa" +
+ "ir\022\020\n\010startRow\030\003 \001(\014\022\017\n\007stopRow\030\004 \001(\014\022\027\n" +
+ "\006filter\030\005 \001(\0132\007.Filter\022\035\n\ttimeRange\030\006 \001(",
+ "\0132\n.TimeRange\022\026\n\013maxVersions\030\007 \001(\r:\0011\022\031\n" +
+ "\013cacheBlocks\030\010 \001(\010:\004true\022\021\n\tbatchSize\030\t " +
+ "\001(\r\022\025\n\rmaxResultSize\030\n \001(\004\022\022\n\nstoreLimit" +
+ "\030\013 \001(\r\022\023\n\013storeOffset\030\014 \001(\r\022\"\n\032loadColum" +
+ "nFamiliesOnDemand\030\r \001(\010\022\024\n\014cachingCount\030" +
+ "\016 \001(\r\022\023\n\013prefetching\030\017 \001(\010\"\230\001\n\013ScanReque" +
+ "st\022 \n\006region\030\001 \001(\0132\020.RegionSpecifier\022\023\n\004" +
+ "scan\030\002 \001(\0132\005.Scan\022\021\n\tscannerId\030\003 \001(\004\022\024\n\014" +
+ "numberOfRows\030\004 \001(\r\022\024\n\014closeScanner\030\005 \001(\010" +
+ "\022\023\n\013nextCallSeq\030\006 \001(\004\"l\n\014ScanResponse\022\'\n",
+ "\016resultCellMeta\030\001 \001(\0132\017.ResultCellMeta\022\021" +
+ "\n\tscannerId\030\002 \001(\004\022\023\n\013moreResults\030\003 \001(\010\022\013" +
+ "\n\003ttl\030\004 \001(\r\"%\n\016ResultCellMeta\022\023\n\013cellsLe" +
+ "ngth\030\001 \003(\r\"\260\001\n\024BulkLoadHFileRequest\022 \n\006r" +
+ "egion\030\001 \002(\0132\020.RegionSpecifier\0224\n\nfamilyP" +
+ "ath\030\002 \003(\0132 .BulkLoadHFileRequest.FamilyP" +
+ "ath\022\024\n\014assignSeqNum\030\003 \001(\010\032*\n\nFamilyPath\022" +
+ "\016\n\006family\030\001 \002(\014\022\014\n\004path\030\002 \002(\t\"\'\n\025BulkLoa" +
+ "dHFileResponse\022\016\n\006loaded\030\001 \002(\010\"_\n\026Coproc" +
+ "essorServiceCall\022\013\n\003row\030\001 \002(\014\022\023\n\013service",
+ "Name\030\002 \002(\t\022\022\n\nmethodName\030\003 \002(\t\022\017\n\007reques" +
+ "t\030\004 \002(\014\"d\n\031CoprocessorServiceRequest\022 \n\006" +
+ "region\030\001 \002(\0132\020.RegionSpecifier\022%\n\004call\030\002" +
+ " \002(\0132\027.CoprocessorServiceCall\"]\n\032Coproce" +
+ "ssorServiceResponse\022 \n\006region\030\001 \002(\0132\020.Re" +
+ "gionSpecifier\022\035\n\005value\030\002 \002(\0132\016.NameBytes" +
+ "Pair\"B\n\013MultiAction\022 \n\010mutation\030\001 \001(\0132\016." +
+ "MutationProto\022\021\n\003get\030\002 \001(\0132\004.Get\"I\n\014Acti" +
+ "onResult\022\026\n\005value\030\001 \001(\0132\007.Result\022!\n\texce" +
+ "ption\030\002 \001(\0132\016.NameBytesPair\"^\n\014MultiRequ",
+ "est\022 \n\006region\030\001 \002(\0132\020.RegionSpecifier\022\034\n" +
+ "\006action\030\002 \003(\0132\014.MultiAction\022\016\n\006atomic\030\003 " +
+ "\001(\010\".\n\rMultiResponse\022\035\n\006result\030\001 \003(\0132\r.A" +
+ "ctionResult2\342\002\n\rClientService\022 \n\003get\022\013.G" +
+ "etRequest\032\014.GetResponse\022/\n\010multiGet\022\020.Mu" +
+ "ltiGetRequest\032\021.MultiGetResponse\022)\n\006muta" +
+ "te\022\016.MutateRequest\032\017.MutateResponse\022#\n\004s" +
+ "can\022\014.ScanRequest\032\r.ScanResponse\022>\n\rbulk" +
+ "LoadHFile\022\025.BulkLoadHFileRequest\032\026.BulkL" +
+ "oadHFileResponse\022F\n\013execService\022\032.Coproc",
+ "essorServiceRequest\032\033.CoprocessorService" +
+ "Response\022&\n\005multi\022\r.MultiRequest\032\016.Multi" +
+ "ResponseBB\n*org.apache.hadoop.hbase.prot" +
+ "obuf.generatedB\014ClientProtosH\001\210\001\001\240\001\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
Modified: hbase/trunk/hbase-protocol/src/main/protobuf/Client.proto
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-protocol/src/main/protobuf/Client.proto?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-protocol/src/main/protobuf/Client.proto (original)
+++ hbase/trunk/hbase-protocol/src/main/protobuf/Client.proto Mon Jul 8 14:52:00 2013
@@ -175,6 +175,7 @@ message MutationProto {
DELETE_ONE_VERSION = 0;
DELETE_MULTIPLE_VERSIONS = 1;
DELETE_FAMILY = 2;
+ DELETE_FAMILY_VERSION = 3;
}
message ColumnValue {
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/DeleteTracker.java Mon Jul 8 14:52:00 2013
@@ -104,6 +104,7 @@ public interface DeleteTracker {
*/
public static enum DeleteResult {
FAMILY_DELETED, // The KeyValue is deleted by a delete family.
+ FAMILY_VERSION_DELETED, // The KeyValue is deleted by a delete family version.
COLUMN_DELETED, // The KeyValue is deleted by a delete column.
VERSION_DELETED, // The KeyValue is deleted by a version delete.
NOT_DELETED
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanDeleteTracker.java Mon Jul 8 14:52:00 2013
@@ -19,6 +19,9 @@
package org.apache.hadoop.hbase.regionserver;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.util.Bytes;
@@ -43,6 +46,7 @@ public class ScanDeleteTracker implement
private boolean hasFamilyStamp = false;
private long familyStamp = 0L;
+ private SortedSet<Long> familyVersionStamps = new TreeSet<Long>();
private byte [] deleteBuffer = null;
private int deleteOffset = 0;
private int deleteLength = 0;
@@ -75,6 +79,9 @@ public class ScanDeleteTracker implement
hasFamilyStamp = true;
familyStamp = timestamp;
return;
+ } else if (type == KeyValue.Type.DeleteFamilyVersion.getCode()) {
+ familyVersionStamps.add(timestamp);
+ return;
}
if (deleteBuffer != null && type < deleteType) {
@@ -111,6 +118,10 @@ public class ScanDeleteTracker implement
return DeleteResult.FAMILY_DELETED;
}
+ if (familyVersionStamps.contains(Long.valueOf(timestamp))) {
+ return DeleteResult.FAMILY_VERSION_DELETED;
+ }
+
if (deleteBuffer != null) {
int ret = Bytes.compareTo(deleteBuffer, deleteOffset, deleteLength,
buffer, qualifierOffset, qualifierLength);
@@ -146,7 +157,8 @@ public class ScanDeleteTracker implement
@Override
public boolean isEmpty() {
- return deleteBuffer == null && !hasFamilyStamp;
+ return deleteBuffer == null && !hasFamilyStamp &&
+ familyVersionStamps.isEmpty();
}
@Override
@@ -154,6 +166,7 @@ public class ScanDeleteTracker implement
public void reset() {
hasFamilyStamp = false;
familyStamp = 0L;
+ familyVersionStamps.clear();
deleteBuffer = null;
}
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScanQueryMatcher.java Mon Jul 8 14:52:00 2013
@@ -352,6 +352,7 @@ public class ScanQueryMatcher {
case COLUMN_DELETED:
return columns.getNextRowOrNextColumn(bytes, offset, qualLength);
case VERSION_DELETED:
+ case FAMILY_VERSION_DELETED:
return MatchCode.SKIP;
case NOT_DELETED:
break;
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFile.java Mon Jul 8 14:52:00 2013
@@ -950,7 +950,7 @@ public class StoreFile {
private void appendDeleteFamilyBloomFilter(final KeyValue kv)
throws IOException {
- if (!kv.isDeleteFamily()) {
+ if (!kv.isDeleteFamily() && !kv.isDeleteFamilyVersion()) {
return;
}
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java Mon Jul 8 14:52:00 2013
@@ -292,7 +292,7 @@ public class StoreFileScanner implements
kv.getRowOffset(), kv.getRowLength(), kv.getBuffer(),
kv.getQualifierOffset(), kv.getQualifierLength());
} else if (this.matcher != null && !matcher.hasNullColumnInQuery() &&
- kv.isDeleteFamily()) {
+ (kv.isDeleteFamily() || kv.isDeleteFamilyVersion())) {
// if there is no such delete family kv in the store file,
// then no need to seek.
haveToSeek = reader.passesDeleteFamilyBloomFilter(kv.getBuffer(),
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java Mon Jul 8 14:52:00 2013
@@ -1723,6 +1723,160 @@ public class TestFromClientSide {
}
@Test
+ public void testDeleteFamilyVersion() throws Exception {
+ HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+ byte [] TABLE = Bytes.toBytes("testDeleteFamilyVersion");
+
+ byte [][] QUALIFIERS = makeNAscii(QUALIFIER, 1);
+ byte [][] VALUES = makeN(VALUE, 5);
+ long [] ts = {1000, 2000, 3000, 4000, 5000};
+
+ HTable ht = TEST_UTIL.createTable(TABLE, FAMILY, 5);
+
+ Put put = new Put(ROW);
+ for (int q = 0; q < 1; q++)
+ for (int t = 0; t < 5; t++)
+ put.add(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+ ht.put(put);
+ admin.flush(TABLE);
+
+ Delete delete = new Delete(ROW);
+ delete.deleteFamilyVersion(FAMILY, ts[1]); // delete version '2000'
+ delete.deleteFamilyVersion(FAMILY, ts[3]); // delete version '4000'
+ ht.delete(delete);
+ admin.flush(TABLE);
+
+ for (int i = 0; i < 1; i++) {
+ Get get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[i]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ Result result = ht.get(get);
+ // verify version '1000'/'3000'/'5000' remains for all columns
+ assertNResult(result, ROW, FAMILY, QUALIFIERS[i],
+ new long [] {ts[0], ts[2], ts[4]},
+ new byte[][] {VALUES[0], VALUES[2], VALUES[4]},
+ 0, 2);
+ }
+ ht.close();
+ admin.close();
+ }
+
+ @Test
+ public void testDeleteFamilyVersionWithOtherDeletes() throws Exception {
+ byte [] TABLE = Bytes.toBytes("testDeleteFamilyVersionWithOtherDeletes");
+
+ byte [][] QUALIFIERS = makeNAscii(QUALIFIER, 5);
+ byte [][] VALUES = makeN(VALUE, 5);
+ long [] ts = {1000, 2000, 3000, 4000, 5000};
+
+ HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+ HTable ht = TEST_UTIL.createTable(TABLE, FAMILY, 5);
+ Put put = null;
+ Result result = null;
+ Get get = null;
+ Delete delete = null;
+
+ // 1. put on ROW
+ put = new Put(ROW);
+ for (int q = 0; q < 5; q++)
+ for (int t = 0; t < 5; t++)
+ put.add(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+ ht.put(put);
+ admin.flush(TABLE);
+
+ // 2. put on ROWS[0]
+ byte [] ROW2 = Bytes.toBytes("myRowForTest");
+ put = new Put(ROW2);
+ for (int q = 0; q < 5; q++)
+ for (int t = 0; t < 5; t++)
+ put.add(FAMILY, QUALIFIERS[q], ts[t], VALUES[t]);
+ ht.put(put);
+ admin.flush(TABLE);
+
+ // 3. delete on ROW
+ delete = new Delete(ROW);
+ // delete version <= 2000 of all columns
+ // note: deleteFamily must be the first since it will mask
+ // the subsequent other type deletes!
+ delete.deleteFamily(FAMILY, ts[1]);
+ // delete version '4000' of all columns
+ delete.deleteFamilyVersion(FAMILY, ts[3]);
+ // delete version <= 3000 of column 0
+ delete.deleteColumns(FAMILY, QUALIFIERS[0], ts[2]);
+ // delete version <= 5000 of column 2
+ delete.deleteColumns(FAMILY, QUALIFIERS[2], ts[4]);
+ // delete version 5000 of column 4
+ delete.deleteColumn(FAMILY, QUALIFIERS[4], ts[4]);
+ ht.delete(delete);
+ admin.flush(TABLE);
+
+ // 4. delete on ROWS[0]
+ delete = new Delete(ROW2);
+ delete.deleteFamilyVersion(FAMILY, ts[1]); // delete version '2000'
+ delete.deleteFamilyVersion(FAMILY, ts[3]); // delete version '4000'
+ ht.delete(delete);
+ admin.flush(TABLE);
+
+ // 5. check ROW
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[0]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIERS[0],
+ new long [] {ts[4]},
+ new byte[][] {VALUES[4]},
+ 0, 0);
+
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[1]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIERS[1],
+ new long [] {ts[2], ts[4]},
+ new byte[][] {VALUES[2], VALUES[4]},
+ 0, 1);
+
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[2]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertEquals(0, result.size());
+
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[3]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIERS[3],
+ new long [] {ts[2], ts[4]},
+ new byte[][] {VALUES[2], VALUES[4]},
+ 0, 1);
+
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIERS[4]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIERS[4],
+ new long [] {ts[2]},
+ new byte[][] {VALUES[2]},
+ 0, 0);
+
+ // 6. check ROWS[0]
+ for (int i = 0; i < 5; i++) {
+ get = new Get(ROW2);
+ get.addColumn(FAMILY, QUALIFIERS[i]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ // verify version '1000'/'3000'/'5000' remains for all columns
+ assertNResult(result, ROW2, FAMILY, QUALIFIERS[i],
+ new long [] {ts[0], ts[2], ts[4]},
+ new byte[][] {VALUES[0], VALUES[2], VALUES[4]},
+ 0, 2);
+ }
+ ht.close();
+ admin.close();
+ }
+
+ @Test
public void testDeletes() throws Exception {
byte [] TABLE = Bytes.toBytes("testDeletes");
Modified: hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java?rev=1500780&r1=1500779&r2=1500780&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java (original)
+++ hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestScanDeleteTracker.java Mon Jul 8 14:52:00 2013
@@ -67,6 +67,35 @@ public class TestScanDeleteTracker exten
assertEquals(DeleteResult.FAMILY_DELETED, ret);
}
+ public void testDeletedBy_DeleteFamilyVersion() {
+ byte [] qualifier1 = Bytes.toBytes("qualifier1");
+ byte [] qualifier2 = Bytes.toBytes("qualifier2");
+ 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);
+ assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
+ ret = sdt.isDeleted(qualifier2, 0, qualifier2.length, timestamp);
+ assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
+ ret = sdt.isDeleted(qualifier3, 0, qualifier3.length, timestamp);
+ assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
+ ret = sdt.isDeleted(qualifier4, 0, qualifier4.length, timestamp);
+ assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret);
+
+ ret = sdt.isDeleted(qualifier1, 0, qualifier1.length, timestamp + 3);
+ assertEquals(DeleteResult.NOT_DELETED, ret);
+ ret = sdt.isDeleted(qualifier2, 0, qualifier2.length, timestamp - 2);
+ assertEquals(DeleteResult.NOT_DELETED, ret);
+ ret = sdt.isDeleted(qualifier3, 0, qualifier3.length, timestamp - 5);
+ assertEquals(DeleteResult.NOT_DELETED, ret);
+ ret = sdt.isDeleted(qualifier4, 0, qualifier4.length, timestamp + 8);
+ assertEquals(DeleteResult.NOT_DELETED, ret);
+ }
+
+
public void testDelete_DeleteColumn() {
byte [] qualifier = Bytes.toBytes("qualifier");
deleteType = KeyValue.Type.Delete.getCode();