diff --git a/pom.xml b/pom.xml
index 25aee488..ac53a096 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,7 +54,7 @@
${project.encoding}
UTF-8
1.7.21
-
1.2.14.1-SNAPSHOT
+ 1.2.14.4-SNAPSHOT
diff --git a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java
index 66af86e1..3a2ea2d4 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java
@@ -24,6 +24,7 @@
import com.alipay.oceanbase.hbase.result.ClientStreamScanner;
import com.alipay.oceanbase.hbase.util.*;
import com.alipay.oceanbase.rpc.ObTableClient;
+import com.alipay.oceanbase.rpc.exception.ObTableException;
import com.alipay.oceanbase.rpc.mutation.BatchOperation;
import com.alipay.oceanbase.rpc.mutation.result.BatchOperationResult;
import com.alipay.oceanbase.rpc.protocol.payload.impl.ObObj;
@@ -38,7 +39,6 @@
import com.alipay.oceanbase.rpc.stream.ObTableClientQueryStreamResult;
import com.alipay.oceanbase.rpc.table.ObHBaseParams;
import com.alipay.oceanbase.rpc.table.ObKVParams;
-import com.alipay.sofa.common.thread.SofaThreadPoolExecutor;
import com.google.protobuf.Descriptors;
import com.google.protobuf.Message;
@@ -54,6 +54,7 @@
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.hbase.util.VersionInfo;
import org.slf4j.Logger;
@@ -65,7 +66,6 @@
import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
import static com.alipay.oceanbase.hbase.util.Preconditions.checkArgument;
import static com.alipay.oceanbase.hbase.util.TableHBaseLoggerFactory.LCD;
-import static com.alipay.oceanbase.hbase.util.TableHBaseLoggerFactory.TABLE_HBASE_LOGGER_SPACE;
import static com.alipay.oceanbase.rpc.protocol.payload.impl.execute.ObTableOperation.getInstance;
import static com.alipay.oceanbase.rpc.protocol.payload.impl.execute.ObTableOperationType.*;
import static com.alipay.sofa.common.thread.SofaThreadPoolConstants.SOFA_THREAD_POOL_LOGGING_CAPABILITY;
@@ -132,7 +132,7 @@ public class OHTable implements HTableInterface {
/**
* the buffer of put request
*/
- private final ArrayList writeBuffer = new ArrayList();
+ private final ArrayList writeBuffer = new ArrayList<>();
/**
* when the put request reach the write buffer size the do put will
* flush commits automatically
@@ -197,8 +197,14 @@ public OHTable(Configuration configuration, String tableName) throws IOException
long keepAliveTime = configuration.getLong(HBASE_HTABLE_THREAD_KEEP_ALIVE_TIME,
DEFAULT_HBASE_HTABLE_THREAD_KEEP_ALIVE_TIME);
this.executePool = createDefaultThreadPoolExecutor(1, maxThreads, keepAliveTime);
- this.obTableClient = ObTableClientManager
- .getOrCreateObTableClient(new OHConnectionConfiguration(configuration));
+ OHConnectionConfiguration ohConnectionConf = new OHConnectionConfiguration(configuration);
+ int numRetries = configuration.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
+ HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
+ this.obTableClient = ObTableClientManager.getOrCreateObTableClient(setUserDefinedNamespace(
+ this.tableNameString, ohConnectionConf));
+ this.obTableClient.setRpcExecuteTimeout(ohConnectionConf.getRpcTimeout());
+ this.obTableClient.setRuntimeRetryTimes(numRetries);
+ setOperationTimeout(ohConnectionConf.getOperationTimeout());
finishSetUp();
}
@@ -244,8 +250,14 @@ public OHTable(Configuration configuration, final byte[] tableName,
this.tableNameString = Bytes.toString(tableName);
this.executePool = executePool;
this.cleanupPoolOnClose = false;
- this.obTableClient = ObTableClientManager
- .getOrCreateObTableClient(new OHConnectionConfiguration(configuration));
+ OHConnectionConfiguration ohConnectionConf = new OHConnectionConfiguration(configuration);
+ int numRetries = configuration.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
+ HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
+ this.obTableClient = ObTableClientManager.getOrCreateObTableClient(setUserDefinedNamespace(
+ this.tableNameString, ohConnectionConf));
+ this.obTableClient.setRpcExecuteTimeout(ohConnectionConf.getRpcTimeout());
+ this.obTableClient.setRuntimeRetryTimes(numRetries);
+ setOperationTimeout(ohConnectionConf.getOperationTimeout());
finishSetUp();
}
@@ -262,6 +274,7 @@ public OHTable(Configuration configuration, final byte[] tableName,
* @param executePool ExecutorService to be used.
* @throws IllegalArgumentException if the param error
*/
+ @InterfaceAudience.Private
public OHTable(final byte[] tableName, final ObTableClient obTableClient,
final ExecutorService executePool) {
checkArgument(tableName != null, "tableNameString is blank.");
@@ -298,6 +311,7 @@ public OHTable(TableName tableName, Connection connection,
} else {
this.cleanupPoolOnClose = false;
}
+
this.rpcTimeout = connectionConfig.getRpcTimeout();
this.operationTimeout = connectionConfig.getOperationTimeout();
this.operationExecuteInPool = this.configuration.getBoolean(
@@ -308,7 +322,15 @@ public OHTable(TableName tableName, Connection connection,
DEFAULT_HBASE_HTABLE_PUT_WRITE_BUFFER_CHECK);
this.writeBufferSize = connectionConfig.getWriteBufferSize();
this.tableName = tableName.getName();
- this.obTableClient = ObTableClientManager.getOrCreateObTableClient(connectionConfig);
+ int numRetries = configuration.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
+ HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
+ this.obTableClient = ObTableClientManager.getOrCreateObTableClient(setUserDefinedNamespace(
+ this.tableNameString, connectionConfig));
+ this.obTableClient.setRpcExecuteTimeout(rpcTimeout);
+ this.obTableClient.setRuntimeRetryTimes(numRetries);
+ setOperationTimeout(operationTimeout);
+
+ finishSetUp();
}
/**
@@ -332,9 +354,8 @@ public static ThreadPoolExecutor createDefaultThreadPoolExecutor(int coreSize, i
if (System.getProperty(SOFA_THREAD_POOL_LOGGING_CAPABILITY) == null) {
System.setProperty(SOFA_THREAD_POOL_LOGGING_CAPABILITY, "false");
}
- SofaThreadPoolExecutor executor = new SofaThreadPoolExecutor(coreSize, maxThreads,
- keepAliveTime, SECONDS, new SynchronousQueue(), "OHTableDefaultExecutePool",
- TABLE_HBASE_LOGGER_SPACE);
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(coreSize, maxThreads,
+ keepAliveTime, SECONDS, new SynchronousQueue<>(), Threads.newDaemonThreadFactory("ohtable"));
executor.allowCoreThreadTimeOut(true);
return executor;
}
@@ -366,6 +387,36 @@ private void finishSetUp() {
WRITE_BUFFER_SIZE_DEFAULT);
}
+ private OHConnectionConfiguration setUserDefinedNamespace(String tableNameString,
+ OHConnectionConfiguration ohConnectionConf)
+ throws IOException {
+ if (tableNameString.indexOf(':') != -1) {
+ String[] params = tableNameString.split(":");
+ if (params.length != 2) {
+ throw new IllegalArgumentException("Please check the format of self-defined "
+ + "namespace and qualifier: { "
+ + tableNameString + " }");
+ }
+ String database = params[0];
+ checkArgument(isNotBlank(database), "self-defined namespace cannot be blank or null { "
+ + tableNameString + " }");
+ if (ohConnectionConf.isOdpMode()) {
+ ohConnectionConf.setDatabase(database);
+ } else {
+ String databaseSuffix = "database=" + database;
+ String paramUrl = ohConnectionConf.getParamUrl();
+ int databasePos = paramUrl.indexOf("database");
+ if (databasePos == -1) {
+ paramUrl += "&" + databaseSuffix;
+ } else {
+ paramUrl = paramUrl.substring(0, databasePos) + databaseSuffix;
+ }
+ ohConnectionConf.setParamUrl(paramUrl);
+ }
+ }
+ return ohConnectionConf;
+ }
+
@Override
public byte[] getTableName() {
return tableName;
@@ -429,28 +480,250 @@ public Boolean[] exists(List gets) throws IOException {
return objectResults;
}
+ private BatchOperation compatOldServerPut(final List extends Row> actions, final Object[] results, BatchError batchError, int i, List puts)
+ throws Exception {
+ BatchOperationResult tmpResults;
+ List resultMapSingleOp = new LinkedList<>();
+ if (((Put)actions.get(i)).getFamilyCellMap().size() == 1) {
+ puts.clear();
+ Put put = (Put) actions.get(i++);
+ String family = Bytes.toString(put.getFamilyCellMap().firstKey());
+ // aggregate put
+ puts.add(put);
+ while (i < actions.size()) {
+ if (actions.get(i) instanceof Put && ((Put)actions.get(i)).getFamilyCellMap().size() == 1 && Objects.equals(
+ Bytes.toString(((Put) actions.get(i)).getFamilyCellMap().firstKey()),
+ family)) {
+ puts.add(actions.get(i++));
+ } else {
+ break;
+ }
+ }
+ String realTableName = getTargetTableName(tableNameString, family,
+ configuration);
+ BatchOperation batch = buildBatchOperation(realTableName, puts, false,
+ resultMapSingleOp);
+ tmpResults = batch.execute();
+ int index = 0;
+ for (int k = 0; k < resultMapSingleOp.size(); k++) {
+ if (tmpResults.getResults().get(index) instanceof ObTableException) {
+ if (results != null) {
+ results[i - puts.size() + k] = tmpResults.getResults().get(index);
+ }
+ batchError.add(
+ (ObTableException) tmpResults.getResults().get(index),
+ actions.get(i - puts.size() + k), null);
+ } else {
+ if (results != null) {
+ results[i - puts.size() + k] = new Result();
+ }
+ }
+ index += resultMapSingleOp.get(k);
+ }
+ return null;
+ } else {
+ // multi cf put
+ Put put = (Put) actions.get(i);
+ String realTableName = getTargetTableName(tableNameString);
+ return buildBatchOperation(realTableName,
+ Collections.singletonList(put),
+ true, resultMapSingleOp);
+
+ }
+ }
+
+ private BatchOperation compatOldServerDel(final List extends Row> actions, final Object[] results, BatchError batchError, int i)
+ throws Exception {
+ Delete delete = (Delete)actions.get(i);
+ List resultMapSingleOp = new LinkedList<>();
+ if (delete.isEmpty()) {
+ return buildBatchOperation(tableNameString,
+ Collections.singletonList(delete), true,
+ resultMapSingleOp);
+ } else if (delete.getFamilyCellMap().size() > 1) {
+ boolean has_delete_family = delete.getFamilyMap().entrySet().stream()
+ .flatMap(entry -> entry.getValue().stream()).anyMatch(
+ kv -> KeyValue.Type.codeToType(
+ kv.getType()) == KeyValue.Type.DeleteFamily || KeyValue.Type.codeToType(
+ kv.getType()) == KeyValue.Type.DeleteFamilyVersion);
+ if (!has_delete_family) {
+ return buildBatchOperation(tableNameString,
+ Collections.singletonList(delete), true,
+ resultMapSingleOp);
+ } else {
+ for (Map.Entry> entry : delete.getFamilyCellMap()
+ .entrySet()) {
+ byte[] family = entry.getKey();
+ String realTableName = getTargetTableName(tableNameString,
+ Bytes.toString(family), configuration);
+ // split delete
+ List cells = entry.getValue();
+ Delete del = new Delete(delete.getRow());
+ del.getFamilyCellMap().put(family, cells);
+ BatchOperation batch = buildBatchOperation(realTableName,
+ Collections.singletonList(del), false,
+ resultMapSingleOp);
+ BatchOperationResult tmpResults = batch.execute();
+ if (tmpResults.getResults().get(0) instanceof ObTableException) {
+ if (results != null) {
+ results[i] = tmpResults.getResults().get(0);
+ }
+ batchError.add((ObTableException) tmpResults.getResults().get(0), actions.get(i), null);
+ }
+ }
+ if (results != null && results[i] == null) {
+ results[i] = new Result();
+ }
+ return null;
+ }
+ } else {
+ byte[] family = delete.getFamilyCellMap().firstKey();
+ String realTableName = getTargetTableName(tableNameString, Bytes.toString(family), configuration);
+ return buildBatchOperation(realTableName,
+ Collections.singletonList(delete),
+ false, resultMapSingleOp);
+ }
+
+ }
+
+ private void compatOldServerBatch(final List extends Row> actions, final Object[] results, BatchError batchError)
+ throws Exception {
+ for (Row row : actions) {
+ if (!(row instanceof Put) && !(row instanceof Delete)) {
+ throw new FeatureNotSupportedException(
+ "not supported other type in batch yet,only support put and delete");
+ }
+ }
+ List puts = new LinkedList<>();
+ BatchOperation batch;
+ for (int i = 0; i < actions.size(); i++) {
+ if (actions.get(i) instanceof Put) {
+ batch = compatOldServerPut(actions, results, batchError, i, puts);
+ if (!puts.isEmpty()) {
+ i = i + puts.size() - 1;
+ }
+ puts.clear();
+ } else {
+ batch = compatOldServerDel(actions, results, batchError, i);
+ }
+ if (batch != null) {
+ BatchOperationResult tmpResults = batch.execute();
+ if (tmpResults.getResults().get(0) instanceof ObTableException) {
+ if (results != null) {
+ results[i] = tmpResults.getResults().get(0);
+ }
+ batchError.add((ObTableException) tmpResults.getResults().get(0), actions.get(i), null);
+ } else {
+ if (results != null) {
+ results[i] = new Result();
+ }
+ }
+ }
+ }
+ }
+
@Override
- public void batch(List extends Row> actions, Object[] results) {
- throw new FeatureNotSupportedException("not supported yet.");
+ public void batch(final List extends Row> actions, final Object[] results) throws IOException{
+ if (actions == null) {
+ return;
+ }
+ if (results != null) {
+ if (results.length != actions.size()) {
+ throw new AssertionError("results.length");
+ }
+ }
+ BatchError batchError = new BatchError();
+ obTableClient.setRuntimeBatchExecutor(executePool);
+ List resultMapSingleOp = new LinkedList<>();
+ if (!CompatibilityUtil.isBatchSupport()) {
+ try {
+ compatOldServerBatch(actions, results, batchError);
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ } else {
+ String realTableName = getTargetTableName(actions);
+ BatchOperation batch = buildBatchOperation(realTableName, actions,
+ tableNameString.equals(realTableName), resultMapSingleOp);
+ BatchOperationResult tmpResults;
+ try {
+ tmpResults = batch.execute();
+ } catch (Exception e) {
+ throw new IOException(e);
+ }
+ int index = 0;
+ for (int i = 0; i != actions.size(); ++i) {
+ if (tmpResults.getResults().get(index) instanceof ObTableException) {
+ if (results != null) {
+ results[i] = tmpResults.getResults().get(index);
+ }
+ batchError.add((ObTableException) tmpResults.getResults().get(index), actions.get(i), null);
+ } else {
+ if (results != null) {
+ results[i] = new Result();
+ }
+ }
+ index += resultMapSingleOp.get(i);
+ }
+ }
+ if (batchError.hasErrors()) {
+ throw batchError.makeException();
+ }
+ }
+
+ private String getTargetTableName(List extends Row> actions) {
+ byte[] family = null;
+ for (Row action : actions) {
+ if (action instanceof RowMutations || action instanceof RegionCoprocessorServiceExec) {
+ throw new FeatureNotSupportedException("not supported yet'");
+ } else {
+ Mutation mutation = (Mutation) action;
+ if (mutation.getFamilyCellMap().size() != 1) {
+ return getTargetTableName(tableNameString);
+ } else {
+ byte[] nextFamily = mutation.getFamilyCellMap().keySet().iterator().next();
+ if (family != null && !Arrays.equals(family, nextFamily)) {
+ return getTargetTableName(tableNameString);
+ } else if (family == null) {
+ family = nextFamily;
+ }
+ }
+ }
+ }
+ return getTargetTableName(tableNameString, Bytes.toString(family), configuration);
}
@Override
- public Object[] batch(List extends Row> actions) {
- throw new FeatureNotSupportedException("not supported yet.");
+ public Object[] batch(List extends Row> actions) throws IOException {
+ Object[] results = new Object[actions.size()];
+ batch(actions, results);
+ return results;
}
@Override
public void batchCallback(List extends Row> actions, Object[] results,
Batch.Callback callback) throws IOException,
InterruptedException {
- throw new FeatureNotSupportedException("not supported yet'");
+ try {
+ batch(actions, results);
+ } finally {
+ if (results != null) {
+ for (int i = 0; i < results.length; i++) {
+ if (!(results[i] instanceof ObTableException)) {
+ callback.update(null, actions.get(i).getRow(), (R) results[i]);
+ }
+ }
+ }
+ }
}
@Override
- public Object[] batchCallback(List extends Row> actions, Batch.Callback callback)
- throws IOException,
- InterruptedException {
- throw new FeatureNotSupportedException("not supported yet'");
+ public Object[] batchCallback(final List extends Row> actions,
+ final Batch.Callback callback) throws IOException,
+ InterruptedException {
+ Object[] results = new Object[actions.size()];
+ batchCallback(actions, results, callback);
+ return results;
}
public static int compareByteArray(byte[] bt1, byte[] bt2) {
@@ -540,7 +813,7 @@ public Result get(final Get get) throws IOException {
ServerCallable serverCallable = new ServerCallable(configuration,
obTableClient, tableNameString, get.getRow(), get.getRow(), operationTimeout) {
public Result call() throws IOException {
- List keyValueList = new ArrayList();
+ List keyValueList = new ArrayList<>();
byte[] family = new byte[] {};
ObTableQuery obTableQuery;
try {
@@ -550,6 +823,9 @@ public Result call() throws IOException {
// In a Get operation where the family map is greater than 1 or equal to 0,
// we handle this by appending the column family to the qualifier on the client side.
// The server can then use this information to filter the appropriate column families and qualifiers.
+ if (!get.getColumnFamilyTimeRange().isEmpty()) {
+ throw new FeatureNotSupportedException("setColumnFamilyTimeRange is only supported in single column family for now");
+ }
NavigableSet columnFilters = new TreeSet<>(Bytes.BYTES_COMPARATOR);
processColumnFilters(columnFilters, get.getFamilyMap());
obTableQuery = buildObTableQuery(get, columnFilters);
@@ -563,6 +839,17 @@ public Result call() throws IOException {
for (Map.Entry> entry : get.getFamilyMap()
.entrySet()) {
family = entry.getKey();
+ if (!get.getColumnFamilyTimeRange().isEmpty()) {
+ Map colFamTimeRangeMap = get.getColumnFamilyTimeRange();
+ if (colFamTimeRangeMap.size() > 1) {
+ throw new FeatureNotSupportedException("setColumnFamilyTimeRange is only supported in single column family for now");
+ } else if (colFamTimeRangeMap.get(family) == null) {
+ throw new IllegalArgumentException("Get family is not matched in ColumnFamilyTimeRange");
+ } else {
+ TimeRange tr = colFamTimeRangeMap.get(family);
+ get.setTimeRange(tr.getMin(), tr.getMax());
+ }
+ }
obTableQuery = buildObTableQuery(get, entry.getValue());
ObTableQueryRequest request = buildObTableQueryRequest(obTableQuery,
getTargetTableName(tableNameString, Bytes.toString(family),
@@ -591,8 +878,18 @@ public Result call() throws IOException {
@Override
public Result[] get(List gets) throws IOException {
Result[] results = new Result[gets.size()];
+ List> futures = new LinkedList<>();
+ for (int i = 0; i < gets.size(); i++) {
+ int index = i;
+ Future future = executePool.submit(() -> get(gets.get(index)));
+ futures.add(future);
+ }
for (int i = 0; i < gets.size(); i++) {
- results[i] = get(gets.get(i));
+ try {
+ results[i] = futures.get(i).get();
+ } catch (Exception e) {
+ throw new RuntimeException("gets occur error. index:{" + i + "}", e);
+ }
}
return results;
}
@@ -633,6 +930,9 @@ public ResultScanner call() throws IOException {
// In a Scan operation where the family map is greater than 1 or equal to 0,
// we handle this by appending the column family to the qualifier on the client side.
// The server can then use this information to filter the appropriate column families and qualifiers.
+ if (!scan.getColumnFamilyTimeRange().isEmpty()) {
+ throw new FeatureNotSupportedException("setColumnFamilyTimeRange is only supported in single column family for now");
+ }
NavigableSet columnFilters = new TreeSet<>(Bytes.BYTES_COMPARATOR);
processColumnFilters(columnFilters, scan.getFamilyMap());
filter = buildObHTableFilter(scan.getFilter(), scan.getTimeRange(),
@@ -649,6 +949,17 @@ public ResultScanner call() throws IOException {
for (Map.Entry> entry : scan.getFamilyMap()
.entrySet()) {
family = entry.getKey();
+ if (!scan.getColumnFamilyTimeRange().isEmpty()) {
+ Map colFamTimeRangeMap = scan.getColumnFamilyTimeRange();
+ if (colFamTimeRangeMap.size() > 1) {
+ throw new FeatureNotSupportedException("setColumnFamilyTimeRange is only supported in single column family for now");
+ } else if (colFamTimeRangeMap.get(family) == null) {
+ throw new IllegalArgumentException("Scan family is not matched in ColumnFamilyTimeRange");
+ } else {
+ TimeRange tr = colFamTimeRangeMap.get(family);
+ scan.setTimeRange(tr.getMin(), tr.getMax());
+ }
+ }
filter = buildObHTableFilter(scan.getFilter(), scan.getTimeRange(),
scan.getMaxVersions(), entry.getValue());
obTableQuery = buildObTableQuery(filter, scan);
@@ -799,67 +1110,11 @@ public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
private void innerDelete(Delete delete) throws IOException {
checkArgument(delete.getRow() != null, "row is null");
- List errorCodeList = new ArrayList();
- BatchOperationResult results = null;
-
try {
- checkFamilyViolation(delete.getFamilyMap().keySet(), false);
- if (delete.getFamilyMap().isEmpty()) {
- // For a Delete operation without any qualifiers, we construct a DeleteFamily request.
- // The server then performs the operation on all column families.
- KeyValue kv = new KeyValue(delete.getRow(), delete.getTimeStamp(),
- KeyValue.Type.DeleteFamily);
-
- BatchOperation batch = buildBatchOperation(tableNameString, Arrays.asList(kv),
- false, null);
- results = batch.execute();
- } else if (delete.getFamilyMap().size() > 1) {
- // Currently, the Delete Family operation type cannot transmit qualifiers to the server.
- // As a result, the server cannot identify which families need to be deleted.
- // Therefore, this process is handled sequentially.
- boolean hasDeleteFamily = false;
- for (Map.Entry> entry : delete.getFamilyMap().entrySet()) {
- for (KeyValue kv : entry.getValue()) {
- if (KeyValue.Type.codeToType(kv.getType()) == KeyValue.Type.DeleteFamily) {
- hasDeleteFamily = true;
- break;
- }
- }
- if (hasDeleteFamily) {
- break;
- }
- }
- if (!hasDeleteFamily) {
- BatchOperation batch = buildBatchOperation(tableNameString,
- delete.getFamilyMap(), false, null);
- results = batch.execute();
- } else {
- for (Map.Entry> entry : delete.getFamilyMap().entrySet()) {
- BatchOperation batch = buildBatchOperation(
- getTargetTableName(tableNameString, Bytes.toString(entry.getKey()),
- configuration), entry.getValue(), false, null);
- results = batch.execute();
- }
- }
- } else {
- Map.Entry> entry = delete.getFamilyMap().entrySet()
- .iterator().next();
-
- BatchOperation batch = buildBatchOperation(
- getTargetTableName(tableNameString, Bytes.toString(entry.getKey()),
- configuration), entry.getValue(), false, null);
- results = batch.execute();
- }
-
- errorCodeList = results.getErrorCodeList();
- boolean hasError = results.hasError();
- if (hasError) {
- throw results.getFirstException();
- }
+ batch(Collections.singletonList(delete));
} catch (Exception e) {
- logger.error(LCD.convert("01-00004"), tableNameString, errorCodeList, e);
- throw new IOException("delete table " + tableNameString + " error codes "
- + errorCodeList, e);
+ logger.error(LCD.convert("01-00004"), tableNameString, e);
+ throw new IOException("delete table " + tableNameString + " error.", e);
}
}
@@ -1136,77 +1391,34 @@ public boolean isAutoFlush() {
public void flushCommits() throws IOException {
try {
+ if (writeBuffer.isEmpty()){
+ return;
+ }
+ Map exceptionRowMap = new LinkedHashMap();
boolean[] resultSuccess = new boolean[writeBuffer.size()];
try {
- Map, List>> familyMap = new HashMap, List>>();
- for (int i = 0; i < writeBuffer.size(); i++) {
- Put aPut = writeBuffer.get(i);
- Map> innerFamilyMap = aPut.getFamilyMap();
- if (innerFamilyMap.size() > 1) {
- // Bypass logic: directly construct BatchOperation for puts with family map size > 1
- try {
- BatchOperation batch = buildBatchOperation(this.tableNameString,
- innerFamilyMap, false, null);
- BatchOperationResult results = batch.execute();
-
- boolean hasError = results.hasError();
- resultSuccess[i] = !hasError;
- if (hasError) {
- throw results.getFirstException();
- }
- } catch (Exception e) {
- logger.error(LCD.convert("01-00008"), tableNameString, null, autoFlush,
- writeBuffer.size(), e);
- throw new IOException("put table " + tableNameString + " error codes "
- + null + "auto flush " + autoFlush
- + " current buffer size " + writeBuffer.size(), e);
- }
- } else {
- // Existing logic for puts with family map size = 1
- for (Map.Entry> entry : innerFamilyMap.entrySet()) {
- String family = Bytes.toString(entry.getKey());
- Pair, List> keyValueWithIndex = familyMap
- .get(family);
- if (keyValueWithIndex == null) {
- keyValueWithIndex = new Pair, List>(
- new ArrayList(), new ArrayList());
- familyMap.put(family, keyValueWithIndex);
- }
- keyValueWithIndex.getFirst().add(i);
- keyValueWithIndex.getSecond().addAll(entry.getValue());
- }
- }
- }
- for (Map.Entry, List>> entry : familyMap
- .entrySet()) {
- List errorCodeList = new ArrayList(entry.getValue()
- .getSecond().size());
- try {
- String targetTableName = getTargetTableName(this.tableNameString,
- entry.getKey(), configuration);
-
- BatchOperation batch = buildBatchOperation(targetTableName, entry
- .getValue().getSecond(), false, null);
- BatchOperationResult results = batch.execute();
-
- errorCodeList = results.getErrorCodeList();
- boolean hasError = results.hasError();
- for (Integer index : entry.getValue().getFirst()) {
- resultSuccess[index] = !hasError;
+ String realTableName = getTargetTableName(writeBuffer);
+ List resultMapSingleOp = new LinkedList<>();
+ BatchOperation batch = buildBatchOperation(realTableName, writeBuffer, tableNameString.equals(realTableName), resultMapSingleOp);
+ BatchOperationResult results = batch.execute();
+ if (results != null) {
+ int index = 0;
+ for (int i = 0; i != resultSuccess.length; ++i) {
+ if (results.getResults().get(index) instanceof ObTableException) {
+ resultSuccess[i] = false;
+ exceptionRowMap.put((ObTableException)results.getResults().get(index), writeBuffer.get(i));
+ } else {
+ resultSuccess[i] = true;
}
- if (hasError) {
- throw results.getFirstException();
- }
- } catch (Exception e) {
- logger.error(LCD.convert("01-00008"), tableNameString, errorCodeList,
- autoFlush, writeBuffer.size(), e);
- throw new IOException("put table " + tableNameString + " error codes "
- + errorCodeList + "auto flush " + autoFlush
- + " current buffer size " + writeBuffer.size(), e);
+ index += resultMapSingleOp.get(i);
}
-
}
-
+ } catch (Exception e) {
+ logger.error(LCD.convert("01-00008"), tableNameString, null, autoFlush,
+ writeBuffer.size(), e);
+ throw new IOException("put table " + tableNameString + " error codes " + null
+ + "auto flush " + autoFlush + " current buffer size "
+ + writeBuffer.size(), e);
} finally {
// mutate list so that it is empty for complete success, or contains
// only failed records results are returned in the same order as the
@@ -1218,6 +1430,12 @@ public void flushCommits() throws IOException {
writeBuffer.remove(i);
}
}
+ if (!exceptionRowMap.isEmpty()) {
+ exceptionRowMap.forEach((e, row)->{
+ logger.error(LCD.convert("01-00008"), row, tableNameString, autoFlush,
+ writeBuffer.size(), e);
+ });
+ }
}
} finally {
if (clearBufferOnFail) {
@@ -1528,14 +1746,16 @@ private ObTableQuery buildObTableQuery(ObHTableFilter filter, byte[] start,
boolean includeStart, byte[] stop, boolean includeStop,
boolean isReversed) {
ObNewRange obNewRange = new ObNewRange();
-
+ ObBorderFlag obBorderFlag = new ObBorderFlag();
if (Arrays.equals(start, HConstants.EMPTY_BYTE_ARRAY)) {
obNewRange.setStartKey(ObRowKey.getInstance(ObObj.getMin(), ObObj.getMin(),
ObObj.getMin()));
} else if (includeStart) {
obNewRange.setStartKey(ObRowKey.getInstance(start, ObObj.getMin(), ObObj.getMin()));
+ obBorderFlag.setInclusiveStart();
} else {
obNewRange.setStartKey(ObRowKey.getInstance(start, ObObj.getMax(), ObObj.getMax()));
+ obBorderFlag.unsetInclusiveStart();
}
if (Arrays.equals(stop, HConstants.EMPTY_BYTE_ARRAY)) {
@@ -1543,10 +1763,13 @@ private ObTableQuery buildObTableQuery(ObHTableFilter filter, byte[] start,
ObObj.getMax()));
} else if (includeStop) {
obNewRange.setEndKey(ObRowKey.getInstance(stop, ObObj.getMax(), ObObj.getMax()));
+ obBorderFlag.setInclusiveEnd();
} else {
obNewRange.setEndKey(ObRowKey.getInstance(stop, ObObj.getMin(), ObObj.getMin()));
+ obBorderFlag.unsetInclusiveEnd();
}
ObTableQuery obTableQuery = new ObTableQuery();
+ obNewRange.setBorderFlag(obBorderFlag);
if (isReversed) {
obTableQuery.setScanOrder(ObScanOrder.Reverse);
}
@@ -1623,62 +1846,54 @@ public static ObTableBatchOperation buildObTableBatchOperation(List ke
return batch;
}
- private ObTableBatchOperation buildObTableBatchOperation(Map> familyMap,
- boolean putToAppend,
- List qualifiers) {
- ObTableBatchOperation batch = new ObTableBatchOperation();
- for (Map.Entry> entry : familyMap.entrySet()) {
- byte[] family = entry.getKey();
- List keyValueList = entry.getValue();
- for (KeyValue kv : keyValueList) {
- if (qualifiers != null) {
- qualifiers
- .add((Bytes.toString(family) + "." + Bytes.toString(kv.getQualifier()))
- .getBytes());
- }
- KeyValue new_kv = modifyQualifier(kv,
- (Bytes.toString(family) + "." + Bytes.toString(kv.getQualifier())).getBytes());
- batch.addTableOperation(buildObTableOperation(new_kv, putToAppend));
- }
- }
- batch.setSameType(true);
- batch.setSamePropertiesNames(true);
- return batch;
- }
-
private com.alipay.oceanbase.rpc.mutation.Mutation buildMutation(KeyValue kv,
- boolean putToAppend) {
+ ObTableOperationType operationType,
+ boolean isTableGroup) {
KeyValue.Type kvType = KeyValue.Type.codeToType(kv.getType());
- switch (kvType) {
- case Put:
- ObTableOperationType operationType;
- if (putToAppend) {
- operationType = APPEND;
- } else {
- operationType = INSERT_OR_UPDATE;
- }
+ switch (operationType) {
+ case INSERT_OR_UPDATE:
+ case APPEND:
return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(operationType,
ROW_KEY_COLUMNS,
new Object[] { kv.getRow(), kv.getQualifier(), kv.getTimestamp() }, V_COLUMNS,
new Object[] { kv.getValue() });
- case Delete:
- return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL, ROW_KEY_COLUMNS,
- new Object[] { kv.getRow(), kv.getQualifier(), kv.getTimestamp() }, null, null);
- case DeleteColumn:
- return com.alipay.oceanbase.rpc.mutation.Mutation
- .getInstance(DEL, ROW_KEY_COLUMNS,
- new Object[] { kv.getRow(), kv.getQualifier(), -kv.getTimestamp() }, null,
- null);
- case DeleteFamily:
- return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL, ROW_KEY_COLUMNS,
- new Object[] { kv.getRow(), null, -kv.getTimestamp() }, null, null);
+ case DEL:
+ switch (kvType) {
+ case Delete:
+ return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL,
+ ROW_KEY_COLUMNS,
+ new Object[] { kv.getRow(), kv.getQualifier(), kv.getTimestamp() },
+ null, null);
+ case Maximum:
+ return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL,
+ ROW_KEY_COLUMNS,
+ new Object[] { kv.getRow(), null, -kv.getTimestamp() }, null, null);
+ case DeleteColumn:
+ return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL,
+ ROW_KEY_COLUMNS,
+ new Object[] { kv.getRow(), kv.getQualifier(), -kv.getTimestamp() },
+ null, null);
+ case DeleteFamily:
+ return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(DEL,
+ ROW_KEY_COLUMNS,
+ new Object[] { kv.getRow(), isTableGroup ? kv.getQualifier() : null,
+ -kv.getTimestamp() }, null, null);
+ case DeleteFamilyVersion:
+ return com.alipay.oceanbase.rpc.mutation.Mutation.getInstance(
+ DEL,
+ ROW_KEY_COLUMNS,
+ new Object[] { kv.getRow(), isTableGroup ? kv.getQualifier() : null,
+ kv.getTimestamp() }, null, null);
+ default:
+ throw new IllegalArgumentException("illegal mutation type " + kvType);
+ }
default:
- throw new IllegalArgumentException("illegal mutation type " + kvType);
+ throw new IllegalArgumentException("illegal mutation type " + operationType);
}
}
private KeyValue modifyQualifier(KeyValue original, byte[] newQualifier) {
- // Extract existing components
+ // Extract existing components
byte[] row = original.getRow();
byte[] family = original.getFamily();
byte[] value = original.getValue();
@@ -1689,36 +1904,67 @@ private KeyValue modifyQualifier(KeyValue original, byte[] newQualifier) {
value);
}
- private BatchOperation buildBatchOperation(String tableName,
- Map> familyMap,
- boolean putToAppend, List qualifiers) {
+ private BatchOperation buildBatchOperation(String tableName, List extends Row> actions,
+ boolean isTableGroup, List resultMapSingleOp)
+ throws FeatureNotSupportedException,
+ IllegalArgumentException {
BatchOperation batch = obTableClient.batchOperation(tableName);
-
- for (Map.Entry> entry : familyMap.entrySet()) {
- byte[] family = entry.getKey();
- List keyValueList = entry.getValue();
- for (KeyValue kv : keyValueList) {
- if (qualifiers != null) {
- qualifiers.add(kv.getQualifier());
+ int posInList = -1;
+ int singleOpResultNum;
+ for (Row row : actions) {
+ singleOpResultNum = 0;
+ posInList++;
+ if (row instanceof Put) {
+ Put put = (Put) row;
+ if (put.isEmpty()) {
+ throw new IllegalArgumentException("No columns to insert for #"
+ + (posInList + 1) + " item");
}
- KeyValue new_kv = modifyQualifier(kv,
- (Bytes.toString(family) + "." + Bytes.toString(kv.getQualifier())).getBytes());
- batch.addOperation(buildMutation(new_kv, putToAppend));
- }
- }
-
- batch.setEntityType(ObTableEntityType.HKV);
- return batch;
- }
-
- private BatchOperation buildBatchOperation(String tableName, List keyValueList,
- boolean putToAppend, List qualifiers) {
- BatchOperation batch = obTableClient.batchOperation(tableName);
- for (KeyValue kv : keyValueList) {
- if (qualifiers != null) {
- qualifiers.add(kv.getQualifier());
+ for (Map.Entry> entry : put.getFamilyMap().entrySet()) {
+ byte[] family = entry.getKey();
+ List keyValueList = entry.getValue();
+ for (KeyValue kv : keyValueList) {
+ singleOpResultNum++;
+ if (isTableGroup) {
+ KeyValue new_kv = modifyQualifier(kv,
+ (Bytes.toString(family) + "." + Bytes.toString(kv.getQualifier()))
+ .getBytes());
+ batch
+ .addOperation(buildMutation(new_kv, INSERT_OR_UPDATE, isTableGroup));
+ } else {
+ batch.addOperation(buildMutation(kv, INSERT_OR_UPDATE, isTableGroup));
+ }
+ }
+ }
+ } else if (row instanceof Delete) {
+ Delete delete = (Delete) row;
+ if (delete.isEmpty()) {
+ singleOpResultNum++;
+ KeyValue kv = new KeyValue(delete.getRow(), delete.getTimeStamp(),
+ KeyValue.Type.Maximum);
+ batch.addOperation(buildMutation(kv, DEL, isTableGroup));
+ } else {
+ for (Map.Entry> entry : delete.getFamilyMap().entrySet()) {
+ byte[] family = entry.getKey();
+ List keyValueList = entry.getValue();
+ for (KeyValue kv : keyValueList) {
+ singleOpResultNum++;
+ if (isTableGroup) {
+ KeyValue new_kv = modifyQualifier(kv,
+ (Bytes.toString(family) + "." + Bytes.toString(kv
+ .getQualifier())).getBytes());
+ batch.addOperation(buildMutation(new_kv, DEL, true));
+ } else {
+ batch.addOperation(buildMutation(kv, DEL, false));
+ }
+ }
+ }
+ }
+ } else {
+ throw new FeatureNotSupportedException(
+ "not supported other type in batch yet,only support put and delete");
}
- batch.addOperation(buildMutation(kv, putToAppend));
+ resultMapSingleOp.add(singleOpResultNum);
}
batch.setEntityType(ObTableEntityType.HKV);
return batch;
diff --git a/src/main/java/com/alipay/oceanbase/hbase/OHTablePool.java b/src/main/java/com/alipay/oceanbase/hbase/OHTablePool.java
index d4b92d08..507a09b1 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/OHTablePool.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/OHTablePool.java
@@ -49,6 +49,7 @@
public class OHTablePool implements Closeable {
+ private String originTabelName = null;
private final PoolMap tables;
private final int maxSize;
private final PoolMap.PoolType poolType;
@@ -314,6 +315,9 @@ int getCurrentPoolSize(String tableName) {
* @param paramUrl the table root server http url
*/
public void setParamUrl(final String tableName, String paramUrl) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_PARAM_URL, Bytes.toBytes(paramUrl));
}
@@ -334,6 +338,9 @@ public String getParamUrl(final String tableName) {
* @param fullUserName the table login username
*/
public void setFullUserName(final String tableName, final String fullUserName) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_FULL_USER_NAME, Bytes.toBytes(fullUserName));
}
@@ -354,6 +361,9 @@ public String getFullUserName(final String tableName) {
* @param password the table login password
*/
public void setPassword(final String tableName, final String password) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_PASSWORD, Bytes.toBytes(password));
}
@@ -374,6 +384,9 @@ public String getPassword(final String tableName) {
* @param sysUserName the sys username
*/
public void setSysUserName(final String tableName, final String sysUserName) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_SYS_USER_NAME, Bytes.toBytes(sysUserName));
}
@@ -394,6 +407,9 @@ public String getSysUserName(final String tableName) {
* @param sysPassword the sys user password
*/
public void setSysPassword(final String tableName, final String sysPassword) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_SYS_PASSWORD, Bytes.toBytes(sysPassword));
}
@@ -481,6 +497,10 @@ public long getWriteBufferSize(String tableName) {
.toLong(attr);
}
+ public String getOriginTableName() {
+ return this.originTabelName;
+ }
+
/**
* Sets the operation timeout for the specified tables in this pool.
*
@@ -520,6 +540,9 @@ public int getOperationTimeout(String tableName) {
* @param odpAddr ODP address
*/
public void setOdpAddr(final String tableName, String odpAddr) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_ODP_ADDR, Bytes.toBytes(odpAddr));
}
@@ -545,6 +568,9 @@ public String getOdpAddr(String tableName) {
* @param odpPort ODP port
*/
public void setOdpPort(final String tableName, int odpPort) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_ODP_PORT, Bytes.toBytes(odpPort));
}
@@ -564,6 +590,9 @@ public int getOdpPort(String tableName) {
* @param odpMode ODP mode
*/
public void setOdpMode(final String tableName, boolean odpMode) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_ODP_MODE, Bytes.toBytes(odpMode));
}
@@ -583,6 +612,9 @@ public boolean getOdpMode(String tableName) {
* @param database ODP database name
*/
public void setDatabase(final String tableName, String database) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableAttribute(tableName, HBASE_OCEANBASE_DATABASE, Bytes.toBytes(database));
}
@@ -653,6 +685,9 @@ public Object getTableExtendAttribute(String tableName, String attributeName) {
}
public void setRuntimeBatchExecutor(String tableName, ExecutorService runtimeBatchExecutor) {
+ if (originTabelName == null) {
+ originTabelName = tableName;
+ }
setTableExtendAttribute(tableName, HBASE_OCEANBASE_BATCH_EXECUTOR, runtimeBatchExecutor);
}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java b/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java
index bda64927..e10ef0b1 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java
@@ -159,4 +159,8 @@ public final class OHConstants {
public static final int MAX_KEYVALUE_SIZE_DEFAULT = -1;
+ public static final String SOCKET_TIMEOUT = "ipc.socket.timeout";
+
+ public static final int DEFAULT_SOCKET_TIMEOUT = 20000; // 20 seconds
+
}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtils.java b/src/main/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtils.java
index e58d2590..296f70bc 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtils.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtils.java
@@ -20,12 +20,14 @@
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
import java.lang.reflect.Field;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
+import java.util.Set;
@InterfaceAudience.Private
public class HBaseFilterUtils {
@@ -40,15 +42,21 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream, Filte
throws IOException {
if (filter == null) {
throw new IllegalArgumentException("Filter is null");
+ } else if (filter instanceof DependentColumnFilter) {
+ toParseableByteArray(byteStream, (DependentColumnFilter) filter);
} else if (filter instanceof CompareFilter) {
- // RowFilter, ValueFilter, QualifierFilter
+ // RowFilter, ValueFilter, QualifierFilter, FamilyFilter
toParseableByteArray(byteStream, (CompareFilter) filter);
+ } else if (filter instanceof SingleColumnValueExcludeFilter) {
+ toParseableByteArray(byteStream, (SingleColumnValueExcludeFilter) filter);
} else if (filter instanceof SingleColumnValueFilter) {
toParseableByteArray(byteStream, (SingleColumnValueFilter) filter);
} else if (filter instanceof PageFilter) {
toParseableByteArray(byteStream, (PageFilter) filter);
} else if (filter instanceof ColumnCountGetFilter) {
toParseableByteArray(byteStream, (ColumnCountGetFilter) filter);
+ } else if (filter instanceof FirstKeyValueMatchingQualifiersFilter) {
+ toParseableByteArray(byteStream, (FirstKeyValueMatchingQualifiersFilter) filter);
} else if (filter instanceof PrefixFilter) {
toParseableByteArray(byteStream, (PrefixFilter) filter);
} else if (filter instanceof FilterList) {
@@ -63,8 +71,18 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream, Filte
toParseableByteArray(byteStream, (FirstKeyOnlyFilter) filter);
} else if (filter instanceof KeyOnlyFilter) {
toParseableByteArray(byteStream, (KeyOnlyFilter) filter);
+ } else if (filter instanceof FuzzyRowFilter) {
+ toParseableByteArray(byteStream, (FuzzyRowFilter) filter);
} else if (filter instanceof TimestampsFilter) {
toParseableByteArray(byteStream, (TimestampsFilter) filter);
+ } else if (filter instanceof MultiRowRangeFilter) {
+ toParseableByteArray(byteStream, (MultiRowRangeFilter) filter);
+ } else if (filter instanceof InclusiveStopFilter) {
+ toParseableByteArray(byteStream, (InclusiveStopFilter) filter);
+ } else if (filter instanceof ColumnRangeFilter) {
+ toParseableByteArray(byteStream, (ColumnRangeFilter) filter);
+ } else if (filter instanceof MultipleColumnPrefixFilter) {
+ toParseableByteArray(byteStream, (MultipleColumnPrefixFilter) filter);
} else if (filter instanceof SkipFilter) {
toParseableByteArray(byteStream, (SkipFilter) filter);
} else if (filter instanceof WhileMatchFilter) {
@@ -149,6 +167,26 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
byteStream.write(')');
}
+ // SingleColumnValueExcludeFilter('cf1','col1',=,'binary:123',true,true)
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ SingleColumnValueExcludeFilter filter)
+ throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write("('".getBytes());
+ writeBytesWithEscape(byteStream, filter.getFamily());
+ byteStream.write("','".getBytes());
+ writeBytesWithEscape(byteStream, filter.getQualifier());
+ byteStream.write("',".getBytes());
+ byteStream.write(toParseableByteArray(filter.getOperator()));
+ byteStream.write(',');
+ toParseableByteArray(byteStream, filter.getComparator());
+ byteStream.write(',');
+ byteStream.write(Boolean.toString(filter.getFilterIfMissing()).getBytes());
+ byteStream.write(',');
+ byteStream.write(Boolean.toString(filter.getLatestVersionOnly()).getBytes());
+ byteStream.write(')');
+ }
+
// PageFilter(100);
private static void toParseableByteArray(ByteArrayOutputStream byteStream, PageFilter filter)
throws IOException {
@@ -167,6 +205,34 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
byteStream.write(')');
}
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ DependentColumnFilter filter) throws IOException {
+ // DependentColumnFilter '(' family ',' qualifier ',' BOOL_VALUE ')'
+ if (filter.getComparator() == null) {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write("('".getBytes());
+ writeBytesWithEscape(byteStream, filter.getFamily());
+ byteStream.write("','".getBytes());
+ writeBytesWithEscape(byteStream, filter.getQualifier());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(filter.getDropDependentColumn()).getBytes());
+ byteStream.write(')');
+ } else { // DependentColumnFilter '(' family ',' qualifier ',' BOOL_VALUE ',' compare_op ',' comparator ')'
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write("('".getBytes());
+ writeBytesWithEscape(byteStream, filter.getFamily());
+ byteStream.write("','".getBytes());
+ writeBytesWithEscape(byteStream, filter.getQualifier());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(filter.getDropDependentColumn()).getBytes());
+ byteStream.write(',');
+ byteStream.write(toParseableByteArray(filter.getOperator()));
+ byteStream.write(',');
+ toParseableByteArray(byteStream, filter.getComparator());
+ byteStream.write(')');
+ }
+ }
+
private static void toParseableByteArray(ByteArrayOutputStream byteStream,
ColumnPaginationFilter filter) throws IOException {
byteStream.write(filter.getClass().getSimpleName().getBytes());
@@ -213,6 +279,35 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream, KeyOn
byteStream.write(')');
}
+ // FuzzyRowFilter('abc','101','ddd','010');
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream, FuzzyRowFilter filter) throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+
+ List> fuzzyKeysData;
+ try {
+ Field field = filter.getClass().getDeclaredField("fuzzyKeysData");
+ field.setAccessible(true);
+ fuzzyKeysData = (List>)field.get(filter);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ for (int i = 0; i < fuzzyKeysData.size(); i ++) {
+ Pair data = fuzzyKeysData.get(i);
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, data.getFirst());
+ byteStream.write("'".getBytes());
+ byteStream.write(',');
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, data.getSecond());
+ byteStream.write("'".getBytes());
+ if (i < fuzzyKeysData.size() - 1) {
+ byteStream.write(',');
+ }
+ }
+ byteStream.write(')');
+ }
+
private static void toParseableByteArray(ByteArrayOutputStream byteStream, TimestampsFilter filter) throws IOException {
byteStream.write(filter.getClass().getSimpleName().getBytes());
byteStream.write('(');
@@ -234,6 +329,81 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream, Times
byteStream.write(')');
}
+ // MultiRowRangeFilter('a',true,'b',false,'c',true,'d',false);
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ MultiRowRangeFilter filter) throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+
+ List ranges = filter.getRowRanges();
+ for (int i = 0; i < ranges.size(); i++) {
+ MultiRowRangeFilter.RowRange range = ranges.get(i);
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, range.getStartRow());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(range.isStartRowInclusive()).getBytes());
+ byteStream.write(',');
+
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, range.getStopRow());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(range.isStopRowInclusive()).getBytes());
+ if (i < ranges.size() - 1) {
+ byteStream.write(',');
+ }
+ }
+ byteStream.write(')');
+ }
+
+ // InclusiveStopFilter('aaa');
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ InclusiveStopFilter filter) throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+ byteStream.write('\'');
+ writeBytesWithEscape(byteStream, filter.getStopRowKey());
+ byteStream.write('\'');
+ byteStream.write(')');
+ }
+
+ // ColumnRangeFilter('a',true,'b',false);
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ ColumnRangeFilter filter) throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, filter.getMinColumn());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(filter.getMinColumnInclusive()).getBytes());
+ byteStream.write(',');
+
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, filter.getMaxColumn());
+ byteStream.write("',".getBytes());
+ byteStream.write(Boolean.toString(filter.getMaxColumnInclusive()).getBytes());
+ byteStream.write(')');
+ }
+
+ // MultipleColumnPrefixFilter('a','b','d');
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ MultipleColumnPrefixFilter filter) throws IOException {
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+
+ byte[][] ranges = filter.getPrefix();
+ for (int i = 0; i < ranges.length; i++) {
+ byte[] range = ranges[i];
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, range);
+ byteStream.write("'".getBytes());
+ if (i < ranges.length - 1) {
+ byteStream.write(',');
+ }
+ }
+ byteStream.write(')');
+ }
+
// ColumnCountGetFilter(100)
private static void toParseableByteArray(ByteArrayOutputStream byteStream,
ColumnCountGetFilter filter) throws IOException {
@@ -243,6 +413,32 @@ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
byteStream.write(')');
}
+ // FirstKeyValueMatchingQualifiersFilter('q1','q2')
+ private static void toParseableByteArray(ByteArrayOutputStream byteStream,
+ FirstKeyValueMatchingQualifiersFilter filter) throws IOException {
+ Set qualifiers;
+ try {
+ Field field = filter.getClass().getDeclaredField("qualifiers");
+ field.setAccessible(true);
+ qualifiers = (Set)field.get(filter);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ byteStream.write(filter.getClass().getSimpleName().getBytes());
+ byteStream.write('(');
+ int i = 0;
+ for (byte[] qualifier: qualifiers) {
+ byteStream.write("'".getBytes());
+ writeBytesWithEscape(byteStream, qualifier);
+ byteStream.write("'".getBytes());
+ if (i < qualifiers.size() - 1) {
+ byteStream.write(',');
+ }
+ i++;
+ }
+ byteStream.write(')');
+ }
+
// PrefixFilter('prefix');
private static void toParseableByteArray(ByteArrayOutputStream byteStream, PrefixFilter filter)
throws IOException {
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/BatchError.java b/src/main/java/com/alipay/oceanbase/hbase/util/BatchError.java
new file mode 100644
index 00000000..49fe17e9
--- /dev/null
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/BatchError.java
@@ -0,0 +1,39 @@
+package com.alipay.oceanbase.hbase.util;
+
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
+import org.apache.hadoop.hbase.client.Row;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BatchError {
+ private final List throwables = new ArrayList();
+ private final List actions = new ArrayList();
+ private final List addresses = new ArrayList();
+
+ public synchronized void add(Throwable ex, Row row, ServerName serverName) {
+ if (row == null) {
+ throw new IllegalArgumentException("row cannot be null. location=" + serverName);
+ }
+
+ throwables.add(ex);
+ actions.add(row);
+ addresses.add(serverName != null ? serverName.toString() : "null");
+ }
+
+ public boolean hasErrors() {
+ return !throwables.isEmpty();
+ }
+
+ public synchronized RetriesExhaustedWithDetailsException makeException() {
+ return new RetriesExhaustedWithDetailsException(new ArrayList(throwables),
+ new ArrayList(actions), new ArrayList(addresses));
+ }
+
+ public synchronized void clear() {
+ throwables.clear();
+ actions.clear();
+ addresses.clear();
+ }
+}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/CompatibilityUtil.java b/src/main/java/com/alipay/oceanbase/hbase/util/CompatibilityUtil.java
new file mode 100644
index 00000000..39db637c
--- /dev/null
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/CompatibilityUtil.java
@@ -0,0 +1,9 @@
+package com.alipay.oceanbase.hbase.util;
+
+import com.alipay.oceanbase.rpc.ObGlobal;
+
+public class CompatibilityUtil {
+ public static boolean isBatchSupport() {
+ return ObGlobal.OB_VERSION > ObGlobal.OB_VERSION_4_3_4_0;
+ }
+}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/OHBufferedMutatorImpl.java b/src/main/java/com/alipay/oceanbase/hbase/util/OHBufferedMutatorImpl.java
index 0cef7e62..42e44737 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/util/OHBufferedMutatorImpl.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/OHBufferedMutatorImpl.java
@@ -18,14 +18,11 @@
package com.alipay.oceanbase.hbase.util;
import com.alipay.oceanbase.hbase.OHTable;
-import com.alipay.oceanbase.rpc.ObTableClient;
-import com.alipay.oceanbase.rpc.protocol.payload.impl.execute.*;
+import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
-import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import java.io.IOException;
@@ -34,54 +31,53 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
import static com.alipay.oceanbase.rpc.util.TableClientLoggerFactory.LCD;
@InterfaceAudience.Private
public class OHBufferedMutatorImpl implements BufferedMutator {
- private static final Logger LOGGER = TableHBaseLoggerFactory
- .getLogger(OHBufferedMutatorImpl.class);
+ private static final Logger LOGGER = TableHBaseLoggerFactory
+ .getLogger(OHBufferedMutatorImpl.class);
- private final ExceptionListener listener;
+ private final ExceptionListener listener;
- protected final ObTableClient obTableClient;
- private final TableName tableName;
- private volatile Configuration conf;
- private final OHConnectionConfiguration connectionConfig;
+ private final OHTable ohTable;
+ private final TableName tableName;
+ private volatile Configuration conf;
- final ConcurrentLinkedQueue asyncWriteBuffer = new ConcurrentLinkedQueue();
- AtomicLong currentAsyncBufferSize = new AtomicLong(0);
+ @VisibleForTesting
+ final ConcurrentLinkedQueue asyncWriteBuffer = new ConcurrentLinkedQueue();
+ @VisibleForTesting
+ AtomicLong currentAsyncBufferSize = new AtomicLong(0);
- private AtomicReference> type = new AtomicReference<>(null);
- private final long writeBufferSize;
- private final int maxKeyValueSize;
- private boolean closed = false;
- private final ExecutorService pool;
- private final int rpcTimeout;
+ private long writeBufferSize;
+ private final int maxKeyValueSize;
+ private boolean closed = false;
+ private final ExecutorService pool;
+ private int rpcTimeout;
+ private int operationTimeout;
public OHBufferedMutatorImpl(OHConnectionImpl ohConnection, BufferedMutatorParams params)
throws IOException {
if (ohConnection == null || ohConnection.isClosed()) {
throw new IllegalArgumentException("Connection is null or closed.");
}
- // create a ObTableClient to do rpc operations
- this.obTableClient = ObTableClientManager.getOrCreateObTableClient(ohConnection
- .getOHConnectionConfiguration());
-
// init params in OHBufferedMutatorImpl
this.tableName = params.getTableName();
this.conf = ohConnection.getConfiguration();
- this.connectionConfig = ohConnection.getOHConnectionConfiguration();
this.listener = params.getListener();
+
+ OHConnectionConfiguration connectionConfig = ohConnection.getOHConnectionConfiguration();
this.pool = params.getPool();
- this.obTableClient.setRuntimeBatchExecutor(pool);
+ this.rpcTimeout = connectionConfig.getRpcTimeout();
+ this.operationTimeout = connectionConfig.getOperationTimeout();
this.writeBufferSize = params.getWriteBufferSize() != OHConnectionImpl.BUFFERED_PARAM_UNSET ? params
.getWriteBufferSize() : connectionConfig.getWriteBufferSize();
this.maxKeyValueSize = params.getMaxKeyValueSize() != OHConnectionImpl.BUFFERED_PARAM_UNSET ? params
.getMaxKeyValueSize() : connectionConfig.getMaxKeyValueSize();
- this.rpcTimeout = connectionConfig.getRpcTimeout();
- this.obTableClient.setRpcExecuteTimeout(rpcTimeout);
+
+ // create an OHTable object to do batch work
+ this.ohTable = new OHTable(tableName, ohConnection, connectionConfig, pool);
}
@Override
@@ -119,38 +115,37 @@ public void mutate(List extends Mutation> mutations) throws IOException {
}
long toAddSize = 0;
- // check if every mutation's family is the same
- // check if mutations are the same type
for (Mutation m : mutations) {
- OHTable.checkFamilyViolation(m.getFamilyMap().keySet(), true);
- validateInsUpAndDelete(m);
- Class> curType = m.getClass();
- // set the type of this BufferedMutator
- if (type.get() == null) {
- type.compareAndSet(null, mutations.get(0).getClass());
- }
- if (!type.get().equals(curType)) {
- throw new IllegalArgumentException("Not support different type in one batch.");
- }
+ validateOperation(m);
toAddSize += m.heapSize();
}
currentAsyncBufferSize.addAndGet(toAddSize);
asyncWriteBuffer.addAll(mutations);
- asyncExecute(false);
+ if (currentAsyncBufferSize.get() > writeBufferSize) {
+ execute(false);
+ }
+
}
/**
* Check whether the mutation is Put or Delete in 1.x
* @param mt - mutation operation
*/
- private void validateInsUpAndDelete(Mutation mt) throws IllegalArgumentException {
+ private void validateOperation(Mutation mt) throws IllegalArgumentException {
+ if (mt == null) {
+ throw new IllegalArgumentException("Mutation operation cannot be null");
+ }
if (!(mt instanceof Put) && !(mt instanceof Delete)) {
throw new IllegalArgumentException("Only support for Put and Delete for now.");
}
if (mt instanceof Put) {
+ // family empty check is in validatePut
HTable.validatePut((Put) mt, maxKeyValueSize);
+ OHTable.checkFamilyViolation(mt.getFamilyMap().keySet(), true);
+ } else {
+ OHTable.checkFamilyViolation(mt.getFamilyMap().keySet(), false);
}
}
@@ -161,91 +156,49 @@ private void validateInsUpAndDelete(Mutation mt) throws IllegalArgumentException
* @param flushAll - if true, sends all the writes and wait for all of them to finish before
* returning.
*/
- private void asyncExecute(boolean flushAll) throws IOException {
+ private void execute(boolean flushAll) throws IOException {
LinkedList execBuffer = new LinkedList<>();
- ObTableBatchOperationRequest request = null;
- // namespace n1, n1:table_name
- // namespace default, table_name
- String tableNameString = tableName.getNameAsString();
+ long dequeuedSize = 0L;
try {
- while (true) {
- try{
- if (!flushAll || asyncWriteBuffer.isEmpty()) {
- if (currentAsyncBufferSize.get() <= writeBufferSize) {
- break;
- }
- }
- Mutation m;
- while ((m = asyncWriteBuffer.poll()) != null) {
- execBuffer.add(m);
- long size = m.heapSize();
- currentAsyncBufferSize.addAndGet(-size);
- }
- // in concurrent situation, asyncWriteBuffer may be empty here
- // for other threads flush all buffer
- if (execBuffer.isEmpty()) {
- break;
- }
- // for now, operations' family is the same
- byte[] family = execBuffer.getFirst().getFamilyMap().firstKey();
- ObTableBatchOperation batch = buildObTableBatchOperation(execBuffer);
- // table_name$cf_name
- String targetTableName = OHTable.getTargetTableName(tableNameString, Bytes.toString(family), conf);
- request = OHTable.buildObTableBatchOperationRequest(batch, targetTableName);
- } catch (Exception ex) {
- LOGGER.error("Errors occur before mutation operation", ex);
- throw new IllegalArgumentException("Errors occur before mutation operation", ex);
- }
- try {
- ObTableBatchOperationResult result = (ObTableBatchOperationResult) obTableClient.execute(request);
- } catch (Exception ex) {
- LOGGER.debug("Errors occur during mutation operation", ex);
- Mutation m = null;
- try {
- // retry every single operation
- while (!execBuffer.isEmpty()) {
- // poll elements from execBuffer to recollect remaining operations
- m = execBuffer.poll();
- byte[] family = m.getFamilyMap().firstKey();
- ObTableBatchOperation batch = buildObTableBatchOperation(Collections.singletonList(m));
- String targetTableName = OHTable.getTargetTableName(tableNameString, Bytes.toString(family), conf);
- request = OHTable.buildObTableBatchOperationRequest(batch, targetTableName);
- ObTableBatchOperationResult result = (ObTableBatchOperationResult) obTableClient.execute(request);
- }
- } catch (Exception newEx) {
- if (m != null) {
- execBuffer.addFirst(m);
- }
- // if retry fails, only recollect remaining operations
- while(!execBuffer.isEmpty()) {
- m = execBuffer.poll();
- long size = m.heapSize();
- asyncWriteBuffer.add(m);
- currentAsyncBufferSize.addAndGet(size);
- }
- throw newEx;
- }
- }
+ Mutation m;
+ while ((writeBufferSize <= 0 || dequeuedSize < (writeBufferSize * 2) || flushAll)
+ && (m = asyncWriteBuffer.poll()) != null) {
+ execBuffer.add(m);
+ long size = m.heapSize();
+ currentAsyncBufferSize.addAndGet(-size);
+ dequeuedSize += size;
+ }
+
+ if (execBuffer.isEmpty()) {
+ return;
}
+ ohTable.batch(execBuffer);
+ // if commit all successfully, clean execBuffer
+ execBuffer.clear();
} catch (Exception ex) {
LOGGER.error(LCD.convert("01-00026"), ex);
- // if the cause is illegal argument, directly throw to user
- if (ex instanceof IllegalArgumentException) {
- throw (IllegalArgumentException) ex;
- }
- // TODO: need to collect error information and actions during batch operations
- // TODO: maybe keep in ObTableBatchOperationResult
- List throwables = new ArrayList();
- List actions = new ArrayList();
- List addresses = new ArrayList();
- throwables.add(ex);
- RetriesExhaustedWithDetailsException error = new RetriesExhaustedWithDetailsException(
- new ArrayList(throwables),
- new ArrayList(actions), new ArrayList(addresses));
- if (listener == null) {
- throw error;
+ if (ex.getCause() instanceof RetriesExhaustedWithDetailsException) {
+ LOGGER.error(tableName + ": One or more of the operations have failed after retries.");
+ RetriesExhaustedWithDetailsException retryException = (RetriesExhaustedWithDetailsException) ex.getCause();
+ // recollect mutations
+ execBuffer.clear();
+ for (int i = 0; i < retryException.getNumExceptions(); ++i) {
+ execBuffer.add((Mutation) retryException.getRow(i));
+ }
+ if (listener != null) {
+ listener.onException(retryException, this);
+ } else {
+ throw retryException;
+ }
} else {
- listener.onException(error, this);
+ LOGGER.error("Errors unrelated to operations occur during mutation operation", ex);
+ throw ex;
+ }
+ } finally {
+ for (Mutation mutation : execBuffer) {
+ long size = mutation.heapSize();
+ currentAsyncBufferSize.addAndGet(size);
+ asyncWriteBuffer.add(mutation);
}
}
}
@@ -256,7 +209,7 @@ public void close() throws IOException {
return;
}
try {
- asyncExecute(true);
+ execute(true);
} finally {
// the pool in ObTableClient will be shut down too
this.pool.shutdown();
@@ -273,13 +226,21 @@ public void close() throws IOException {
}
}
+ @Deprecated
+ public void setWriteBufferSize(long writeBufferSize) throws IOException {
+ this.writeBufferSize = writeBufferSize;
+ if (currentAsyncBufferSize.get() > writeBufferSize) {
+ flush();
+ }
+ }
+
/**
* Force to commit all operations
* do not care whether the pool is shut down or this BufferedMutator is closed
*/
@Override
public void flush() throws IOException {
- asyncExecute(true);
+ execute(true);
}
@Override
@@ -287,13 +248,18 @@ public long getWriteBufferSize() {
return this.writeBufferSize;
}
- private ObTableBatchOperation buildObTableBatchOperation(List extends Mutation> execBuffer) {
- List keyValueList = new LinkedList<>();
- for (Mutation mutation : execBuffer) {
- for (Map.Entry> entry : mutation.getFamilyMap().entrySet()) {
- keyValueList.addAll(entry.getValue());
- }
- }
- return OHTable.buildObTableBatchOperation(keyValueList, false, null);
+ public void setRpcTimeout(int rpcTimeout) {
+ this.rpcTimeout = rpcTimeout;
+ this.ohTable.setRpcTimeout(rpcTimeout);
+ }
+
+ public void setOperationTimeout(int operationTimeout) {
+ this.operationTimeout = operationTimeout;
+ this.ohTable.setOperationTimeout(operationTimeout);
+ }
+
+ @Deprecated
+ public List getWriteBuffer() {
+ return Arrays.asList(asyncWriteBuffer.toArray(new Row[0]));
}
}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/OHConnectionConfiguration.java b/src/main/java/com/alipay/oceanbase/hbase/util/OHConnectionConfiguration.java
index e4789df3..f602fdda 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/util/OHConnectionConfiguration.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/OHConnectionConfiguration.java
@@ -25,11 +25,15 @@
import java.util.Properties;
import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.hadoop.hbase.ipc.RpcClient.DEFAULT_SOCKET_TIMEOUT_CONNECT;
+import static org.apache.hadoop.hbase.ipc.RpcClient.SOCKET_TIMEOUT_CONNECT;
@InterfaceAudience.Private
public class OHConnectionConfiguration {
+ private String paramUrl;
+ private String database;
private final Properties properties;
- private final String paramUrl;
private final String fullUsername;
private final String password;
private final String sysUsername;
@@ -37,13 +41,13 @@ public class OHConnectionConfiguration {
private final String odpAddr;
private final int odpPort;
private final boolean odpMode;
- private final String database;
private final long writeBufferSize;
private final int operationTimeout;
private final int scannerCaching;
private final long scannerMaxResultSize;
private final int maxKeyValueSize;
private final int rpcTimeout;
+ private final int rpcConnectTimeout;
public OHConnectionConfiguration(Configuration conf) {
this.paramUrl = conf.get(HBASE_OCEANBASE_PARAM_URL);
@@ -54,11 +58,27 @@ public OHConnectionConfiguration(Configuration conf) {
this.odpAddr = conf.get(HBASE_OCEANBASE_ODP_ADDR);
this.odpPort = conf.getInt(HBASE_OCEANBASE_ODP_PORT, -1);
this.odpMode = conf.getBoolean(HBASE_OCEANBASE_ODP_MODE, false);
- this.database = conf.get(HBASE_OCEANBASE_DATABASE);
+ String database = conf.get(HBASE_OCEANBASE_DATABASE);
+ if (isBlank(database)) {
+ database = "default";
+ }
+ this.database = database;
this.writeBufferSize = conf.getLong(WRITE_BUFFER_SIZE_KEY, WRITE_BUFFER_SIZE_DEFAULT);
this.operationTimeout = conf.getInt("hbase.client.operation.timeout", 1200000);
this.rpcTimeout = conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY,
HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
+ int rpcConnectTimeout = -1;
+ if (conf.get(SOCKET_TIMEOUT_CONNECT) != null) {
+ rpcConnectTimeout = conf.getInt(SOCKET_TIMEOUT_CONNECT, DEFAULT_SOCKET_TIMEOUT_CONNECT);
+ } else {
+ if (conf.get(SOCKET_TIMEOUT) != null) {
+ rpcConnectTimeout = conf.getInt(SOCKET_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
+ } else {
+ rpcConnectTimeout = conf.getInt(SOCKET_TIMEOUT_CONNECT,
+ DEFAULT_SOCKET_TIMEOUT_CONNECT);
+ }
+ }
+ this.rpcConnectTimeout = rpcConnectTimeout;
this.scannerCaching = conf.getInt("hbase.client.scanner.caching", Integer.MAX_VALUE);
this.scannerMaxResultSize = conf.getLong("hbase.client.scanner.max.result.size",
WRITE_BUFFER_SIZE_DEFAULT);
@@ -72,6 +92,14 @@ public OHConnectionConfiguration(Configuration conf) {
}
}
+ public void setParamUrl(String paramUrl) {
+ this.paramUrl = paramUrl;
+ }
+
+ public void setDatabase(String database) {
+ this.database = database;
+ }
+
public long getWriteBufferSize() {
return this.writeBufferSize;
}
@@ -92,6 +120,10 @@ public int getRpcTimeout() {
return this.rpcTimeout;
}
+ public int getRpcConnectTimeout() {
+ return this.rpcConnectTimeout;
+ }
+
public long getScannerMaxResultSize() {
return this.scannerMaxResultSize;
}
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/OHTableFactory.java b/src/main/java/com/alipay/oceanbase/hbase/util/OHTableFactory.java
index 06c88892..8d42daa4 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/util/OHTableFactory.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/OHTableFactory.java
@@ -65,6 +65,8 @@ public OHTableFactory(Configuration conf, OHTablePool tablePool,
public HTableInterface createHTableInterface(Configuration config, byte[] tableName) {
try {
String tableNameStr = Bytes.toString(tableName);
+ tableNameStr = tableNameStr.equals(this.tablePool.getOriginTableName()) ? tableNameStr
+ : this.tablePool.getOriginTableName();
OHTable ht = new OHTable(adjustConfiguration(copyConfiguration(config), tableNameStr),
tableName, this.threadPool);
diff --git a/src/main/java/com/alipay/oceanbase/hbase/util/ObTableClientManager.java b/src/main/java/com/alipay/oceanbase/hbase/util/ObTableClientManager.java
index 9b0c8182..036ce265 100644
--- a/src/main/java/com/alipay/oceanbase/hbase/util/ObTableClientManager.java
+++ b/src/main/java/com/alipay/oceanbase/hbase/util/ObTableClientManager.java
@@ -21,6 +21,8 @@
import com.alipay.oceanbase.rpc.constant.Constants;
import com.google.common.base.Objects;
import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.client.ConnectionConfiguration;
import java.io.IOException;
import java.util.Map;
@@ -58,7 +60,11 @@ public static ObTableClient getOrCreateObTableClient(OHConnectionConfiguration c
checkArgument(isNotBlank(connectionConfig.getParamUrl()), HBASE_OCEANBASE_PARAM_URL
+ " is blank");
obTableClientKey = new ObTableClientKey();
- obTableClientKey.setParamUrl(connectionConfig.getParamUrl());
+ String paramUrl = connectionConfig.getParamUrl();
+ if (!paramUrl.contains("database")) {
+ paramUrl += "&database=default";
+ }
+ obTableClientKey.setParamUrl(paramUrl);
obTableClientKey.setSysUserName(connectionConfig.getSysUsername());
if (connectionConfig.getSysPassword() == null) {
obTableClientKey.setSysPassword(Constants.EMPTY_STRING);
@@ -80,11 +86,11 @@ public static ObTableClient getOrCreateObTableClient(OHConnectionConfiguration c
obTableClientKey.getProperties().put(property.getKey(), property.getValue());
}
- return getOrCreateObTableClient(obTableClientKey);
+ return getOrCreateObTableClient(obTableClientKey, connectionConfig.getRpcConnectTimeout());
}
- public static ObTableClient getOrCreateObTableClient(ObTableClientKey obTableClientKey)
- throws IOException {
+ public static ObTableClient getOrCreateObTableClient(ObTableClientKey obTableClientKey,
+ int rpcConnectTimeout) throws IOException {
if (OB_TABLE_CLIENT_INSTANCE.get(obTableClientKey) == null) {
ReentrantLock tmp = new ReentrantLock();
ReentrantLock lock = OB_TABLE_CLIENT_LOCK.putIfAbsent(obTableClientKey, tmp);
@@ -109,6 +115,7 @@ public static ObTableClient getOrCreateObTableClient(ObTableClientKey obTableCli
}
obTableClient.setFullUserName(obTableClientKey.getFullUserName());
obTableClient.setPassword(obTableClientKey.getPassword());
+ obTableClient.setRpcConnectTimeout(rpcConnectTimeout);
obTableClient.init();
OB_TABLE_CLIENT_INSTANCE.put(obTableClientKey, obTableClient);
}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/HTableMultiCFTestBase.java b/src/test/java/com/alipay/oceanbase/hbase/HTableMultiCFTestBase.java
new file mode 100644
index 00000000..ca864ab1
--- /dev/null
+++ b/src/test/java/com/alipay/oceanbase/hbase/HTableMultiCFTestBase.java
@@ -0,0 +1,1415 @@
+/*-
+ * #%L
+ * com.oceanbase:obkv-hbase-client
+ * %%
+ * Copyright (C) 2022 - 2024 OceanBase Group
+ * %%
+ * OBKV HBase Client Framework is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * #L%
+ */
+
+package com.alipay.oceanbase.hbase;
+
+import org.apache.hadoop.conf.Configuration;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.*;
+import org.apache.hadoop.hbase.client.coprocessor.Batch;
+import org.apache.hadoop.hbase.filter.*;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.*;
+import org.junit.rules.ExpectedException;
+
+import java.util.*;
+
+import static org.apache.hadoop.hbase.util.Bytes.toBytes;
+import static org.junit.Assert.*;
+
+public abstract class HTableMultiCFTestBase {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ protected static Table multiCfHTable;
+
+ public void tryPut(Table multiCfHTable, Put put) throws Exception {
+ multiCfHTable.put(put);
+ Thread.sleep(1);
+ }
+
+ @Test
+ public void testDeleteFamilyVerison() throws Exception {
+ String key1 = "scanKey1x";
+ String key2 = "scanKey2x";
+ String key3 = "scanKey3x";
+ String column1 = "column1";
+ String column2 = "column2";
+ String column3 = "column3";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+ String family1 = "family_with_group1";
+ String family2 = "family_with_group2";
+ // delete previous data
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family1));
+ deleteKey1Family.deleteFamily(toBytes(family2));
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family1));
+ deleteKey2Family.deleteFamily(toBytes(family2));
+ Delete deleteKey3Family = new Delete(toBytes(key3));
+ deleteKey3Family.deleteFamily(toBytes(family1));
+ deleteKey3Family.deleteFamily(toBytes(family2));
+
+ multiCfHTable.delete(deleteKey1Family);
+ multiCfHTable.delete(deleteKey2Family);
+ multiCfHTable.delete(deleteKey3Family);
+
+ long minTimeStamp = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp1 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp2 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp3 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp4 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp5 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp6 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp7 = System.currentTimeMillis();
+ Thread.sleep(5);
+
+ Put putKey1Fam1Column1MinTs = new Put(toBytes(key1));
+ putKey1Fam1Column1MinTs.add(toBytes(family1), toBytes(column1), minTimeStamp,
+ toBytes(value1));
+
+ Put putKey3Fam1Column1Ts1 = new Put(toBytes(key3));
+ putKey3Fam1Column1Ts1.add(toBytes(family1), toBytes(column1), timeStamp1, toBytes(value2));
+
+ Put putKey1Fam1Column2MinTs = new Put(toBytes(key1));
+ putKey1Fam1Column2MinTs.add(toBytes(family1), toBytes(column2), minTimeStamp,
+ toBytes(value1));
+
+ Put putKey1Fam1Column2Ts3 = new Put(toBytes(key1));
+ putKey1Fam1Column2Ts3.add(toBytes(family1), toBytes(column2), timeStamp3, toBytes(value2));
+
+ Put putKey2Fam1Column2Ts3 = new Put(toBytes(key2));
+ putKey2Fam1Column2Ts3.add(toBytes(family1), toBytes(column2), timeStamp3, toBytes(value2));
+
+ Put putKey2Fam1Column3Ts1 = new Put(toBytes(key2));
+ putKey2Fam1Column3Ts1.add(toBytes(family1), toBytes(column3), timeStamp1, toBytes(value2));
+
+ Put putKey3Fam1Column3Ts1 = new Put(toBytes(key3));
+ putKey3Fam1Column3Ts1.add(toBytes(family1), toBytes(column3), timeStamp1, toBytes(value2));
+
+ Put putKey3Fam1Column2Ts4 = new Put(toBytes(key3));
+ putKey3Fam1Column2Ts4.add(toBytes(family1), toBytes(column2), timeStamp4, toBytes(value1));
+
+ Put putKey2Fam1Column3Ts3 = new Put(toBytes(key2));
+ putKey2Fam1Column3Ts3.add(toBytes(family1), toBytes(column3), timeStamp3, toBytes(value1));
+
+ tryPut(multiCfHTable, putKey1Fam1Column1MinTs);
+ tryPut(multiCfHTable, putKey3Fam1Column1Ts1);
+ tryPut(multiCfHTable, putKey1Fam1Column2MinTs);
+ tryPut(multiCfHTable, putKey1Fam1Column2Ts3);
+ tryPut(multiCfHTable, putKey2Fam1Column2Ts3);
+ tryPut(multiCfHTable, putKey2Fam1Column3Ts1);
+ tryPut(multiCfHTable, putKey3Fam1Column3Ts1);
+ tryPut(multiCfHTable, putKey3Fam1Column2Ts4);
+ tryPut(multiCfHTable, putKey2Fam1Column3Ts3);
+
+ // test DeleteFamilyVersion single cf
+ Get get = new Get(toBytes(key1));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(minTimeStamp);
+ get.setMaxVersions(10);
+ Result r = multiCfHTable.get(get);
+ Assert.assertEquals(2, r.raw().length);
+
+ get = new Get(toBytes(key3));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(timeStamp1);
+ get.setMaxVersions(10);
+ r = multiCfHTable.get(get);
+ Assert.assertEquals(2, r.raw().length);
+
+ get = new Get(toBytes(key2));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(timeStamp3);
+ get.setMaxVersions(10);
+ r = multiCfHTable.get(get);
+ Assert.assertEquals(2, r.raw().length);
+
+ Delete delKey1MinTs = new Delete(toBytes(key1));
+ delKey1MinTs.deleteFamilyVersion(toBytes(family1), minTimeStamp);
+ multiCfHTable.delete(delKey1MinTs);
+
+ get = new Get(toBytes(key1));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(minTimeStamp);
+ get.setMaxVersions(10);
+ r = multiCfHTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ Delete delKey3Ts1 = new Delete(toBytes(key3));
+ delKey3Ts1.deleteFamilyVersion(toBytes(family1), timeStamp1);
+ multiCfHTable.delete(delKey3Ts1);
+
+ get = new Get(toBytes(key3));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(timeStamp1);
+ get.setMaxVersions(10);
+ r = multiCfHTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ Delete delKey2Ts3 = new Delete(toBytes(key2));
+ delKey2Ts3.deleteFamilyVersion(family1.getBytes(), timeStamp3);
+ multiCfHTable.delete(delKey2Ts3);
+
+ get = new Get(toBytes(key2));
+ get.addFamily(toBytes(family1));
+ get.setTimeStamp(timeStamp3);
+ get.setMaxVersions(10);
+ r = multiCfHTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes(key1));
+ scan.setStopRow("scanKey4x".getBytes());
+ scan.addFamily(toBytes(family1));
+ scan.setMaxVersions(10);
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+ int key1Cnt = 0, key2Cnt = 0, key3Cnt = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ if (key1.equals(Bytes.toString(kv.getRow()))) {
+ ++key1Cnt;
+ } else if (key2.equals(Bytes.toString(kv.getRow()))) {
+ ++key2Cnt;
+ } else {
+ ++key3Cnt;
+ }
+ }
+ }
+ Assert.assertEquals(1, key1Cnt);
+ Assert.assertEquals(1, key2Cnt);
+ Assert.assertEquals(1, key3Cnt);
+
+ multiCfHTable.delete(deleteKey1Family);
+ multiCfHTable.delete(deleteKey2Family);
+ multiCfHTable.delete(deleteKey3Family);
+
+ // test DeleteFamilyVersion multiple cf
+ Put putKey1Fam1Column3Ts4 = new Put(toBytes(key1));
+ putKey1Fam1Column3Ts4.add(toBytes(family1), toBytes(column3), timeStamp4, toBytes(value3));
+
+ Put putKey1Fam2Column2Ts2 = new Put(toBytes(key1));
+ putKey1Fam2Column2Ts2.add(toBytes(family2), toBytes(column2), timeStamp2, toBytes(value1));
+
+ Put putKey1Fam2Column3Ts2 = new Put(toBytes(key1));
+ putKey1Fam2Column3Ts2.add(toBytes(family2), toBytes(column3), timeStamp2, toBytes(value1));
+
+ Put putKey1Fam1Column2Ts1 = new Put(toBytes(key1));
+ putKey1Fam1Column2Ts1.add(toBytes(family1), toBytes(column2), timeStamp1, toBytes(value2));
+
+ Put putKey2Fam1Column2Ts5 = new Put(toBytes(key2));
+ putKey2Fam1Column2Ts5.add(toBytes(family1), toBytes(column2), timeStamp5, toBytes(value2));
+
+ Put putKey2Fam2Column3Ts1 = new Put(toBytes(key2));
+ putKey2Fam2Column3Ts1.add(toBytes(family2), toBytes(column3), timeStamp3, toBytes(value3));
+
+ Put putKey2Fam1Column1Ts5 = new Put(toBytes(key2));
+ putKey2Fam1Column1Ts5.add(toBytes(family1), toBytes(column1), timeStamp5, toBytes(value1));
+
+ Put putKey2Fam2Column1Ts3 = new Put(toBytes(key2));
+ putKey2Fam2Column1Ts3.add(toBytes(family2), toBytes(column1), timeStamp3, toBytes(value2));
+
+ Put putKey3Fam1Column2Ts6 = new Put(toBytes(key3));
+ putKey3Fam1Column2Ts6.add(toBytes(family1), toBytes(column2), timeStamp6, toBytes(value2));
+
+ Put putKey3Fam2Column3Ts7 = new Put(toBytes(key3));
+ putKey3Fam2Column3Ts7.add(toBytes(family2), toBytes(column3), timeStamp7, toBytes(value1));
+
+ Put putKey3Fam2Column1Ts7 = new Put(toBytes(key3));
+ putKey3Fam2Column1Ts7.add(toBytes(family2), toBytes(column1), timeStamp7, toBytes(value2));
+
+ Put putKey3Fam1Column2Ts2 = new Put(toBytes(key3));
+ putKey3Fam1Column2Ts2.add(toBytes(family1), toBytes(column2), timeStamp2, toBytes(value1));
+
+ tryPut(multiCfHTable, putKey1Fam1Column3Ts4);
+ tryPut(multiCfHTable, putKey1Fam2Column2Ts2);
+ tryPut(multiCfHTable, putKey1Fam2Column3Ts2);
+ tryPut(multiCfHTable, putKey1Fam1Column2Ts1);
+ tryPut(multiCfHTable, putKey2Fam1Column2Ts5);
+ tryPut(multiCfHTable, putKey2Fam2Column3Ts1);
+ tryPut(multiCfHTable, putKey2Fam1Column1Ts5);
+ tryPut(multiCfHTable, putKey2Fam2Column1Ts3);
+ tryPut(multiCfHTable, putKey3Fam1Column2Ts6);
+ tryPut(multiCfHTable, putKey3Fam2Column3Ts7);
+ tryPut(multiCfHTable, putKey3Fam2Column1Ts7);
+ tryPut(multiCfHTable, putKey3Fam1Column2Ts2);
+
+ Get getKey1 = new Get(toBytes(key1));
+ getKey1.addFamily(toBytes(family1));
+ getKey1.addFamily(toBytes(family2));
+ getKey1.setMaxVersions(10);
+ r = multiCfHTable.get(getKey1);
+ Assert.assertEquals(4, r.raw().length);
+
+ Get getKey2 = new Get(toBytes(key2));
+ getKey2.addFamily(toBytes(family1));
+ getKey2.addFamily(toBytes(family2));
+ getKey2.setMaxVersions(10);
+ r = multiCfHTable.get(getKey2);
+ Assert.assertEquals(4, r.raw().length);
+
+ Get getKey3 = new Get(toBytes(key3));
+ getKey3.addFamily(toBytes(family1));
+ getKey3.addFamily(toBytes(family2));
+ getKey3.setMaxVersions(10);
+ r = multiCfHTable.get(getKey3);
+ Assert.assertEquals(4, r.raw().length);
+
+ Delete delKey1Ts_6_2 = new Delete(toBytes(key1));
+ delKey1Ts_6_2.deleteFamilyVersion(toBytes(family1), timeStamp4);
+ delKey1Ts_6_2.deleteFamilyVersion(toBytes(family2), timeStamp2);
+ multiCfHTable.delete(delKey1Ts_6_2);
+
+ getKey1 = new Get(toBytes(key1));
+ getKey1.addFamily(toBytes(family1));
+ getKey1.addFamily(toBytes(family2));
+ getKey1.setMaxVersions(10);
+ r = multiCfHTable.get(getKey1);
+ Assert.assertEquals(1, r.raw().length);
+ for (KeyValue kv : r.raw()) {
+ Assert.assertEquals(timeStamp1, kv.getTimestamp());
+ }
+
+ Delete delKey2Ts_5_3 = new Delete(toBytes(key2));
+ delKey2Ts_5_3.deleteFamilyVersion(toBytes(family1), timeStamp5);
+ delKey2Ts_5_3.deleteFamilyVersion(toBytes(family2), timeStamp3);
+ multiCfHTable.delete(delKey2Ts_5_3);
+
+ getKey2 = new Get(toBytes(key2));
+ getKey2.addFamily(toBytes(family1));
+ getKey2.addFamily(toBytes(family2));
+ getKey2.setMaxVersions(10);
+ r = multiCfHTable.get(getKey2);
+ Assert.assertEquals(0, r.raw().length);
+
+ Delete delKey3Ts_2_7 = new Delete(toBytes(key3));
+ delKey3Ts_2_7.deleteFamilyVersion(toBytes(family1), timeStamp2);
+ delKey3Ts_2_7.deleteFamilyVersion(toBytes(family2), timeStamp7);
+ multiCfHTable.delete(delKey3Ts_2_7);
+
+ getKey3 = new Get(toBytes(key3));
+ getKey3.addFamily(toBytes(family1));
+ getKey3.addFamily(toBytes(family2));
+ getKey3.setMaxVersions(10);
+ r = multiCfHTable.get(getKey3);
+ Assert.assertEquals(1, r.raw().length);
+ for (KeyValue kv : r.raw()) {
+ Assert.assertEquals(timeStamp6, kv.getTimestamp());
+ }
+
+ scan = new Scan();
+ scan.setStartRow(toBytes(key1));
+ scan.setStopRow("scanKey4x".getBytes());
+ scan.addFamily(toBytes(family1));
+ scan.addFamily(toBytes(family2));
+ scan.setMaxVersions(10);
+ scanner = multiCfHTable.getScanner(scan);
+ int ts1Cnt = 0, ts9Cnt = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ if (kv.getTimestamp() == timeStamp1) {
+ ++ts1Cnt;
+ } else if (kv.getTimestamp() == timeStamp6) {
+ ++ts9Cnt;
+ }
+ }
+ }
+ Assert.assertEquals(1, ts1Cnt);
+ Assert.assertEquals(1, ts9Cnt);
+
+ multiCfHTable.delete(deleteKey1Family);
+ multiCfHTable.delete(deleteKey2Family);
+ multiCfHTable.delete(deleteKey3Family);
+ }
+
+ @Test
+ public void testMulfiColumnFamilyBufferedMutator() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family3_column2 = "family3_column2".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Configuration conf = ObHTableTestUtil.newConfiguration();
+ TableName tableName = TableName.valueOf("test_multi_cf");
+ Connection connection = ConnectionFactory.createConnection(conf);
+ BufferedMutator mutator = connection.getBufferedMutator(tableName);
+
+ int rows = 10;
+ List keys = new ArrayList<>();
+ List mutations = new ArrayList<>();
+ for (int i = 0; i < rows; ++i) {
+ String key = "Key" + i;
+ keys.add(key);
+ Delete delete = new Delete(toBytes(key));
+ mutations.add(delete);
+ Put put = new Put(toBytes(key));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ mutations.add(put);
+ }
+ mutator.mutate(mutations);
+
+ // test force flush
+ mutator.flush();
+ Get get = new Get(toBytes("Key2"));
+ get.addFamily(family1);
+ get.addFamily(family2);
+ Result result = multiCfHTable.get(get);
+ Assert.assertEquals(5, result.raw().length);
+
+ mutations.clear();
+ for (int i = 0; i < rows; ++i) {
+ if (i % 5 == 0) { // 0, 5
+ Delete delete = new Delete(toBytes("Key" + i));
+ delete.deleteFamily(family2);
+ delete.deleteFamily(family3);
+ mutations.add(delete);
+ }
+ }
+ mutator.mutate(mutations);
+ mutator.flush();
+
+ get = new Get(toBytes("Key0"));
+ result = multiCfHTable.get(get);
+ Assert.assertEquals(3, result.raw().length);
+ Assert.assertFalse(result.containsColumn(family2, family2_column1));
+ Assert.assertFalse(result.containsColumn(family2, family2_column2));
+ Assert.assertFalse(result.containsColumn(family3, family3_column1));
+
+ get = new Get(toBytes("Key5"));
+ result = multiCfHTable.get(get);
+ Assert.assertEquals(3, result.raw().length);
+ Assert.assertFalse(result.containsColumn(family2, family2_column1));
+ Assert.assertFalse(result.containsColumn(family2, family2_column2));
+ Assert.assertFalse(result.containsColumn(family3, family3_column1));
+
+ mutations.clear();
+ for (String key : keys) {
+ Delete delete = new Delete(toBytes(key));
+ mutations.add(delete);
+ }
+ mutator.mutate(mutations);
+ mutator.flush();
+
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes("Key0"));
+ scan.setStopRow(toBytes("Key10"));
+ scan.addFamily(family1);
+ scan.addFamily(family2);
+ scan.addFamily(family3);
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+ int count = 0;
+ for (Result r : scanner) {
+ count += r.raw().length;
+ }
+ Assert.assertEquals(0, count);
+
+ // test auto flush
+ long bufferSize = 45000L;
+ BufferedMutatorParams params = new BufferedMutatorParams(tableName);
+ params.writeBufferSize(bufferSize);
+ mutator = connection.getBufferedMutator(params);
+
+ while (true) {
+ for (int i = 0; i < rows; ++i) {
+ mutations.clear();
+ Put put = new Put(toBytes(keys.get(i)));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family3, family3_column1, family2_value);
+ put.add(family3, family3_column2, family3_value);
+ mutations.add(put);
+ if (i % 3 == 0) { // 0, 3, 6, 9
+ Delete delete = new Delete(toBytes(keys.get(i)));
+ delete.deleteFamily(family1);
+ delete.deleteFamily(family2);
+ mutations.add(delete);
+ }
+ mutator.mutate(mutations);
+ }
+
+ get = new Get(toBytes("Key0"));
+ result = multiCfHTable.get(get);
+ if (!result.isEmpty()) {
+ break;
+ }
+ }
+ get = new Get(toBytes("Key2"));
+ result = multiCfHTable.get(get);
+ Assert.assertEquals(6 , result.raw().length);
+ Assert.assertTrue(result.containsColumn(family1, family1_column1));
+ Assert.assertTrue(result.containsColumn(family1, family1_column2));
+ Assert.assertTrue(result.containsColumn(family1, family1_column3));
+ Assert.assertTrue(result.containsColumn(family2, family2_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column2));
+
+ get = new Get(toBytes("Key3"));
+ result = multiCfHTable.get(get);
+ if (result.containsColumn(family1, family1_column1) || result.containsColumn(family2, family2_column1)) {
+ mutator.flush();
+ }
+ get = new Get(toBytes("Key3"));
+ result = multiCfHTable.get(get);
+ Assert.assertEquals(2, result.raw().length);
+ Assert.assertFalse(result.containsColumn(family1, family1_column1));
+ Assert.assertFalse(result.containsColumn(family1, family1_column2));
+ Assert.assertFalse(result.containsColumn(family1, family1_column3));
+ Assert.assertFalse(result.containsColumn(family2, family2_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column2));
+
+ get = new Get(toBytes("Key9"));
+ result = multiCfHTable.get(get);
+ if (result.containsColumn(family1, family1_column1) || result.containsColumn(family2, family2_column1)) {
+ mutator.flush();
+ }
+ get = new Get(toBytes("Key9"));
+ result = multiCfHTable.get(get);
+ Assert.assertEquals(2, result.raw().length);
+ Assert.assertFalse(result.containsColumn(family1, family1_column1));
+ Assert.assertFalse(result.containsColumn(family1, family1_column2));
+ Assert.assertFalse(result.containsColumn(family1, family1_column3));
+ Assert.assertFalse(result.containsColumn(family2, family2_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column1));
+ Assert.assertTrue(result.containsColumn(family3, family3_column2));
+
+ // clean data
+ mutations.clear();
+ for (String key : keys) {
+ Delete delete = new Delete(toBytes(key));
+ mutations.add(delete);
+ }
+ mutator.mutate(mutations);
+ mutator.flush();
+
+ scan = new Scan();
+ scan.setStartRow(toBytes("Key0"));
+ scan.setStopRow(toBytes("Key10"));
+ scan.addFamily(family1);
+ scan.addFamily(family2);
+ scan.addFamily(family3);
+ scanner = multiCfHTable.getScanner(scan);
+ count = 0;
+ for (Result r : scanner) {
+ count += r.raw().length;
+ }
+ Assert.assertEquals(0, count);
+ }
+
+ @Test
+ public void testMultiColumnFamilyBatch() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ int rows = 10;
+ List batchLsit = new LinkedList<>();
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ Delete delete = new Delete(toBytes("Key" + i));
+ batchLsit.add(delete);
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ batchLsit.add(put);
+ }
+
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ Delete delete = new Delete(toBytes("Key1"));
+ delete.deleteColumns(family1, family1_column1);
+ delete.deleteColumns(family2, family2_column1);
+ batchLsit.add(delete);
+ multiCfHTable.batch(batchLsit);
+ // f1c2 f1c3 f2c2 f3c1
+ Get get = new Get(toBytes("Key1"));
+ Result result = multiCfHTable.get(get);
+ KeyValue[] keyValues = result.raw();
+ assertEquals(4, keyValues.length);
+ assertFalse(result.containsColumn(family1, family1_column1));
+ assertFalse(result.containsColumn(family2, family2_column1));
+
+ assertTrue(result.containsColumn(family1, family1_column2));
+ assertArrayEquals(result.getValue(family1, family1_column2), family1_value);
+ assertTrue(result.containsColumn(family1, family1_column3));
+ assertArrayEquals(result.getValue(family1, family1_column3), family1_value);
+ assertTrue(result.containsColumn(family2, family2_column2));
+ assertArrayEquals(result.getValue(family2, family2_column2), family2_value);
+ assertTrue(result.containsColumn(family3, family3_column1));
+ assertArrayEquals(result.getValue(family3, family3_column1), family3_value);
+
+ // f1c1 f2c1 f2c2
+ delete = new Delete(toBytes("Key2"));
+ delete.deleteColumns(family1, family1_column2);
+ delete.deleteColumns(family1, family1_column3);
+ delete.deleteColumns(family3, family3_column1);
+ batchLsit.add(delete);
+ // null
+ multiCfHTable.batch(batchLsit);
+ get = new Get(toBytes("Key2"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(3, keyValues.length);
+ batchLsit.clear();
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ batchLsit.add(put);
+ }
+
+ delete = new Delete(toBytes("Key3"));
+ delete.deleteColumn(family1, family1_column2);
+ delete.deleteColumn(family2, family2_column1);
+ batchLsit.add(delete);
+ multiCfHTable.batch(batchLsit);
+ get = new Get(toBytes("Key3"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(6, keyValues.length);
+
+ batchLsit.clear();
+ delete = new Delete(toBytes("Key4"));
+ delete.deleteColumns(family1, family1_column2);
+ delete.deleteColumns(family2, family2_column1);
+ delete.deleteFamily(family3);
+ batchLsit.add(delete);
+ multiCfHTable.batch(batchLsit);
+ get = new Get(toBytes("Key4"));
+ get.setMaxVersions(10);
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(6, keyValues.length);
+
+ batchLsit.clear();
+ final long[] updateCounter = new long[] { 0L };
+ delete = new Delete(toBytes("Key5"));
+ delete.deleteColumns(family1, family1_column2);
+ delete.deleteColumns(family2, family2_column1);
+ delete.deleteFamily(family3);
+ batchLsit.add(delete);
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ batchLsit.add(put);
+ }
+ multiCfHTable.batchCallback(batchLsit, new Batch.Callback() {
+ @Override
+ public void update(byte[] region, byte[] row, Result result) {
+ updateCounter[0]++;
+ }
+ });
+ assertEquals(11, updateCounter[0]);
+
+ }
+
+ @Test
+ public void testMultiColumnFamilyPut() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 30;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+ int count = 0;
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ count++;
+ }
+ assertEquals(count, rows);
+ }
+
+ @Ignore
+ public void testMultiColumnFamilyAppend() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 30;
+
+ for (int i = 0; i < rows; ++i) {
+ Append append = new Append(toBytes("Key" + i));
+ append.add(family1, family1_column1, family1_value);
+ append.add(family1, family1_column2, family1_value);
+ append.add(family1, family1_column3, family1_value);
+ append.add(family2, family2_column1, family2_value);
+ append.add(family2, family2_column2, family2_value);
+ append.add(family3, family3_column1, family3_value);
+ multiCfHTable.append(append);
+ }
+
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+ int count = 0;
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ count++;
+ }
+ assertEquals(count, rows);
+ }
+
+ @Test
+ public void testMultiColumnFamilyReverseScan() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 30;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ Scan scan = new Scan();
+ scan.addFamily(family1);
+ scan.addFamily(family2);
+ scan.setReversed(true);
+ ResultScanner scanner2 = multiCfHTable.getScanner(scan);
+
+ for (Result result : scanner2) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testMultiColumnFamilyScanWithColumns() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 30;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ scan.addColumn(family1, family1_column1);
+ scan.addColumn(family2, family2_column1);
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(2, keyValues.length);
+ }
+ scanner.close();
+ scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ scan.addColumn(family1, family1_column1);
+ scan.addColumn(family1, family1_column2);
+ scan.addColumn(family1, family1_column3);
+ scan.addColumn(family2, family2_column1);
+ scan.addColumn(family2, family2_column2);
+ scanner = multiCfHTable.getScanner(scan);
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(5, keyValues.length);
+ }
+ scanner.close();
+ scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ scan.addFamily(family1);
+ scan.addFamily(family2);
+
+ scanner = multiCfHTable.getScanner(scan);
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(5, keyValues.length);
+ }
+ scanner.close();
+ scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ scan.addFamily(family1);
+ scan.addFamily(family3);
+
+ scanner = multiCfHTable.getScanner(scan);
+
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ // f1c1 f1c2 f1c3 f3c1
+ assertEquals(4, keyValues.length);
+ }
+ scanner.close();
+ }
+
+ @Test
+ public void testMultiColumnFamilyScanWithFilter() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 30;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ PrefixFilter filter = new PrefixFilter(toBytes("Key1"));
+ Scan scan = new Scan();
+ scan.setStartRow(toBytes("Key"));
+ scan.setStopRow(toBytes("Kf"));
+ scan.setFilter(filter);
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+
+ // Key1, Key10, Key11, Key12, Key13, Key14, Key15, Key16, Key17, Key18, Key19
+ int count = 0;
+ for (Result result : scanner) {
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(6, keyValues.length);
+ count++;
+ }
+ assertEquals(11, count);
+ }
+
+ @Test
+ public void testMultiColumnFamilyGet() throws Exception {
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ Map expectedValues = new HashMap<>();
+ expectedValues.put(family1_column1, family1_value);
+ expectedValues.put(family1_column2, family1_value);
+ expectedValues.put(family1_column3, family1_value);
+ expectedValues.put(family2_column1, family2_value);
+ expectedValues.put(family2_column2, family2_value);
+ expectedValues.put(family3_column1, family3_value);
+
+ int rows = 3;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ // get with empty family
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ Get get = new Get(toBytes("Key1"));
+ Result result = multiCfHTable.get(get);
+ KeyValue[] keyValues = result.raw();
+ long timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(6, keyValues.length);
+
+ // f1c1 f2c1 f2c2
+ Get get2 = new Get(toBytes("Key1"));
+ get2.addColumn(family1, family1_column1);
+ get2.addColumn(family2, family2_column1);
+ get2.addColumn(family2, family2_column2);
+ Result result2 = multiCfHTable.get(get2);
+ keyValues = result2.raw();
+ timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(3, keyValues.length);
+
+ //f2c1 f2c2
+ Get get3 = new Get(toBytes("Key1"));
+ get3.addFamily(family1);
+ get3.addColumn(family2, family2_column1);
+ get3.addColumn(family2, family2_column2);
+ Result result3 = multiCfHTable.get(get3);
+ keyValues = result3.raw();
+ timestamp = keyValues[0].getTimestamp();
+ for (int i = 1; i < keyValues.length; ++i) {
+ assertEquals(timestamp, keyValues[i].getTimestamp());
+ byte[] qualifier = keyValues[i].getQualifier();
+ byte[] expectedValue = expectedValues.get(qualifier);
+ if (expectedValue != null) {
+ assertEquals(expectedValue, keyValues[i].getValue());
+ }
+ }
+ assertEquals(5, keyValues.length);
+ }
+
+ @Test
+ public void testMultiColumnFamilyDelete() throws Exception {
+ String key1 = "scanKey1x";
+ String key2 = "scanKey2x";
+ String key3 = "scanKey3x";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+
+ byte[] family1 = "family_with_group1".getBytes();
+ byte[] family2 = "family_with_group2".getBytes();
+ byte[] family3 = "family_with_group3".getBytes();
+
+ byte[] family1_column1 = "family1_column1".getBytes();
+ byte[] family1_column2 = "family1_column2".getBytes();
+ byte[] family1_column3 = "family1_column3".getBytes();
+ byte[] family2_column1 = "family2_column1".getBytes();
+ byte[] family2_column2 = "family2_column2".getBytes();
+ byte[] family2_column3 = "family2_column3".getBytes();
+ byte[] family3_column1 = "family3_column1".getBytes();
+ byte[] family1_value = "VVV1".getBytes();
+ byte[] family2_value = "VVV2".getBytes();
+ byte[] family3_value = "VVV3".getBytes();
+
+ int rows = 10;
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ Delete delete = new Delete(toBytes("Key" + i));
+ multiCfHTable.delete(delete);
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ Delete delete = new Delete(toBytes("Key1"));
+ delete.deleteColumns(family1, family1_column1);
+ delete.deleteColumns(family2, family2_column1);
+ multiCfHTable.delete(delete);
+ // f1c2 f1c3 f2c2 f3c1
+ Get get = new Get(toBytes("Key1"));
+ Result result = multiCfHTable.get(get);
+ KeyValue[] keyValues = result.raw();
+ assertEquals(4, keyValues.length);
+ assertFalse(result.containsColumn(family1, family1_column1));
+ assertFalse(result.containsColumn(family2, family2_column1));
+
+ assertTrue(result.containsColumn(family1, family1_column2));
+ assertArrayEquals(result.getValue(family1, family1_column2), family1_value);
+ assertTrue(result.containsColumn(family1, family1_column3));
+ assertArrayEquals(result.getValue(family1, family1_column3), family1_value);
+ assertTrue(result.containsColumn(family2, family2_column2));
+ assertArrayEquals(result.getValue(family2, family2_column2), family2_value);
+ assertTrue(result.containsColumn(family3, family3_column1));
+ assertArrayEquals(result.getValue(family3, family3_column1), family3_value);
+
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ delete = new Delete(toBytes("Key2"));
+ delete.deleteFamily(family1);
+ delete.deleteFamily(family2);
+ // f3c1
+ multiCfHTable.delete(delete);
+ get = new Get(toBytes("Key2"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(1, keyValues.length);
+
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ delete = new Delete(toBytes("Key3"));
+ delete.deleteFamily(family1);
+ delete.deleteColumns(family2, family2_column1);
+ multiCfHTable.delete(delete);
+ // f2c2 f3c1
+ get = new Get(toBytes("Key3"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(2, keyValues.length);
+
+ // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
+ delete = new Delete(toBytes("Key4"));
+ multiCfHTable.delete(delete);
+ // null
+ get = new Get(toBytes("Key4"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(0, keyValues.length);
+
+ // f1c1 f2c1 f2c2
+ delete = new Delete(toBytes("Key5"));
+ delete.deleteColumns(family1, family1_column2);
+ delete.deleteColumns(family1, family1_column3);
+ delete.deleteColumns(family3, family3_column1);
+ multiCfHTable.delete(delete);
+ // null
+ get = new Get(toBytes("Key5"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(3, keyValues.length);
+
+ for (int i = 0; i < rows; ++i) {
+ Put put = new Put(toBytes("Key" + i));
+ put.add(family1, family1_column1, family1_value);
+ put.add(family1, family1_column2, family1_value);
+ put.add(family1, family1_column3, family1_value);
+ put.add(family2, family2_column1, family2_value);
+ put.add(family2, family2_column2, family2_value);
+ put.add(family3, family3_column1, family3_value);
+ multiCfHTable.put(put);
+ }
+
+ delete = new Delete(toBytes("Key6"));
+ delete.deleteColumn(family1, family1_column2);
+ delete.deleteColumn(family2, family2_column1);
+ multiCfHTable.delete(delete);
+ get = new Get(toBytes("Key6"));
+ result = multiCfHTable.get(get);
+ keyValues = result.raw();
+ assertEquals(6, keyValues.length);
+
+ long lastTimestamp = result.getColumnCells(family1, family1_column1).get(0).getTimestamp();
+ assertEquals(lastTimestamp, result.getColumnCells(family1, family1_column3).get(0)
+ .getTimestamp());
+ assertEquals(lastTimestamp, result.getColumnCells(family2, family2_column2).get(0)
+ .getTimestamp());
+ assertEquals(lastTimestamp, result.getColumnCells(family3, family3_column1).get(0)
+ .getTimestamp());
+
+ long oldTimestamp = result.getColumnCells(family1, family1_column2).get(0).getTimestamp();
+ assertEquals(oldTimestamp, result.getColumnCells(family2, family2_column1).get(0)
+ .getTimestamp());
+ assertTrue(lastTimestamp > oldTimestamp);
+ }
+
+ @Test
+ public void testFamilyFilter() throws Exception {
+ String key1 = "getKey1";
+ String key2 = "getKey2";
+ String column1 = "abc";
+ String column2 = "def";
+ String value1 = "value1";
+ String value2 = "value2";
+ String family1 = "family_with_group1";
+ String family2 = "family_with_group2";
+ String family3 = "family_with_group3";
+
+ Delete deleteKey1 = new Delete(toBytes(key1));
+ deleteKey1.deleteFamily(toBytes(family1));
+ deleteKey1.deleteFamily(toBytes(family2));
+ deleteKey1.deleteFamily(toBytes(family3));
+ Delete deleteKey2 = new Delete(toBytes(key2));
+ deleteKey2.deleteFamily(toBytes(family1));
+ deleteKey2.deleteFamily(toBytes(family2));
+ deleteKey2.deleteFamily(toBytes(family3));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family1), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family2), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family2), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family3), toBytes(column2), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family3), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family3), toBytes(column1), toBytes(value2));
+
+ multiCfHTable.delete(deleteKey1);
+ multiCfHTable.delete(deleteKey2);
+ multiCfHTable.put(putKey1Column1Value1);
+ multiCfHTable.put(putKey1Column1Value2);
+ multiCfHTable.put(putKey1Column2Value2);
+ multiCfHTable.put(putKey2Column2Value1);
+ multiCfHTable.put(putKey2Column1Value1);
+ multiCfHTable.put(putKey2Column1Value2);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family1.getBytes());
+ scan.addFamily(family2.getBytes());
+ scan.addFamily(family3.getBytes());
+ scan.setMaxVersions(10);
+ FamilyFilter f = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ Bytes.toBytes(family2)));
+ scan.setFilter(f);
+ ResultScanner scanner = multiCfHTable.getScanner(scan);
+
+ int res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ Assert.assertArrayEquals(family2.getBytes(), keyValue.getFamily());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family1.getBytes());
+ scan.addFamily(family2.getBytes());
+ scan.addFamily(family3.getBytes());
+ scan.setMaxVersions(10);
+ f = new FamilyFilter(CompareFilter.CompareOp.NOT_EQUAL, new BinaryComparator(
+ Bytes.toBytes(family2)));
+ scan.setFilter(f);
+ scanner = multiCfHTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 4);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family1.getBytes());
+ scan.addFamily(family2.getBytes());
+ scan.addFamily(family3.getBytes());
+ scan.setMaxVersions(10);
+ f = new FamilyFilter(CompareFilter.CompareOp.GREATER, new BinaryComparator(
+ Bytes.toBytes(family2)));
+ scan.setFilter(f);
+ scanner = multiCfHTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ Assert.assertArrayEquals(family3.getBytes(), keyValue.getFamily());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 3);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family1.getBytes());
+ scan.addFamily(family2.getBytes());
+ scan.addFamily(family3.getBytes());
+ scan.setMaxVersions(10);
+ f = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(
+ Bytes.toBytes("family_with_group")));
+ scan.setFilter(f);
+ scanner = multiCfHTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 6);
+ scanner.close();
+ }
+}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/HTableTestBase.java b/src/test/java/com/alipay/oceanbase/hbase/HTableTestBase.java
index 4c93efde..9d32921d 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/HTableTestBase.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/HTableTestBase.java
@@ -24,7 +24,9 @@
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.*;
+import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
@@ -42,12 +44,12 @@
import static org.apache.hadoop.hbase.util.Bytes.toBytes;
import static org.junit.Assert.*;
-public abstract class HTableTestBase {
+public abstract class HTableTestBase extends HTableMultiCFTestBase {
@Rule
public ExpectedException expectedException = ExpectedException.none();
- protected Table hTable;
+ protected static Table hTable;
@Test
public void testTableGroup() throws IOError, IOException {
@@ -103,7 +105,7 @@ PRIMARY KEY (`K`, `Q`, `T`)
}
// test scan with empty family
- Scan scan = new Scan();
+ Scan scan = new Scan(toBytes(key));
ResultScanner scanner = hTable.getScanner(scan);
for (Result result : scanner) {
for (KeyValue keyValue : result.raw()) {
@@ -131,9 +133,6 @@ private void testBasic(String family) throws Exception {
String column2 = "putColumn2";
String value = "value";
long timestamp = System.currentTimeMillis();
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
Put put = new Put(toBytes(key));
put.add(family.getBytes(), column1.getBytes(), timestamp, toBytes(value));
@@ -167,7 +166,7 @@ private void testBasic(String family) throws Exception {
r = hTable.get(get);
Assert.assertEquals(1, r.raw().length);
- delete = new Delete(key.getBytes());
+ Delete delete = new Delete(key.getBytes());
delete.deleteFamily(family.getBytes());
hTable.delete(delete);
@@ -405,27 +404,7 @@ public void testMultiPartitionDel() throws IOException {
String column1 = "column1";
String column2 = "column2";
String column3 = "column3";
- String value = "value";
String family = "familyPartition";
- // delete
- {
- List deletes = new ArrayList();
- for (String key : keys) {
- Delete del = new Delete(Bytes.toBytes(key));
- del.deleteColumns(toBytes(family), toBytes(column1));
- del.deleteColumns(toBytes(family), toBytes(column2), System.currentTimeMillis());
- deletes.add(del);
- }
-
- for (String key : keys) {
- // del same k, q, t
- Delete del = new Delete(Bytes.toBytes(key));
- del.deleteColumn(toBytes(family), toBytes(column3), 100L);
- del.deleteColumn(toBytes(family), toBytes(column3), 100L);
- deletes.add(del);
- }
- hTable.delete(deletes);
- }
// get
{
List gets = new ArrayList();
@@ -458,7 +437,6 @@ public void testFilter() throws Exception {
String column2 = "def";
String value1 = "value1";
String value2 = "value2";
- String value3 = "value3";
String family = "family1";
Delete deleteKey1Family = new Delete(toBytes(key1));
deleteKey1Family.deleteFamily(toBytes(family));
@@ -466,9 +444,6 @@ public void testFilter() throws Exception {
Delete deleteKey2Family = new Delete(toBytes(key2));
deleteKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -497,8 +472,6 @@ public void testFilter() throws Exception {
Result r;
ColumnPrefixFilter filter;
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
tryPut(hTable, putKey1Column1Value1);
tryPut(hTable, putKey1Column1Value2);
tryPut(hTable, putKey1Column1Value1);
@@ -509,6 +482,81 @@ public void testFilter() throws Exception {
tryPut(hTable, putKey2Column2Value1);
tryPut(hTable, putKey2Column2Value2);
+ // time may be different
+ // +---------+-----+----------------+--------+
+ // | K | Q | T | V |
+ // +---------+-----+----------------+--------+
+ // | getKey1 | abc | -1728834971469 | value1 |
+ // | getKey1 | abc | -1728834971399 | value2 |
+ // | getKey1 | abc | -1728834971330 | value1 |
+ // | getKey1 | def | -1728834971748 | value2 |
+ // | getKey1 | def | -1728834971679 | value1 |
+ // | getKey1 | def | -1728834971609 | value2 |
+ // | getKey1 | def | -1728834971540 | value1 |
+ // | getKey2 | def | -1728834971887 | value2 |
+ // | getKey2 | def | -1728834971818 | value1 |
+ // +---------+-----+----------------+--------+
+
+ SingleColumnValueFilter singleColumnValueFilter;
+ singleColumnValueFilter = new SingleColumnValueFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value1)));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(singleColumnValueFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(7, r.raw().length);
+
+ SingleColumnValueExcludeFilter singleColumnValueExcludeFilter;
+ singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value1)));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(singleColumnValueExcludeFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(4, r.raw().length);
+
+ DependentColumnFilter dependentColumnFilter = new DependentColumnFilter(
+ Bytes.toBytes(family), Bytes.toBytes(column1), false);
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(dependentColumnFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
+ dependentColumnFilter = new DependentColumnFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), true);
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(dependentColumnFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ dependentColumnFilter = new DependentColumnFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), false, CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value2)));
+ get = new Get(toBytes(key2));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(dependentColumnFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ dependentColumnFilter = new DependentColumnFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column2), false, CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value2)));
+ get = new Get(toBytes(key2));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(dependentColumnFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
+
filter = new ColumnPrefixFilter(Bytes.toBytes("e"));
get = new Get(toBytes(key1));
get.setMaxVersions(10);
@@ -817,28 +865,84 @@ public void testFilter() throws Exception {
}
Assert.assertEquals(res_count, 12);
scanner.close();
+
+ long timestamp = System.currentTimeMillis();
+ putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), timestamp, toBytes(value1));
+
+ putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), timestamp, toBytes(value1));
+
+ putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ // putKey1Column1Value1 and putKey2Column1Value1 have the same timestamp
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column1Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ dependentColumnFilter = new DependentColumnFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), false, CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value1)));
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ scan.setFilter(dependentColumnFilter);
+ scanner = hTable.getScanner(scan);
+
+ long prevTimestamp = -1;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ if (prevTimestamp == -1) {
+ prevTimestamp = keyValue.getTimestamp();
+ } else {
+ Assert.assertEquals(prevTimestamp, keyValue.getTimestamp());
+ }
+ }
+ }
+ scanner.close();
}
@Test
- public void testFilter2() throws Exception {
- String key1 = "getKey1";
- String key2 = "getKey2";
+ public void testRowRangeFilter() throws Exception {
+ String key1 = "ka1";
+ String key2 = "kb2";
String column1 = "abc";
String column2 = "def";
String value1 = "value1";
String value2 = "value2";
String value3 = "value3";
String family = "family1";
- long ts;
Delete deleteKey1Family = new Delete(toBytes(key1));
deleteKey1Family.deleteFamily(toBytes(family));
Delete deleteKey2Family = new Delete(toBytes(key2));
deleteKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -863,9 +967,6 @@ public void testFilter2() throws Exception {
Put putKey2Column2Value1 = new Put(toBytes(key2));
putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
- Get get;
- Result r;
-
hTable.delete(deleteKey1Family);
hTable.delete(deleteKey2Family);
tryPut(hTable, putKey1Column1Value1);
@@ -878,90 +979,56 @@ public void testFilter2() throws Exception {
tryPut(hTable, putKey2Column2Value1);
tryPut(hTable, putKey2Column2Value2);
- FirstKeyOnlyFilter filter = new FirstKeyOnlyFilter();
- get = new Get(toBytes(key1));
- get.setMaxVersions(10);
- get.addFamily(toBytes(family));
- get.setFilter(filter);
- r = hTable.get(get);
- Assert.assertEquals(1, r.raw().length);
-
- KeyOnlyFilter kFilter = new KeyOnlyFilter();
- get = new Get(toBytes(key1));
- get.setMaxVersions(10);
- get.addFamily(toBytes(family));
- get.setFilter(kFilter);
- r = hTable.get(get);
- Assert.assertEquals(7, r.raw().length);
-
- ts = r.rawCells()[0].getTimestamp();
-
- List tss = new ArrayList<>();
- tss.add(ts - 1);
- tss.add(ts);
- tss.add(ts + 1);
- TimestampsFilter tFilter = new TimestampsFilter(tss);
- get = new Get(toBytes(key1));
- get.setMaxVersions(10);
- get.addFamily(toBytes(family));
- get.setFilter(tFilter);
- r = hTable.get(get);
- Assert.assertEquals(1, r.raw().length);
-
- tss = new ArrayList<>();
- tss.add(ts - 1);
- tss.add(ts + 1);
- tFilter = new TimestampsFilter(tss);
- get = new Get(toBytes(key1));
- get.setMaxVersions(10);
- get.addFamily(toBytes(family));
- get.setFilter(tFilter);
- r = hTable.get(get);
- Assert.assertEquals(0, r.raw().length);
-
- Put putKey1Column3Value1 = new Put(toBytes(key1));
- putKey1Column3Value1.add(toBytes(family), toBytes("ggg"), toBytes(value1));
- tryPut(hTable, putKey1Column3Value1);
-
Scan scan;
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
+ List ranges = new ArrayList<>();
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("ka3"), true, Bytes.toBytes("kd4"), false));
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("c"), true, Bytes.toBytes("d$%%"), false));
+ MultiRowRangeFilter filter = new MultiRowRangeFilter(ranges);
+ scan.setFilter(filter);
ResultScanner scanner = hTable.getScanner(scan);
int res_count = 0;
for (Result result : scanner) {
for (KeyValue keyValue : result.raw()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
- }
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 2);
scanner.close();
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- filter = new FirstKeyOnlyFilter();
+ scan.setReversed(true);
+ ranges = new ArrayList<>();
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("ka3"), true, Bytes.toBytes("kd4"), false));
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("c"), true, Bytes.toBytes("d$%%"), false));
+ filter = new MultiRowRangeFilter(ranges);
scan.setFilter(filter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
for (KeyValue keyValue : result.raw()) {
- if (res_count < 1) {
- Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
- }
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
res_count += 1;
}
}
@@ -970,157 +1037,1134 @@ public void testFilter2() throws Exception {
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- kFilter = new KeyOnlyFilter();
- scan.setFilter(kFilter);
+ scan.setReversed(true);
+ ranges = new ArrayList<>();
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("kb2"), false, Bytes.toBytes("kd4"), false));
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("kb11"), true, Bytes.toBytes("kb2"), true));
+ filter = new MultiRowRangeFilter(ranges);
+ scan.setFilter(filter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
for (KeyValue keyValue : result.raw()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
- }
- Assert.assertEquals(0, keyValue.getValueLength());
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 2);
scanner.close();
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- kFilter = new KeyOnlyFilter(true);
- scan.setFilter(kFilter);
+ scan.setReversed(true);
+ ranges = new ArrayList<>();
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("z4"), true, Bytes.toBytes("zzzsad"), true));
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("kb2"), true, Bytes.toBytes("kd4"), false));
+ filter = new MultiRowRangeFilter(ranges);
+ scan.setFilter(filter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
- for (Cell cell : result.rawCells()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
- }
- Assert.assertEquals(4, cell.getValueLength());
- Assert.assertEquals(6, Bytes.toInt(CellUtil.cloneValue(cell)));
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 2);
scanner.close();
- FilterList filterList = new FilterList(MUST_PASS_ONE);
- filterList.addFilter(new KeyOnlyFilter(false));
- filterList.addFilter(new KeyOnlyFilter(true));
+ // Inclusive stop filter
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- scan.setFilter(filterList);
+ InclusiveStopFilter iFilter = new InclusiveStopFilter(Bytes.toBytes("ka1"));
+ scan.setFilter(iFilter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
- for (Cell cell : result.rawCells()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
- }
- Assert.assertEquals(4, cell.getValueLength());
- Assert.assertEquals(0, Bytes.toInt(CellUtil.cloneValue(cell)));
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 7);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setReversed(true);
+ scan.setMaxVersions(10);
+ iFilter = new InclusiveStopFilter(Bytes.toBytes("ka1"));
+ scan.setFilter(iFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 7);
scanner.close();
- filterList = new FilterList(MUST_PASS_ALL);
- filterList.addFilter(new KeyOnlyFilter(false));
- filterList.addFilter(new KeyOnlyFilter(true));
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- scan.setFilter(filterList);
- scanner = hTable.getScanner(scan);
+ iFilter = new InclusiveStopFilter(Bytes.toBytes("kb1"));
+ scan.setFilter(iFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 7);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ iFilter = new InclusiveStopFilter(Bytes.toBytes("kb2"));
+ scan.setFilter(iFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 9);
+ scanner.close();
+ }
+
+ @Test
+ public void testColumnRangeFilter() throws Exception {
+ String key1 = "ka1";
+ String key2 = "kb2";
+ String column1 = "abc";
+ String column2 = "def";
+ String value1 = "value1";
+ String value2 = "value2";
+ String family = "family1";
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family));
+
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ ColumnRangeFilter filter = new ColumnRangeFilter(Bytes.toBytes("a"), true,
+ Bytes.toBytes("b"), false);
+ scan.setFilter(filter);
+ ResultScanner scanner = hTable.getScanner(scan);
+
+ int res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(3, res_count);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ filter = new ColumnRangeFilter(Bytes.toBytes("abc"), true, Bytes.toBytes("def"), false);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(3, res_count);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ filter = new ColumnRangeFilter(Bytes.toBytes("abc"), false, Bytes.toBytes("def"), true);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(6, res_count);
+ scanner.close();
+
+ // MultipleColumnPrefixFilter
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ byte[][] range = { Bytes.toBytes("g"), Bytes.toBytes("3"), Bytes.toBytes("d"), };
+ MultipleColumnPrefixFilter iFilter = new MultipleColumnPrefixFilter(range);
+ scan.setFilter(iFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(6, res_count);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ // 和原生hbase不一致,已知
+ range = new byte[][] { Bytes.toBytes("de"), Bytes.toBytes("bg"), Bytes.toBytes("nc"),
+ Bytes.toBytes("aa"), Bytes.toBytes("abcd"), Bytes.toBytes("dea"), };
+ iFilter = new MultipleColumnPrefixFilter(range);
+ scan.setFilter(iFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(6, res_count);
+ scanner.close();
+ }
+
+ @Test
+ public void testFilterNullRange() throws Exception {
+ String key1 = "ka1";
+ String key2 = "kb2";
+ String column1 = "abc";
+ String column2 = "def";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+ String family = "family1";
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family));
+
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ byte[][] r = {};
+ MultipleColumnPrefixFilter iFilter = new MultipleColumnPrefixFilter(r);
+ scan.setFilter(iFilter);
+ ResultScanner scanner = hTable.getScanner(scan);
+
+ int res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out
+ .printf(
+ "Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()), Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()), keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue()));
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 0);
+ scanner.close();
+ }
+
+ @Test
+ public void testFilter2() throws Exception {
+ String key1 = "getKey1";
+ String key2 = "getKey2";
+ String column1 = "abc";
+ String column2 = "def";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+ String family = "family1";
+ long ts;
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family));
+
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Get get;
+ Result r;
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ FirstKeyOnlyFilter filter = new FirstKeyOnlyFilter();
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filter);
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
+
+ KeyOnlyFilter kFilter = new KeyOnlyFilter();
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(kFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(7, r.raw().length);
+
+ ts = r.rawCells()[0].getTimestamp();
+
+ List tss = new ArrayList<>();
+ tss.add(ts - 1);
+ tss.add(ts);
+ tss.add(ts + 1);
+ TimestampsFilter tFilter = new TimestampsFilter(tss);
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(tFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
+
+ tss = new ArrayList<>();
+ tss.add(ts - 1);
+ tss.add(ts + 1);
+ tFilter = new TimestampsFilter(tss);
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(tFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ Put putKey1Column3Value1 = new Put(toBytes(key1));
+ putKey1Column3Value1.add(toBytes(family), toBytes("ggg"), toBytes(value1));
+ tryPut(hTable, putKey1Column3Value1);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ ResultScanner scanner = hTable.getScanner(scan);
+
+ int res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
+ }
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ filter = new FirstKeyOnlyFilter();
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ if (res_count < 1) {
+ Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
+ }
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ kFilter = new KeyOnlyFilter();
+ scan.setFilter(kFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), keyValue.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), keyValue.getRow());
+ }
+ Assert.assertEquals(0, keyValue.getValueLength());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ kFilter = new KeyOnlyFilter(true);
+ scan.setFilter(kFilter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (Cell cell : result.rawCells()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
+ }
+ Assert.assertEquals(4, cell.getValueLength());
+ Assert.assertEquals(6, Bytes.toInt(CellUtil.cloneValue(cell)));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ FilterList filterList = new FilterList(MUST_PASS_ONE);
+ filterList.addFilter(new KeyOnlyFilter(false));
+ filterList.addFilter(new KeyOnlyFilter(true));
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ scan.setFilter(filterList);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (Cell cell : result.rawCells()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
+ }
+ Assert.assertEquals(4, cell.getValueLength());
+ Assert.assertEquals(0, Bytes.toInt(CellUtil.cloneValue(cell)));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ filterList = new FilterList(MUST_PASS_ALL);
+ filterList.addFilter(new KeyOnlyFilter(false));
+ filterList.addFilter(new KeyOnlyFilter(true));
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ scan.setFilter(filterList);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (Cell cell : result.rawCells()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
+ }
+ Assert.assertEquals(4, cell.getValueLength());
+ Assert.assertEquals(0, Bytes.toInt(CellUtil.cloneValue(cell)));
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ filterList = new FilterList(MUST_PASS_ONE);
+ filterList.addFilter(new KeyOnlyFilter(true));
+ filterList.addFilter(new KeyOnlyFilter(false));
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ scan.setFilter(filterList);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (Cell cell : result.rawCells()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
+ }
+ Assert.assertEquals(0, cell.getValueLength());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ filterList = new FilterList(MUST_PASS_ALL);
+ filterList.addFilter(new KeyOnlyFilter(true));
+ filterList.addFilter(new KeyOnlyFilter(false));
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setStartRow("getKey1".getBytes());
+ scan.setStopRow("getKey3".getBytes());
+ scan.setMaxVersions(10);
+ scan.setFilter(filterList);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (Cell cell : result.rawCells()) {
+ if (res_count < 8) {
+ Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
+ } else {
+ Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
+ }
+ Assert.assertEquals(0, cell.getValueLength());
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+ }
+
+ @Test
+ public void testFuzzyRowFilter() throws Exception {
+ String key1 = "abab";
+ String key2 = "abcc";
+ String column1 = "c1";
+ String column2 = "c2";
+ String column3 = "c3";
+ String column4 = "c4";
+ String column5 = "c5";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+ String family = "family1";
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family));
+
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Put putKey1Column3Value1 = new Put(toBytes(key1));
+ putKey1Column3Value1.add(toBytes(family), toBytes(column3), toBytes(value1));
+
+ Put putKey1Column4Value1 = new Put(toBytes(key1));
+ putKey1Column4Value1.add(toBytes(family), toBytes(column4), toBytes(value1));
+
+ Put putKey1Column5Value1 = new Put(toBytes(key1));
+ putKey1Column5Value1.add(toBytes(family), toBytes(column5), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column3Value1);
+ tryPut(hTable, putKey1Column4Value1);
+ tryPut(hTable, putKey1Column5Value1);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ List> fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("abab"), Bytes.toBytes("0000")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ FuzzyRowFilter filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ ResultScanner scanner = hTable.getScanner(scan);
+
+ int res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("abcc"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("ccab"), Bytes.toBytes("1100")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 10);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("cccc"), Bytes.toBytes("1100")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("ab##"), Bytes.toBytes("0011")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 12);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("azc"), Bytes.toBytes("010")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("azccd"), Bytes.toBytes("01001")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 2);
+ scanner.close();
+
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ scan.setReversed(true);
+ fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes(""), Bytes.toBytes("")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("dddd"), Bytes.toBytes("0000")));
+ filter = new FuzzyRowFilter(fuzzyKey);
+ scan.setFilter(filter);
+ scanner = hTable.getScanner(scan);
+
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
+ res_count += 1;
+ }
+ }
+ Assert.assertEquals(res_count, 12);
+ scanner.close();
+ }
+
+ @Test
+ public void testFirstKeyValueMatchingQualifiersFilter() throws Exception {
+ String key1 = "getKey1";
+ String key2 = "getKey2";
+ String column1 = "c1";
+ String column2 = "c2";
+ String column3 = "c3";
+ String column4 = "c4";
+ String column5 = "c5";
+ String value1 = "value1";
+ String value2 = "value2";
+ String value3 = "value3";
+ String family = "family1";
+ Delete deleteKey1Family = new Delete(toBytes(key1));
+ deleteKey1Family.deleteFamily(toBytes(family));
+
+ Delete deleteKey2Family = new Delete(toBytes(key2));
+ deleteKey2Family.deleteFamily(toBytes(family));
+
+ Put putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ Put putKey1Column3Value1 = new Put(toBytes(key1));
+ putKey1Column3Value1.add(toBytes(family), toBytes(column3), toBytes(value1));
+
+ Put putKey1Column4Value1 = new Put(toBytes(key1));
+ putKey1Column4Value1.add(toBytes(family), toBytes(column4), toBytes(value1));
+
+ Put putKey1Column5Value1 = new Put(toBytes(key1));
+ putKey1Column5Value1.add(toBytes(family), toBytes(column5), toBytes(value1));
+
+ Put putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
+
+ Put putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), toBytes(value2));
+
+ Put putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), toBytes(value2));
+
+ Put putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), toBytes(value1));
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey1Column3Value1);
+ tryPut(hTable, putKey1Column4Value1);
+ tryPut(hTable, putKey1Column5Value1);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+
+ Scan scan;
+ scan = new Scan();
+ scan.addFamily(family.getBytes());
+ scan.setMaxVersions(10);
+ TreeSet qualifiers = new TreeSet<>(Bytes.BYTES_COMPARATOR);
+ qualifiers.add(Bytes.toBytes("c11"));
+ qualifiers.add(Bytes.toBytes("c2"));
+ FirstKeyValueMatchingQualifiersFilter filter = new FirstKeyValueMatchingQualifiersFilter(qualifiers);
+ scan.setFilter(filter);
+ ResultScanner scanner = hTable.getScanner(scan);
- res_count = 0;
+ int res_count = 0;
for (Result result : scanner) {
- for (Cell cell : result.rawCells()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
- }
- Assert.assertEquals(4, cell.getValueLength());
- Assert.assertEquals(0, Bytes.toInt(CellUtil.cloneValue(cell)));
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 5);
scanner.close();
- filterList = new FilterList(MUST_PASS_ONE);
- filterList.addFilter(new KeyOnlyFilter(true));
- filterList.addFilter(new KeyOnlyFilter(false));
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- scan.setFilter(filterList);
+ scan.setReversed(true);
+ qualifiers = new TreeSet<>(Bytes.BYTES_COMPARATOR);
+ qualifiers.add(Bytes.toBytes("c22"));
+ qualifiers.add(Bytes.toBytes("c4"));
+ filter = new FirstKeyValueMatchingQualifiersFilter(qualifiers);
+ scan.setFilter(filter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
- for (Cell cell : result.rawCells()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
- }
- Assert.assertEquals(0, cell.getValueLength());
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 11);
scanner.close();
- filterList = new FilterList(MUST_PASS_ALL);
- filterList.addFilter(new KeyOnlyFilter(true));
- filterList.addFilter(new KeyOnlyFilter(false));
scan = new Scan();
scan.addFamily(family.getBytes());
- scan.setStartRow("getKey1".getBytes());
- scan.setStopRow("getKey3".getBytes());
scan.setMaxVersions(10);
- scan.setFilter(filterList);
+ scan.setReversed(true);
+ qualifiers = new TreeSet<>(Bytes.BYTES_COMPARATOR);
+ qualifiers.add(Bytes.toBytes("c22"));
+ qualifiers.add(Bytes.toBytes("a"));
+ filter = new FirstKeyValueMatchingQualifiersFilter(qualifiers);
+ scan.setFilter(filter);
scanner = hTable.getScanner(scan);
res_count = 0;
for (Result result : scanner) {
- for (Cell cell : result.rawCells()) {
- if (res_count < 8) {
- Assert.assertArrayEquals(key1.getBytes(), cell.getRow());
- } else {
- Assert.assertArrayEquals(key2.getBytes(), cell.getRow());
- }
- Assert.assertEquals(0, cell.getValueLength());
+ for (KeyValue keyValue : result.raw()) {
+ System.out.printf("Rowkey: %s, Column Family: %s, Column Qualifier: %s, Timestamp: %d, Value: %s%n",
+ Bytes.toString(result.getRow()),
+ Bytes.toString(keyValue.getFamily()),
+ Bytes.toString(keyValue.getQualifier()),
+ keyValue.getTimestamp(),
+ Bytes.toString(keyValue.getValue())
+ );
res_count += 1;
}
}
- Assert.assertEquals(res_count, 10);
+ Assert.assertEquals(res_count, 12);
scanner.close();
}
@@ -1140,9 +2184,6 @@ public void testGetFilter() throws Exception {
Delete deleteKey2Family = new Delete(toBytes(key2));
deleteKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -1242,6 +2283,15 @@ public void testGetFilter() throws Exception {
r = hTable.get(get);
Assert.assertEquals(1, r.raw().length);
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ DependentColumnFilter dependentColumnFilter = new DependentColumnFilter(
+ Bytes.toBytes(family), Bytes.toBytes(column1));
+ get.setFilter(dependentColumnFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
// columnCountGetFilter filter 2
get = new Get(toBytes(key1));
get.setMaxVersions(10);
@@ -1422,6 +2472,67 @@ public void testGetFilter() throws Exception {
r = hTable.get(get);
Assert.assertEquals(7, r.raw().length);
+ filterList = new FilterList();
+ filterList.addFilter(new SingleColumnValueExcludeFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column1), CompareFilter.CompareOp.EQUAL, Bytes.toBytes(value1)));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(4, r.raw().length);
+
+ filterList = new FilterList();
+ filterList.addFilter(new DependentColumnFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column1), false));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
+ filterList = new FilterList();
+ filterList.addFilter(new DependentColumnFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column2), false));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(4, r.raw().length);
+
+ filterList = new FilterList();
+ filterList.addFilter(new DependentColumnFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column2)));
+ get = new Get(toBytes(key2));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(2, r.raw().length);
+
+ filterList = new FilterList();
+ filterList.addFilter(new DependentColumnFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column2), true));
+ get = new Get(toBytes(key2));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(0, r.raw().length);
+
+ filterList = new FilterList();
+ filterList.addFilter(new DependentColumnFilter(Bytes.toBytes(family), Bytes
+ .toBytes(column2), false, CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value2))));
+ get = new Get(toBytes(key2));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(filterList);
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
+
filterList = new FilterList();
filterList.addFilter(new ColumnCountGetFilter(1));
filterList.addFilter(new QualifierFilter(CompareFilter.CompareOp.GREATER,
@@ -1547,6 +2658,17 @@ public void testGetFilter() throws Exception {
r = hTable.get(get);
Assert.assertEquals(7, r.raw().length);
+ SingleColumnValueExcludeFilter singleColumnValueExcludeFilter;
+ singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(Bytes.toBytes(family),
+ Bytes.toBytes(column1), CompareFilter.CompareOp.EQUAL, new BinaryComparator(
+ toBytes(value1)));
+ get = new Get(toBytes(key1));
+ get.setMaxVersions(10);
+ get.addFamily(toBytes(family));
+ get.setFilter(singleColumnValueExcludeFilter);
+ r = hTable.get(get);
+ Assert.assertEquals(4, r.raw().length);
+
singleColumnValueFilter = new SingleColumnValueFilter(Bytes.toBytes(family),
Bytes.toBytes(column1), CompareFilter.CompareOp.EQUAL, new BinaryComparator(
toBytes(value2)));
@@ -1721,11 +2843,6 @@ public void testScanWithObParams() throws Exception {
Delete deleteKey4Family = new Delete(toBytes(key4));
deleteKey4Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteKey4Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -1825,12 +2942,6 @@ public void testScanSessionClean() throws Exception {
Delete deleteKey5Family = new Delete(toBytes(key5));
deleteKey5Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteKey4Family);
- hTable.delete(deleteKey5Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -1894,7 +3005,6 @@ public void testGet() throws Exception {
String column2 = "column2";
String value1 = "value1";
String value2 = "value2";
- String value3 = "value3";
String family = "family1";
// delete previous data
@@ -1909,12 +3019,6 @@ public void testGet() throws Exception {
Delete deleteZKey2Family = new Delete(toBytes(zKey2));
deleteZKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteZKey1Family);
- hTable.delete(deleteZKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -1978,54 +3082,206 @@ public void testGet() throws Exception {
tryPut(hTable, putzKey2Column1Value1);
// show table (time maybe different)
- //+-----------+---------+----------------+--------+
- //| K | Q | T | V |
- //+-----------+---------+----------------+--------+
- //| scanKey1x | column1 | -1709714409669 | value1 |
- //| scanKey1x | column1 | -1709714409637 | value2 |
- //| scanKey1x | column1 | -1709714409603 | value1 |
- //| scanKey1x | column2 | -1709714409802 | value2 |
- //| scanKey1x | column2 | -1709714409768 | value1 |
- //| scanKey1x | column2 | -1709714409735 | value2 |
- //| scanKey1x | column2 | -1709714409702 | value1 |
- //| scanKey2x | column2 | -1709714409869 | value2 |
- //| scanKey2x | column2 | -1709714409836 | value1 |
- //| scanKey3x | column1 | -1709714409940 | value2 |
- //| scanKey3x | column1 | -1709714409904 | value1 |
- //| scanKey3x | column2 | -1709714410010 | value2 |
- //| scanKey3x | column2 | -1709714409977 | value1 |
- //+-----------+---------+----------------+--------+
+ // +-----------+---------+----------------+--------+
+ // | K | Q | T | V |
+ // +-----------+---------+----------------+--------+
+ // | scanKey1x | column1 | -1729223351579 | value1 |
+ // | scanKey1x | column1 | -1729223351504 | value2 |
+ // | scanKey1x | column1 | -1729223351431 | value1 |
+ // | scanKey1x | column2 | -1729223351867 | value2 |
+ // | scanKey1x | column2 | -1729223351796 | value1 |
+ // | scanKey1x | column2 | -1729223351724 | value2 |
+ // | scanKey1x | column2 | -1729223351651 | value1 |
+ // | scanKey2x | column2 | -1729223352015 | value2 |
+ // | scanKey2x | column2 | -1729223351941 | value1 |
+ // | scanKey3x | column1 | -1729223352159 | value2 |
+ // | scanKey3x | column1 | -1729223352088 | value1 |
+ // | scanKey3x | column2 | -1729223352304 | value2 |
+ // | scanKey3x | column2 | -1729223352232 | value1 |
+ // | zScanKey1 | column1 | -1729223352378 | value1 |
+ // | zScanKey2 | column1 | -1729223352450 | value1 |
+ // +-----------+---------+----------------+--------+
+
+ // test closestRowBefore
+ get = new Get("scanKey2x2".getBytes());
+ get.addFamily(family.getBytes());
+ get.setClosestRowBefore(true);
+ r = hTable.get(get);
+ assertEquals(key2, Bytes.toString(r.getRow()));
+
+ // test exists
+ LinkedList gets = new LinkedList<>();
+ Get get1 = new Get(key1.getBytes());
+ get1.addFamily(family.getBytes());
+ Get get2 = new Get(key3.getBytes());
+ get2.addFamily(family.getBytes());
+ Get get3 = new Get(key1.getBytes());
+ get3.addFamily(family.getBytes());
+ Get get4 = new Get("scanKey2x2".getBytes());
+ get4.addFamily(family.getBytes());
+ Get get5 = new Get(key2.getBytes());
+ get5.addFamily(family.getBytes());
+ gets.add(get1);
+ gets.add(get2);
+ gets.add(get3);
+ gets.add(get4);
+ gets.add(get5);
+ boolean[] booleans = hTable.existsAll(gets);
+ assertTrue(booleans[0]);
+ assertTrue(booleans[1]);
+ assertTrue(booleans[2]);
+ assertFalse(booleans[3]);
+ assertTrue(booleans[4]);
+
+ // test single cf setColumnFamilyTimeRange
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ hTable.delete(deleteKey3Family);
+ hTable.delete(deleteZKey1Family);
+ hTable.delete(deleteZKey2Family);
+
+ long minTimeStamp = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp1 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp2 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp3 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp4 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp5 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp6 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp7 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp8 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp9 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp10 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp11 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long maxTimeStamp = System.currentTimeMillis();
+
+ putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), minTimeStamp, toBytes(value1));
+
+ putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), timeStamp1, toBytes(value2));
+
+ putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), timeStamp2, toBytes(value1));
+
+ putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), timeStamp3, toBytes(value2));
+
+ putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), timeStamp4, toBytes(value1));
+
+ putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), timeStamp5, toBytes(value2));
+
+ putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), timeStamp6, toBytes(value1));
+
+ putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), timeStamp7, toBytes(value2));
+
+ putKey3Column1Value1 = new Put(toBytes(key3));
+ putKey3Column1Value1.add(toBytes(family), toBytes(column1), timeStamp8, toBytes(value1));
+
+ putKey3Column1Value2 = new Put(toBytes(key3));
+ putKey3Column1Value2.add(toBytes(family), toBytes(column1), timeStamp9, toBytes(value2));
+
+ putKey3Column2Value1 = new Put(toBytes(key3));
+ putKey3Column2Value1.add(toBytes(family), toBytes(column2), timeStamp10, toBytes(value1));
+
+ putKey3Column2Value2 = new Put(toBytes(key3));
+ putKey3Column2Value2.add(toBytes(family), toBytes(column2), timeStamp11, toBytes(value2));
+
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column1Value1);
+ tryPut(hTable, putKey2Column1Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+ tryPut(hTable, putKey3Column1Value1);
+ tryPut(hTable, putKey3Column1Value2);
+ tryPut(hTable, putKey3Column2Value1);
+ tryPut(hTable, putKey3Column2Value2);
+
+
+ get = new Get(toBytes(key1));
+ get.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, maxTimeStamp);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ r = hTable.get(get);
+ Assert.assertEquals(4, r.raw().length);
+
+ get = new Get(toBytes(key1));
+ get.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, timeStamp2 + 1);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
+ get = new Get(toBytes(key2));
+ // set invalid timeRange
+ get.setTimeRange(minTimeStamp, maxTimeStamp);
+ get.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, timeStamp5 + 1);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ r = hTable.get(get);
+ Assert.assertEquals(2, r.raw().length);
+
+ get = new Get(toBytes(key2));
+ get.setColumnFamilyTimeRange(toBytes(family), timeStamp5, maxTimeStamp);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
- // test closestRowBefore
- get = new Get("scanKey2x2".getBytes());
- get.addFamily(family.getBytes());
- get.setClosestRowBefore(true);
+ get = new Get(toBytes(key3));
+ get.setColumnFamilyTimeRange(toBytes(family), timeStamp8, timeStamp8);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
r = hTable.get(get);
- assertEquals(key2, Bytes.toString(r.getRow()));
+ Assert.assertEquals(0, r.raw().length);
- // test exists
- LinkedList gets = new LinkedList<>();
- Get get1 = new Get(key1.getBytes());
- get1.addFamily(family.getBytes());
- Get get2 = new Get(key3.getBytes());
- get2.addFamily(family.getBytes());
- Get get3 = new Get(key1.getBytes());
- get3.addFamily(family.getBytes());
- Get get4 = new Get("scanKey2x2".getBytes());
- get4.addFamily(family.getBytes());
- Get get5 = new Get(key2.getBytes());
- get5.addFamily(family.getBytes());
- gets.add(get1);
- gets.add(get2);
- gets.add(get3);
- gets.add(get4);
- gets.add(get5);
- boolean[] booleans = hTable.existsAll(gets);
- assertTrue(booleans[0]);
- assertTrue(booleans[1]);
- assertTrue(booleans[2]);
- assertFalse(booleans[3]);
- assertTrue(booleans[4]);
+ get = new Get(toBytes(key3));
+ get.setColumnFamilyTimeRange(toBytes(family), timeStamp8, timeStamp9);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
+
+ get = new Get(toBytes(key3));
+ get.setColumnFamilyTimeRange(toBytes(family), timeStamp8, timeStamp9);
+ get.setColumnFamilyTimeRange(toBytes("mockFamily"), timeStamp8, timeStamp9);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ final Get multiFamGet = get;
+ Assert.assertThrows(IOException.class, () -> {
+ hTable.get(multiFamGet);
+ });
+
+ get = new Get(toBytes(key3));
+ get.setColumnFamilyTimeRange(toBytes("mockFamily"), timeStamp8, timeStamp9);
+ get.addFamily(toBytes(family));
+ get.setMaxVersions();
+ final Get missFamGet = get;
+ Assert.assertThrows(IOException.class, () -> {
+ hTable.get(missFamGet);
+ });
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ hTable.delete(deleteKey3Family);
}
@Test
@@ -2039,7 +3295,6 @@ public void testScan() throws Exception {
String column2 = "column2";
String value1 = "value1";
String value2 = "value2";
- String value3 = "value3";
String family = "family1";
// delete previous data
@@ -2054,12 +3309,6 @@ public void testScan() throws Exception {
Delete deleteZKey2Family = new Delete(toBytes(zKey2));
deleteZKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteZKey1Family);
- hTable.delete(deleteZKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -2125,23 +3374,25 @@ public void testScan() throws Exception {
tryPut(hTable, putzKey2Column1Value1);
// show table (time maybe different)
- //+-----------+---------+----------------+--------+
- //| K | Q | T | V |
- //+-----------+---------+----------------+--------+
- //| scanKey1x | column1 | -1709714409669 | value1 |
- //| scanKey1x | column1 | -1709714409637 | value2 |
- //| scanKey1x | column1 | -1709714409603 | value1 |
- //| scanKey1x | column2 | -1709714409802 | value2 |
- //| scanKey1x | column2 | -1709714409768 | value1 |
- //| scanKey1x | column2 | -1709714409735 | value2 |
- //| scanKey1x | column2 | -1709714409702 | value1 |
- //| scanKey2x | column2 | -1709714409869 | value2 |
- //| scanKey2x | column2 | -1709714409836 | value1 |
- //| scanKey3x | column1 | -1709714409940 | value2 |
- //| scanKey3x | column1 | -1709714409904 | value1 |
- //| scanKey3x | column2 | -1709714410010 | value2 |
- //| scanKey3x | column2 | -1709714409977 | value1 |
- //+-----------+---------+----------------+--------+
+ // +-----------+---------+----------------+--------+
+ // | K | Q | T | V |
+ // +-----------+---------+----------------+--------+
+ // | scanKey1x | column1 | -1729236392149 | value1 |
+ // | scanKey1x | column1 | -1729236392078 | value2 |
+ // | scanKey1x | column1 | -1729236392008 | value1 |
+ // | scanKey1x | column2 | -1729236392436 | value2 |
+ // | scanKey1x | column2 | -1729236392364 | value1 |
+ // | scanKey1x | column2 | -1729236392291 | value2 |
+ // | scanKey1x | column2 | -1729236392220 | value1 |
+ // | scanKey2x | column2 | -1729236392576 | value2 |
+ // | scanKey2x | column2 | -1729236392506 | value1 |
+ // | scanKey3x | column1 | -1729236392720 | value2 |
+ // | scanKey3x | column1 | -1729236392647 | value1 |
+ // | scanKey3x | column2 | -1729236392861 | value2 |
+ // | scanKey3x | column2 | -1729236392790 | value1 |
+ // | zScanKey1 | column1 | -1729236392931 | value1 |
+ // | zScanKey2 | column1 | -1729236393002 | value1 |
+ // +-----------+---------+----------------+--------+
scan = new Scan();
scan.addFamily(family.getBytes());
@@ -2328,6 +3579,189 @@ public void testScan() throws Exception {
hTable.delete(deleteKey3Family);
hTable.delete(deleteZKey1Family);
hTable.delete(deleteZKey2Family);
+
+ // test single cf setColumnFamilyTimeRange
+ long minTimeStamp = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp1 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp2 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp3 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp4 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp5 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp6 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp7 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp8 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp9 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp10 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp11 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long maxTimeStamp = System.currentTimeMillis();
+
+ putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), minTimeStamp, toBytes(value1));
+
+ putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), timeStamp1, toBytes(value2));
+
+ putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), timeStamp2, toBytes(value1));
+
+ putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), timeStamp3, toBytes(value2));
+
+ putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), timeStamp4, toBytes(value1));
+
+ putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), timeStamp5, toBytes(value2));
+
+ putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), timeStamp6, toBytes(value1));
+
+ putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), timeStamp7, toBytes(value2));
+
+ putKey3Column1Value1 = new Put(toBytes(key3));
+ putKey3Column1Value1.add(toBytes(family), toBytes(column1), timeStamp8, toBytes(value1));
+
+ putKey3Column1Value2 = new Put(toBytes(key3));
+ putKey3Column1Value2.add(toBytes(family), toBytes(column1), timeStamp9, toBytes(value2));
+
+ putKey3Column2Value1 = new Put(toBytes(key3));
+ putKey3Column2Value1.add(toBytes(family), toBytes(column2), timeStamp10, toBytes(value1));
+
+ putKey3Column2Value2 = new Put(toBytes(key3));
+ putKey3Column2Value2.add(toBytes(family), toBytes(column2), timeStamp11, toBytes(value2));
+
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column1Value1);
+ tryPut(hTable, putKey2Column1Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+ tryPut(hTable, putKey3Column1Value1);
+ tryPut(hTable, putKey3Column1Value2);
+ tryPut(hTable, putKey3Column2Value1);
+ tryPut(hTable, putKey3Column2Value2);
+
+ // scan key1 + key2
+ scan = new Scan(toBytes(key1), toBytes(key3));
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, maxTimeStamp);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow()))
+ || key2.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(8, res_count);
+
+ // scan key1
+ scan = new Scan(toBytes(key1), toBytes(key2));
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, maxTimeStamp);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(4, res_count);
+
+ // scan key1
+ scan = new Scan(toBytes(key1), toBytes(key2));
+ scan.addFamily(toBytes(family));
+ // set invalid timeRange
+ scan.setTimeRange(minTimeStamp, maxTimeStamp);
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp1, timeStamp3);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(2, res_count);
+
+ // scan all
+ scan = new Scan();
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp2, timeStamp7);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow()))
+ || key2.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(5, res_count);
+
+ scan = new Scan();
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp3, timeStamp9);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ boolean foundKey3 = false;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ if (!foundKey3) {
+ if (key3.equals(Bytes.toString(kv.getRow()))) {
+ foundKey3 = true;
+ }
+ }
+ ++res_count;
+ }
+ }
+ Assert.assertTrue(foundKey3);
+ Assert.assertEquals(6, res_count);
+
+ scan = new Scan();
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp3, timeStamp9);
+ scan.setColumnFamilyTimeRange(toBytes("mockFamily"), timeStamp3, timeStamp9);
+ scan.setMaxVersions();
+ final Scan multiFamScan = scan;
+ Assert.assertThrows(IOException.class, () -> {
+ hTable.getScanner(multiFamScan);
+ });
+
+ scan = new Scan();
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes("mockFamily"), timeStamp3, timeStamp9);
+ scan.setMaxVersions();
+ final Scan missFamScan = scan;
+ Assert.assertThrows(IOException.class, () -> {
+ hTable.getScanner(missFamScan);
+ });
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ hTable.delete(deleteKey3Family);
}
@Test
@@ -2356,12 +3790,6 @@ public void testReversedScan() throws Exception {
Delete deleteZKey2Family = new Delete(toBytes(zKey2));
deleteZKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteZKey1Family);
- hTable.delete(deleteZKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -2451,7 +3879,7 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 6);
+ Assert.assertEquals(6, res_count);
scanner.close();
// reverse scan with MaxVersion
@@ -2469,7 +3897,7 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 3);
+ Assert.assertEquals(3, res_count);
scanner.close();
// reverse scan with pageFilter
@@ -2489,7 +3917,7 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 6);
+ Assert.assertEquals(6, res_count);
scanner.close();
// reverse scan with not_exist_start_row
@@ -2507,7 +3935,7 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 6);
+ Assert.assertEquals(6, res_count);
scanner.close();
// reverse scan with abnormal range
@@ -2525,7 +3953,7 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 0);
+ Assert.assertEquals(0, res_count);
scanner.close();
// reverse scan with abnormal range
@@ -2543,13 +3971,205 @@ public void testReversedScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 13);
+ Assert.assertEquals(13, res_count);
scanner.close();
hTable.delete(deleteKey1Family);
hTable.delete(deleteKey2Family);
hTable.delete(deleteKey3Family);
+ // test single cf setColumnFamilyTimeRange
+ long minTimeStamp = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp1 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp2 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp3 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp4 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp5 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp6 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp7 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp8 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp9 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp10 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long timeStamp11 = System.currentTimeMillis();
+ Thread.sleep(5);
+ long maxTimeStamp = System.currentTimeMillis();
+
+ putKey1Column1Value1 = new Put(toBytes(key1));
+ putKey1Column1Value1.add(toBytes(family), toBytes(column1), minTimeStamp, toBytes(value1));
+
+ putKey1Column1Value2 = new Put(toBytes(key1));
+ putKey1Column1Value2.add(toBytes(family), toBytes(column1), timeStamp1, toBytes(value2));
+
+ putKey1Column2Value1 = new Put(toBytes(key1));
+ putKey1Column2Value1.add(toBytes(family), toBytes(column2), timeStamp2, toBytes(value1));
+
+ putKey1Column2Value2 = new Put(toBytes(key1));
+ putKey1Column2Value2.add(toBytes(family), toBytes(column2), timeStamp3, toBytes(value2));
+
+ putKey2Column1Value1 = new Put(toBytes(key2));
+ putKey2Column1Value1.add(toBytes(family), toBytes(column1), timeStamp4, toBytes(value1));
+
+ putKey2Column1Value2 = new Put(toBytes(key2));
+ putKey2Column1Value2.add(toBytes(family), toBytes(column1), timeStamp5, toBytes(value2));
+
+ putKey2Column2Value1 = new Put(toBytes(key2));
+ putKey2Column2Value1.add(toBytes(family), toBytes(column2), timeStamp6, toBytes(value1));
+
+ putKey2Column2Value2 = new Put(toBytes(key2));
+ putKey2Column2Value2.add(toBytes(family), toBytes(column2), timeStamp7, toBytes(value2));
+
+ putKey3Column1Value1 = new Put(toBytes(key3));
+ putKey3Column1Value1.add(toBytes(family), toBytes(column1), timeStamp8, toBytes(value1));
+
+ putKey3Column1Value2 = new Put(toBytes(key3));
+ putKey3Column1Value2.add(toBytes(family), toBytes(column1), timeStamp9, toBytes(value2));
+
+ putKey3Column2Value1 = new Put(toBytes(key3));
+ putKey3Column2Value1.add(toBytes(family), toBytes(column2), timeStamp10, toBytes(value1));
+
+ putKey3Column2Value2 = new Put(toBytes(key3));
+ putKey3Column2Value2.add(toBytes(family), toBytes(column2), timeStamp11, toBytes(value2));
+
+ tryPut(hTable, putKey1Column1Value1);
+ tryPut(hTable, putKey1Column1Value2);
+ tryPut(hTable, putKey1Column2Value1);
+ tryPut(hTable, putKey1Column2Value2);
+ tryPut(hTable, putKey2Column1Value1);
+ tryPut(hTable, putKey2Column1Value2);
+ tryPut(hTable, putKey2Column2Value1);
+ tryPut(hTable, putKey2Column2Value2);
+ tryPut(hTable, putKey3Column1Value1);
+ tryPut(hTable, putKey3Column1Value2);
+ tryPut(hTable, putKey3Column2Value1);
+ tryPut(hTable, putKey3Column2Value2);
+
+ // scan key1
+ scan = new Scan();
+ scan.setStartRow(toBytes(key1));
+ scan.setStopRow("scanKey0x".getBytes());
+ scan.addFamily(family.getBytes());
+ scan.setColumnFamilyTimeRange(toBytes(family), minTimeStamp, timeStamp3);
+ scan.setReversed(true);
+ scan.setMaxVersions(10);
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(3, res_count);
+
+ // scan key1 + key2
+ scan = new Scan();
+ scan.setStartRow(toBytes(key2));
+ scan.setStopRow("scanKey0x".getBytes());
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp2, timeStamp7);
+ scan.setReversed(true);
+ scan.setMaxVersions(10);
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow()))
+ || key2.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(5, res_count);
+
+ // scan key2
+ scan = new Scan();
+ scan.setStartRow(toBytes(key2));
+ scan.setStopRow(toBytes(key1));
+ scan.addFamily(toBytes(family));
+ // set invalid timeRange
+ scan.setTimeRange(minTimeStamp, maxTimeStamp);
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp4, timeStamp6);
+ scan.setReversed(true);
+ scan.setMaxVersions(10);
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key2.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(2, res_count);
+
+ // scan all
+ scan = new Scan();
+ scan.setStartRow(toBytes(key3));
+ scan.setStopRow("scanKey0x".getBytes());
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp2, timeStamp7);
+ scan.setReversed(true);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ Assert.assertTrue(key1.equals(Bytes.toString(kv.getRow()))
+ || key2.equals(Bytes.toString(kv.getRow())));
+ ++res_count;
+ }
+ }
+ Assert.assertEquals(5, res_count);
+
+ scan = new Scan();
+ scan.setStartRow(toBytes(key3));
+ scan.setStopRow("scanKey0x".getBytes());
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp3, timeStamp9);
+ scan.setReversed(true);
+ scan.setMaxVersions();
+ scanner = hTable.getScanner(scan);
+ res_count = 0;
+ boolean foundKey3 = false;
+ for (Result result : scanner) {
+ for (KeyValue kv : result.raw()) {
+ if (!foundKey3) {
+ if (key3.equals(Bytes.toString(kv.getRow()))) {
+ foundKey3 = true;
+ }
+ }
+ ++res_count;
+ }
+ }
+ Assert.assertTrue(foundKey3);
+ Assert.assertEquals(6, res_count);
+
+ scan = new Scan();
+ scan.setStartRow(toBytes(key3));
+ scan.setStopRow("scanKey0x".getBytes());
+ scan.addFamily(toBytes(family));
+ scan.setColumnFamilyTimeRange(toBytes(family), timeStamp3, timeStamp9);
+ scan.setColumnFamilyTimeRange(toBytes("mockFamily"), timeStamp3, timeStamp9);
+ scan.setReversed(true);
+ scan.setMaxVersions();
+ final Scan errorScan = scan;
+ Assert.assertThrows(IOException.class, () -> {
+ hTable.getScanner(errorScan);
+ });
+
+ hTable.delete(deleteKey1Family);
+ hTable.delete(deleteKey2Family);
+ hTable.delete(deleteKey3Family);
+
}
@Test
@@ -2563,7 +4183,6 @@ public void testPartitionScan() throws Exception {
String column2 = "column2";
String value1 = "value1";
String value2 = "value2";
- String value3 = "value3";
String family = "partitionFamily1";
// delete previous data
@@ -2578,12 +4197,6 @@ public void testPartitionScan() throws Exception {
Delete deleteZKey2Family = new Delete(toBytes(zKey2));
deleteZKey2Family.deleteFamily(toBytes(family));
- hTable.delete(deleteKey1Family);
- hTable.delete(deleteKey2Family);
- hTable.delete(deleteKey3Family);
- hTable.delete(deleteZKey1Family);
- hTable.delete(deleteZKey2Family);
-
Put putKey1Column1Value1 = new Put(toBytes(key1));
putKey1Column1Value1.add(toBytes(family), toBytes(column1), toBytes(value1));
@@ -2700,7 +4313,7 @@ public void testPartitionScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 7);
+ Assert.assertEquals(7, res_count);
scanner.close();
// scan with prefixFilter
@@ -2720,7 +4333,7 @@ public void testPartitionScan() throws Exception {
res_count += 1;
}
}
- Assert.assertEquals(res_count, 2);
+ Assert.assertEquals(2, res_count);
scanner.close();
// scan with singleColumnValueFilter
@@ -2851,9 +4464,6 @@ public void testCheckAndPut() throws IOException, InterruptedException {
String column = "checkAndPut";
String value = "value";
String family = "family1";
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
Get get = new Get(key.getBytes());
get.setMaxVersions(Integer.MAX_VALUE);
get.addColumn(family.getBytes(), column.getBytes());
@@ -2903,15 +4513,12 @@ public void testCheckAndDelete() throws IOException {
String column2 = "checkAndDeleteColumn2";
String value = "value";
String family = "family1";
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
Put put = new Put(key.getBytes());
put.add(family.getBytes(), column.getBytes(), value.getBytes());
hTable.put(put);
// check delete column
- delete = new Delete(key.getBytes());
+ Delete delete = new Delete(key.getBytes());
delete.deleteColumn(family.getBytes(), column.getBytes());
boolean ret = hTable.checkAndDelete(key.getBytes(), family.getBytes(), column.getBytes(),
value.getBytes(), delete);
@@ -3001,9 +4608,6 @@ public void testCheckAndMutate() throws IOException {
String value1 = "value1";
String value2 = "value2";
String family = "family1";
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
long t = System.currentTimeMillis();
// put
@@ -3143,9 +4747,6 @@ public void testCheckAndMutate() throws IOException {
public void testAppend() throws IOException {
String column = "appendColumn";
String key = "appendKey";
- Delete delete = new Delete(key.getBytes());
- delete.deleteColumns("family1".getBytes(), column.getBytes());
- hTable.delete(delete);
// append an absent column is not supported yet
// Append append = new Append(key.getBytes());
@@ -3172,9 +4773,6 @@ public void testAppend() throws IOException {
public void testIncrement() throws IOException {
String column = "incrementColumn";
String key = "incrementKey";
- Delete delete = new Delete(key.getBytes());
- delete.deleteColumns("family1".getBytes(), column.getBytes());
- hTable.delete(delete);
// increment an absent column is not supported yet
// Increment increment = new Increment(key.getBytes());
@@ -3220,9 +4818,6 @@ public void testIncrement() throws IOException {
public void testExist() throws IOException {
String column = "existColumn";
String key = "existKey";
- Delete delete = new Delete(key.getBytes());
- delete.deleteColumns("family1".getBytes(), column.getBytes());
- hTable.delete(delete);
Get get = new Get(key.getBytes());
get.addFamily("family1".getBytes());
@@ -3246,8 +4841,6 @@ public void testExist() throws IOException {
get.setTimeStamp(timestamp + 1);
Assert.assertFalse(hTable.exists(get));
-
- hTable.delete(delete);
}
@Ignore
@@ -3257,7 +4850,6 @@ public void testMutateRow() throws IOException {
String column2 = "mutationRowColumn2";
String key = "mutationRowKey";
String family1 = "family1";
- String family2 = "family2";
String value = "value";
Delete deleteFamily = new Delete(key.getBytes());
@@ -3337,9 +4929,6 @@ public void testQualifyNull() throws Exception {
String value = "value";
String value1 = "value1";
String family = "family1";
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
Put put = new Put(key.getBytes());
put.add(family.getBytes(), null, value.getBytes());
hTable.put(put);
@@ -3427,6 +5016,8 @@ public void testFamilyBlank() throws Exception {
fail();
} catch (IllegalArgumentException e) {
Assert.assertTrue(e.getMessage().contains("family is blank"));
+ } catch (NoSuchColumnFamilyException e) {
+ Assert.assertTrue(e.getMessage().contains("does not exist"));
}
Put put = new Put(key.getBytes());
put.add(null, null, value.getBytes());
@@ -3464,9 +5055,6 @@ public void testScannerMultiVersion() throws Exception {
String column = "column";
String value1 = "value1";
String family = "family1";
- Delete delete = new Delete(key.getBytes());
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
Put put = new Put(key.getBytes());
put.add(family.getBytes(), Bytes.toBytes(column), value.getBytes());
hTable.put(put);
@@ -3737,9 +5325,6 @@ public static byte[] toByteArray(long value) {
public void testIncrementConcurrency() throws Exception {
String column = "incrementColumn";
String key = "incrementKey";
- Delete delete = new Delete(key.getBytes());
- delete.deleteColumns("family1".getBytes(), column.getBytes());
- hTable.delete(delete);
for (int i = 0; i < 100; i++) {
Increment increment = new Increment(key.getBytes());
@@ -3785,16 +5370,12 @@ public void testFilterSpecialValue() throws IOException {
byte[] columnBytes = specialBytes;
byte[] valueBytes = specialBytes;
- Delete delete = new Delete(keyBytes);
- delete.deleteFamily(family.getBytes());
- hTable.delete(delete);
-
Put put = new Put(keyBytes);
put.add(family.getBytes(), columnBytes, valueBytes);
hTable.put(put);
// check delete column
- delete = new Delete(keyBytes);
+ Delete delete = new Delete(keyBytes);
delete.deleteColumn(family.getBytes(), columnBytes);
boolean ret = hTable.checkAndDelete(keyBytes, family.getBytes(), columnBytes, valueBytes,
delete);
@@ -3830,6 +5411,5 @@ public void testFilterSpecialValue() throws IOException {
result = hTable.get(get);
Assert.assertEquals(1, result.raw().length);
Assert.assertArrayEquals(keyBytes, result.getRow());
-
}
}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/LoggerTest.java b/src/test/java/com/alipay/oceanbase/hbase/LoggerTest.java
index d1909ea0..0ab0617b 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/LoggerTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/LoggerTest.java
@@ -17,12 +17,13 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.Increment;
import org.apache.hadoop.hbase.client.Scan;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.support.membermodification.MemberModifier;
@@ -42,7 +43,7 @@
public class LoggerTest {
HTableInterface hTableMock;
- @Before
+ @BeforeClass
public void setup() throws IOException {
Configuration c = ObHTableTestUtil.newConfiguration();
c.set("rs.list.acquire.read.timeout", "10000");
diff --git a/src/test/java/com/alipay/oceanbase/hbase/NativeHBaseTest.java b/src/test/java/com/alipay/oceanbase/hbase/NativeHBaseTest.java
new file mode 100644
index 00000000..545d95b9
--- /dev/null
+++ b/src/test/java/com/alipay/oceanbase/hbase/NativeHBaseTest.java
@@ -0,0 +1,46 @@
+package com.alipay.oceanbase.hbase;
+
+import com.alipay.oceanbase.hbase.util.NativeHBaseUtil;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.*;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.IOException;
+
+public class NativeHBaseTest extends HTableTestBase {
+
+ static Admin admin;
+ static TableName tableName1 = TableName.valueOf("test");
+ static TableName tableName2 = TableName.valueOf("test_multi_cf");
+
+ static {
+ try {
+ admin = NativeHBaseUtil.getAdmin();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @BeforeClass
+ public static void setup() throws IOException {
+ hTable = NativeHBaseUtil.getTable(tableName1);
+ multiCfHTable = NativeHBaseUtil.getTable(tableName2);
+ }
+
+ @Before
+ public void cleanData() throws IOException {
+ admin.disableTable(tableName1);
+ admin.disableTable(tableName2);
+ admin.truncateTable(tableName1, true);
+ admin.truncateTable(tableName2, true);
+ }
+
+ @AfterClass
+ public static void finish() throws IOException {
+ hTable.close();
+ multiCfHTable.close();
+ }
+
+}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHConnectionTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHConnectionTest.java
index a4a78a61..1fa79204 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHConnectionTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHConnectionTest.java
@@ -17,25 +17,28 @@
package com.alipay.oceanbase.hbase;
-import com.alipay.oceanbase.hbase.exception.FeatureNotSupportedException;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Threads;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.*;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
+import static com.alipay.oceanbase.hbase.constants.OHConstants.SOCKET_TIMEOUT;
+import static org.apache.hadoop.hbase.ipc.RpcClient.SOCKET_TIMEOUT_CONNECT;
import static org.apache.hadoop.hbase.util.Bytes.toBytes;
+import static org.junit.Assert.*;
public class OHConnectionTest {
- protected Table hTable;
- protected Connection connection;
+ protected static Table hTable;
+ protected Connection connection;
@Test
public void testConnectionBySet() throws Exception {
@@ -43,10 +46,15 @@ public void testConnectionBySet() throws Exception {
c.set(ClusterConnection.HBASE_CLIENT_CONNECTION_IMPL,
"com.alipay.oceanbase.hbase.util.OHConnectionImpl");
c.set("rs.list.acquire.read.timeout", "10000");
+ // test set rpc connection timeout, the first one is the latest version
+ c.set(SOCKET_TIMEOUT_CONNECT, "15000");
+ // the second one is the deprecated version
+ c.set(SOCKET_TIMEOUT, "12000");
connection = ConnectionFactory.createConnection(c);
TableName tableName = TableName.valueOf("test");
hTable = connection.getTable(tableName);
testBasic();
+ hTable.close();
}
@Test
@@ -54,10 +62,45 @@ public void testConnectionByXml() throws Exception {
Configuration c = ObHTableTestUtil.newConfiguration();
c.set("rs.list.acquire.read.timeout", "10000");
+ // can set rpc connection timeout in xml
connection = ConnectionFactory.createConnection(c);
TableName tableName = TableName.valueOf("test");
hTable = connection.getTable(tableName);
testBasic();
+ hTable.close();
+ }
+
+ @Test
+ public void testRefreshTableEntry() throws Exception {
+ hTable = ObHTableTestUtil.newOHTableClient("n1:test");
+ ((OHTableClient) hTable).init();
+ ((OHTableClient) hTable).refreshTableEntry("family1", false);
+ ((OHTableClient) hTable).refreshTableEntry("family1", true);
+ }
+
+ @Test
+ public void testNew() throws Exception {
+ OHTableClient hTable2 = ObHTableTestUtil.newOHTableClient("n1:test");
+ hTable2.init();
+ hTable2.getConfiguration().set("rs.list.acquire.read.timeout", "10000");
+
+ assertTrue(hTable2.isAutoFlush());
+ hTable2.setAutoFlush(false);
+ assertFalse(hTable2.isAutoFlush());
+ hTable2.setAutoFlush(true, true);
+ assertTrue(hTable2.isAutoFlush());
+ hTable2.setWriteBufferSize(10000000L);
+ assertEquals(10000000L, hTable2.getWriteBufferSize());
+ assertEquals("n1:test", hTable2.getTableNameString());
+ assertEquals("n1:test", new String(hTable2.getTableName()));
+ hTable2.flushCommits();
+ hTable2.close();
+ assertTrue(true);
+ }
+
+ @After
+ public void after() throws IOException {
+ hTable.close();
}
private void testBasic() throws Exception {
@@ -194,26 +237,31 @@ PRIMARY KEY (`K`, `Q`, `T`)
public void testBufferedMutatorWithFlush() throws Exception {
Configuration conf = ObHTableTestUtil.newConfiguration();
conf.set("rs.list.acquire.read.timeout", "10000");
- BufferedMutator putBufferMutator = null;
- BufferedMutator delBufferedMutator = null;
+ conf.set(SOCKET_TIMEOUT_CONNECT, "15000");
+ BufferedMutator bufferMutator = null;
+ String key = "putKey";
+ String column1 = "putColumn1";
+ String value = "value333444";
+ String family = "family_group";
try {
TableName tableName = TableName.valueOf("test");
connection = ConnectionFactory.createConnection(conf);
hTable = connection.getTable(tableName);
+
+ Delete delete= new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
+ hTable.delete(delete);
+
// use defualt params
- putBufferMutator = connection.getBufferedMutator(tableName);
- delBufferedMutator = connection.getBufferedMutator(tableName);
+ bufferMutator = connection.getBufferedMutator(tableName);
+
- String key = "putKey";
- String column1 = "putColumn1";
- String value = "value333444";
long timestamp = System.currentTimeMillis();
// only support Put and Delete
- // for other type of operations, BufferedMutator will not set its type for them
Append append = new Append(Bytes.toBytes(key));
append.add("family_group".getBytes(), column1.getBytes(), toBytes("_suffix"));
- final BufferedMutator apMut = putBufferMutator;
+ final BufferedMutator apMut = bufferMutator;
Assert.assertThrows(IllegalArgumentException.class, () -> {
apMut.mutate(append);
});
@@ -221,37 +269,52 @@ public void testBufferedMutatorWithFlush() throws Exception {
List mutations = new ArrayList<>();
// test Put
Put put1 = new Put(Bytes.toBytes(key));
- put1.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1), timestamp, Bytes.toBytes(value));
+ put1.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1), timestamp, Bytes.toBytes(value));
mutations.add(put1);
Put put2 = new Put(Bytes.toBytes(key));
- put2.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1 + "1"), timestamp, Bytes.toBytes(value + "4"));
+ put2.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "1"), timestamp, Bytes.toBytes(value + "4"));
mutations.add(put2);
// test add Mutations with List
- putBufferMutator.mutate(mutations);
- putBufferMutator.flush();
+ bufferMutator.mutate(mutations);
+ bufferMutator.flush();
Get get = new Get(toBytes(key));
Result r = hTable.get(get);
Assert.assertEquals(2, r.raw().length);
- Delete del = new Delete(Bytes.toBytes(key));
- final BufferedMutator noCfMut = putBufferMutator;
- // test mutation without setting family
- Assert.assertThrows(FeatureNotSupportedException.class, () -> {
- noCfMut.mutate(del);
- });
- del.deleteFamily(Bytes.toBytes("family_group"));
- // test reuse different type bufferedMutator
- final BufferedMutator difTypeMut = putBufferMutator;
+ Put put3 = new Put(Bytes.toBytes(key));
+ final BufferedMutator noCfMut = bufferMutator;
+ // test Put without setting family
Assert.assertThrows(IllegalArgumentException.class, () -> {
- difTypeMut.mutate(del);
+ noCfMut.mutate(put3);
});
+ put3.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "2"), timestamp, Bytes.toBytes(value));
// test add Mutation directly
- delBufferedMutator.mutate(del);
- delBufferedMutator.flush();
+ bufferMutator.mutate(put3);
+ bufferMutator.flush();
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
+ // test Delete
+ Delete del = new Delete(toBytes(key));
+ del.deleteFamily(toBytes(family));
+ bufferMutator.mutate(del);
+ bufferMutator.flush();
r = hTable.get(get);
Assert.assertEquals(0, r.raw().length);
+
+ // test hybrid mutations
+ mutations.clear();
+ mutations.add(put1);
+ mutations.add(put2);
+ mutations.add(del);
+ mutations.add(put3);
+ bufferMutator.mutate(mutations);
+ bufferMutator.flush();
+
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
} catch (Exception ex) {
if (ex instanceof RetriesExhaustedWithDetailsException) {
((RetriesExhaustedWithDetailsException) ex).getCauses().get(0).printStackTrace();
@@ -260,17 +323,14 @@ public void testBufferedMutatorWithFlush() throws Exception {
}
Assert.assertTrue(false);
} finally {
- if (putBufferMutator != null ) {
- putBufferMutator.close();
+ if (bufferMutator != null ) {
+ bufferMutator.close();
// test flush after closed
- putBufferMutator.flush();
- }
- if (delBufferedMutator != null) {
- delBufferedMutator.close();
+ bufferMutator.flush();
// test add mutations after closed
- Delete delete = new Delete(Bytes.toBytes("putKey"));
- delete.deleteFamily(Bytes.toBytes("family_group"));
- final BufferedMutator closedMutator = delBufferedMutator;
+ Delete delete = new Delete(Bytes.toBytes(key));
+ delete.deleteFamily(Bytes.toBytes(family));
+ final BufferedMutator closedMutator = bufferMutator;
Assert.assertThrows(IllegalStateException.class, () -> {
closedMutator.mutate(delete);
});
@@ -279,6 +339,7 @@ public void testBufferedMutatorWithFlush() throws Exception {
}
/*
+ USE n1;
CREATE TABLEGROUP `n1:test` SHARDING = 'ADAPTIVE';
CREATE TABLE `n1:test$family_group` (
`K` varbinary(1024) NOT NULL,
@@ -292,27 +353,32 @@ PRIMARY KEY (`K`, `Q`, `T`)
public void testBufferedMutatorUseNameSpaceWithFlush() throws Exception {
Configuration conf = ObHTableTestUtil.newConfiguration();
conf.set("rs.list.acquire.read.timeout", "10000");
- BufferedMutator putBufferMutator = null;
- BufferedMutator delBufferedMutator = null;
+ conf.set(SOCKET_TIMEOUT_CONNECT, "15000");
+ BufferedMutator bufferMutator = null;
+ String key = "putKey";
+ String column1 = "putColumn1";
+ String value = "value333444";
+ String family = "family_group";
try {
// use n1 database
- TableName tableName = TableName.valueOf("n1:test");
+ TableName tableName = TableName.valueOf("n1","test");
connection = ConnectionFactory.createConnection(conf);
hTable = connection.getTable(tableName);
+ Assert.assertEquals("n1:test", Bytes.toString(((OHTable) hTable).getTableName()));
+
+ Delete delete= new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
+ hTable.delete(delete);
+
// use defualt params
- putBufferMutator = connection.getBufferedMutator(tableName);
- delBufferedMutator = connection.getBufferedMutator(tableName);
+ bufferMutator = connection.getBufferedMutator(tableName);
- String key = "putKey";
- String column1 = "putColumn1";
- String value = "value333444";
long timestamp = System.currentTimeMillis();
// only support Put and Delete
- // for other type of operations, BufferedMutator will not set its type for them
Append append = new Append(Bytes.toBytes(key));
append.add("family_group".getBytes(), column1.getBytes(), toBytes("_suffix"));
- final BufferedMutator apMut = putBufferMutator;
+ final BufferedMutator apMut = bufferMutator;
Assert.assertThrows(IllegalArgumentException.class, () -> {
apMut.mutate(append);
});
@@ -320,37 +386,52 @@ public void testBufferedMutatorUseNameSpaceWithFlush() throws Exception {
List mutations = new ArrayList<>();
// test Put
Put put1 = new Put(Bytes.toBytes(key));
- put1.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1), timestamp, Bytes.toBytes(value));
+ put1.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1), timestamp, Bytes.toBytes(value));
mutations.add(put1);
Put put2 = new Put(Bytes.toBytes(key));
- put2.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1 + "1"), timestamp, Bytes.toBytes(value + "4"));
+ put2.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "1"), timestamp, Bytes.toBytes(value + "4"));
mutations.add(put2);
// test add Mutations with List
- putBufferMutator.mutate(mutations);
- putBufferMutator.flush();
+ bufferMutator.mutate(mutations);
+ bufferMutator.flush();
Get get = new Get(toBytes(key));
Result r = hTable.get(get);
Assert.assertEquals(2, r.raw().length);
- Delete del = new Delete(Bytes.toBytes(key));
- final BufferedMutator noCfMut = putBufferMutator;
- // test mutation without setting family
- Assert.assertThrows(FeatureNotSupportedException.class, () -> {
- noCfMut.mutate(del);
- });
- del.deleteFamily(Bytes.toBytes("family_group"));
- final BufferedMutator difTypeMut = putBufferMutator;
- // test reuse different type bufferedMutator
+ Put put3 = new Put(Bytes.toBytes(key));
+ final BufferedMutator noCfMut = bufferMutator;
+ // test Put without setting family
Assert.assertThrows(IllegalArgumentException.class, () -> {
- difTypeMut.mutate(del);
+ noCfMut.mutate(put3);
});
+ put3.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "2"), timestamp, Bytes.toBytes(value));
// test add Mutation directly
- delBufferedMutator.mutate(del);
- delBufferedMutator.flush();
+ bufferMutator.mutate(put3);
+ bufferMutator.flush();
+ r = hTable.get(get);
+ Assert.assertEquals(3, r.raw().length);
+
+ // test Delete
+ Delete del = new Delete(toBytes(key));
+ del.deleteFamily(toBytes(family));
+ bufferMutator.mutate(del);
+ bufferMutator.flush();
r = hTable.get(get);
Assert.assertEquals(0, r.raw().length);
+
+ // test hybrid mutations
+ mutations.clear();
+ mutations.add(put1);
+ mutations.add(put2);
+ mutations.add(del);
+ mutations.add(put3);
+ bufferMutator.mutate(mutations);
+ bufferMutator.flush();
+
+ r = hTable.get(get);
+ Assert.assertEquals(1, r.raw().length);
} catch (Exception ex) {
if (ex instanceof RetriesExhaustedWithDetailsException) {
((RetriesExhaustedWithDetailsException) ex).getCauses().get(0).printStackTrace();
@@ -359,17 +440,14 @@ public void testBufferedMutatorUseNameSpaceWithFlush() throws Exception {
}
Assert.assertTrue(false);
} finally {
- if (putBufferMutator != null ) {
- putBufferMutator.close();
+ if (bufferMutator != null ) {
+ bufferMutator.close();
// test flush after closed
- putBufferMutator.flush();
- }
- if (delBufferedMutator != null) {
- delBufferedMutator.close();
+ bufferMutator.flush();
// test add mutations after closed
- Delete delete = new Delete(Bytes.toBytes("putKey"));
- delete.deleteFamily(Bytes.toBytes("family_group"));
- final BufferedMutator closedMutator = delBufferedMutator;
+ Delete delete = new Delete(Bytes.toBytes(key));
+ delete.deleteFamily(Bytes.toBytes(family));
+ final BufferedMutator closedMutator = bufferMutator;
Assert.assertThrows(IllegalStateException.class, () -> {
closedMutator.mutate(delete);
});
@@ -391,35 +469,52 @@ PRIMARY KEY (`K`, `Q`, `T`)
public void testBufferedMutatorWithAutoFlush() throws Exception {
Configuration conf = ObHTableTestUtil.newConfiguration();
conf.set("rs.list.acquire.read.timeout", "10000");
- BufferedMutator putBufferMutator = null;
+ BufferedMutator bufferMutator = null;
BufferedMutatorParams params = null;
long bufferSize = 45000L;
int count = 0;
+ String key = "putKey";
+ String column1 = "putColumn1";
+ String value = "value333444";
+ long timestamp = System.currentTimeMillis();
+ String family = "family_group";
try {
TableName tableName = TableName.valueOf("test");
connection = ConnectionFactory.createConnection(conf);
hTable = connection.getTable(tableName);
+
+ Delete delete= new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
+ hTable.delete(delete);
+
// set params
params = new BufferedMutatorParams(tableName);
params.writeBufferSize(bufferSize);
- putBufferMutator = connection.getBufferedMutator(params);
-
- String key = "putKey";
- String column1 = "putColumn1";
- String value = "value333444";
- long timestamp = System.currentTimeMillis();
+ bufferMutator = connection.getBufferedMutator(params);
List mutations = new ArrayList<>();
for (int i = 0; i < 50; ++i) {
mutations.clear();
for (int j = 0; j < 4; ++j) {
Put put = new Put(Bytes.toBytes(key));
- put.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1 + "_" + i + "_" + j),
+ put.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "_" + i + "_" + j),
timestamp, Bytes.toBytes(value + "_" + i + "_" + j));
mutations.add(put);
}
- putBufferMutator.mutate(mutations);
+ if (i % 10 == 0) { // 0, 10, 20, 30, 40
+ for(int j = 0; j < 4; ++j) {
+ Delete del = new Delete(Bytes.toBytes(key));
+ del.addColumns(toBytes(family), toBytes(column1 + "_" + i + "_" + j));
+ mutations.add(del);
+ }
+ }
+ bufferMutator.mutate(mutations);
}
+ Get get = new Get(toBytes(key));
+ get.addFamily(toBytes(family));
+ Result r = hTable.get(get);
+ count = r.raw().length;
+ Assert.assertTrue(count > 0);
} catch (Exception ex) {
if (ex instanceof RetriesExhaustedWithDetailsException) {
((RetriesExhaustedWithDetailsException) ex).getCauses().get(0).printStackTrace();
@@ -428,27 +523,26 @@ public void testBufferedMutatorWithAutoFlush() throws Exception {
}
Assert.assertTrue(false);
} finally {
- if (putBufferMutator != null) {
- putBufferMutator.close();
- Get get = new Get(toBytes("putKey"));
+ if (bufferMutator != null) {
+ bufferMutator.close();
+ Get get = new Get(toBytes(key));
+ get.addFamily(toBytes(family));
Result r = hTable.get(get);
- for (KeyValue keyValue : r.raw()) {
- ++count;
- }
- Assert.assertEquals(200, count);
- Delete delete = new Delete(toBytes("putKey"));
- delete.deleteFamily(toBytes("family_group"));
+ count = r.raw().length;
+ Assert.assertEquals(180, count);
+ Delete delete = new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
hTable.delete(delete);
r = hTable.get(get);
Assert.assertEquals(0, r.raw().length);
// test add mutations after closed
- final BufferedMutator closedMutator = putBufferMutator;
+ final BufferedMutator closedMutator = bufferMutator;
Assert.assertThrows(IllegalStateException.class, () -> {
closedMutator.mutate(delete);
});
// test flush after closed
- putBufferMutator.flush();
+ bufferMutator.flush();
}
if (params != null) {
@@ -477,10 +571,20 @@ public void testBufferedMutatorWithUserPool() throws Exception {
BufferedMutatorParams params = null;
long bufferSize = 45000L;
int count = 0;
+ String key = "putKey";
+ String column1 = "putColumn1";
+ String value = "value333444";
+ long timestamp = System.currentTimeMillis();
+ String family = "family_group";
try {
TableName tableName = TableName.valueOf("test");
connection = ConnectionFactory.createConnection(conf);
hTable = connection.getTable(tableName);
+
+ Delete delete= new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
+ hTable.delete(delete);
+
// set params
params = new BufferedMutatorParams(tableName);
params.writeBufferSize(bufferSize);
@@ -493,22 +597,29 @@ public void testBufferedMutatorWithUserPool() throws Exception {
ohBufferMutator = connection.getBufferedMutator(params);
- String key = "putKey";
- String column1 = "putColumn1";
- String value = "value333444";
- long timestamp = System.currentTimeMillis();
-
List mutations = new ArrayList<>();
for (int i = 0; i < 50; ++i) {
mutations.clear();
for (int j = 0; j < 4; ++j) {
Put put = new Put(Bytes.toBytes(key));
- put.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(column1 + "_" + i + "_" + j),
+ put.addColumn(Bytes.toBytes(family), Bytes.toBytes(column1 + "_" + i + "_" + j),
timestamp, Bytes.toBytes(value + "_" + i + "_" + j));
mutations.add(put);
}
+ if (i % 10 == 0) { // 0, 10, 20, 30, 40
+ for(int j = 0; j < 4; ++j) {
+ Delete del = new Delete(Bytes.toBytes(key));
+ del.addColumns(toBytes(family), toBytes(column1 + "_" + i + "_" + j));
+ mutations.add(del);
+ }
+ }
ohBufferMutator.mutate(mutations);
}
+ Get get = new Get(toBytes(key));
+ get.addFamily(toBytes(family));
+ Result r = hTable.get(get);
+ count = r.raw().length;
+ Assert.assertTrue(count > 0);
} catch (Exception ex) {
if (ex instanceof RetriesExhaustedWithDetailsException) {
((RetriesExhaustedWithDetailsException) ex).getCauses().get(0).printStackTrace();
@@ -519,14 +630,13 @@ public void testBufferedMutatorWithUserPool() throws Exception {
} finally {
if (ohBufferMutator != null) {
ohBufferMutator.close();
- Get get = new Get(toBytes("putKey"));
+ Get get = new Get(toBytes(key));
+ get.addFamily(toBytes(family));
Result r = hTable.get(get);
- for (KeyValue keyValue : r.raw()) {
- ++count;
- }
- Assert.assertEquals(200, count);
- Delete delete = new Delete(toBytes("putKey"));
- delete.deleteFamily(toBytes("family_group"));
+ count = r.raw().length;
+ Assert.assertEquals(180, count);
+ Delete delete = new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
hTable.delete(delete);
r = hTable.get(get);
@@ -566,10 +676,20 @@ public void testBufferedMutatorConcurrent() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
long bufferSize = 45000L;
int count = 0;
+ String key = "putKey";
+ String column1 = "putColumn1";
+ String value = "value333444";
+ long timestamp = System.currentTimeMillis();
+ String family = "family_group";
try {
TableName tableName = TableName.valueOf("test");
connection = ConnectionFactory.createConnection(conf);
hTable = connection.getTable(tableName);
+
+ Delete delete= new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
+ hTable.delete(delete);
+
// set params
params = new BufferedMutatorParams(tableName);
params.writeBufferSize(bufferSize);
@@ -582,24 +702,19 @@ public void testBufferedMutatorConcurrent() throws Exception {
ohBufferMutator = connection.getBufferedMutator(params);
- String key = "putKey";
- String column1 = "putColumn1";
- String value = "value333444";
- long timestamp = System.currentTimeMillis();
-
+ // BufferedMutator is not concurrently safe
for (int i = 0; i < 50; ++i) {
final int taskId = i;
final BufferedMutator thrBufferMutator = ohBufferMutator;
executorService.submit(() -> {
List mutations = new ArrayList<>();
for (int j = 0; j < 4; ++j) {
- String thrKey = key;
String thrColumn = column1 + "_" + taskId + "_" + j;
String thrValue = value + "_" + taskId + "_" + j;
long thrTimestamp = timestamp;
- Put put = new Put(Bytes.toBytes(thrKey));
- put.addColumn(Bytes.toBytes("family_group"), Bytes.toBytes(thrColumn),
+ Put put = new Put(Bytes.toBytes(key));
+ put.addColumn(Bytes.toBytes(family), Bytes.toBytes(thrColumn),
thrTimestamp, Bytes.toBytes(thrValue));
mutations.add(put);
}
@@ -634,14 +749,13 @@ public void testBufferedMutatorConcurrent() throws Exception {
}
if (ohBufferMutator != null) {
ohBufferMutator.close();
- Get get = new Get(toBytes("putKey"));
+ Get get = new Get(toBytes(key));
+ get.addFamily(toBytes(family));
Result r = hTable.get(get);
- for (KeyValue keyValue : r.raw()) {
- ++count;
- }
+ count = r.raw().length;
Assert.assertEquals(200, count);
- Delete delete = new Delete(toBytes("putKey"));
- delete.deleteFamily(toBytes("family_group"));
+ Delete delete = new Delete(toBytes(key));
+ delete.deleteFamily(toBytes(family));
hTable.delete(delete);
r = hTable.get(get);
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableAdminInterfaceTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableAdminInterfaceTest.java
index 380125f1..6d53616b 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTableAdminInterfaceTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableAdminInterfaceTest.java
@@ -17,6 +17,7 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Pair;
import org.junit.Assert;
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTest.java
index 044f45d4..01c4057f 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTest.java
@@ -17,24 +17,33 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import org.junit.*;
-import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class OHTableClientTest extends HTableTestBase {
- @Before
- public void before() throws Exception {
+ @BeforeClass
+ public static void before() throws Exception {
hTable = ObHTableTestUtil.newOHTableClient("test");
+ // hTable = ObHTableTestUtil.newOHTableClient("n1:test");
((OHTableClient) hTable).init();
+ multiCfHTable = ObHTableTestUtil.newOHTableClient("test_multi_cf");
+ ((OHTableClient) multiCfHTable).init();
+ List tableGroups = new LinkedList<>();
+ tableGroups.add("test");
+ tableGroups.add("test_multi_cf");
+ ObHTableTestUtil.prepareClean(tableGroups);
}
- @After
- public void finish() throws IOException {
- hTable.close();
+ @Before
+ public void prepareCase() {
+ ObHTableTestUtil.cleanData();
}
@Test
@@ -46,6 +55,7 @@ public void testRefreshTableEntry() throws Exception {
@Test
public void testNew() throws Exception {
OHTableClient hTable2 = ObHTableTestUtil.newOHTableClient("test");
+ // OHTableClient hTable2 = ObHTableTestUtil.newOHTableClient("n1:test");
hTable2.init();
hTable2.getConfiguration().set("rs.list.acquire.read.timeout", "10000");
@@ -57,14 +67,18 @@ public void testNew() throws Exception {
hTable2.setWriteBufferSize(10000000L);
assertEquals(10000000L, hTable2.getWriteBufferSize());
assertEquals("test", hTable2.getTableNameString());
+ // assertEquals("n1:test", hTable2.getTableNameString());
assertEquals("test", new String(hTable2.getTableName()));
+ // assertEquals("n1:test", new String(hTable2.getTableName()));
hTable2.flushCommits();
hTable2.close();
assertTrue(true);
}
- @After
- public void after() throws IOException {
+ @AfterClass
+ public static void finish() throws Exception {
hTable.close();
+ multiCfHTable.close();
+ ObHTableTestUtil.closeConn();
}
}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTestLoadTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTestLoadTest.java
index 2c636436..ed9df2fa 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTestLoadTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableClientTestLoadTest.java
@@ -17,24 +17,36 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import com.alipay.oceanbase.rpc.exception.ObTableNotExistException;
import org.apache.hadoop.hbase.client.Delete;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
import static com.alipay.oceanbase.hbase.constants.OHConstants.HBASE_HTABLE_TEST_LOAD_ENABLE;
import static com.alipay.oceanbase.hbase.constants.OHConstants.HBASE_HTABLE_TEST_LOAD_SUFFIX;
public class OHTableClientTestLoadTest extends HTableTestBase {
- @Before
- public void before() throws Exception {
+ @BeforeClass
+ public static void before() throws Exception {
hTable = ObHTableTestUtil.newOHTableClient("test");
((OHTableClient) hTable).init();
hTable.getConfiguration().set(HBASE_HTABLE_TEST_LOAD_ENABLE, "true");
+ multiCfHTable = ObHTableTestUtil.newOHTableClient("test_multi_cf");
+ ((OHTableClient) multiCfHTable).init();
+ multiCfHTable.getConfiguration().set(HBASE_HTABLE_TEST_LOAD_ENABLE, "true");
+ List tableGroups = new LinkedList<>();
+ tableGroups.add("test");
+ tableGroups.add("test_multi_cf");
+ ObHTableTestUtil.prepareClean(tableGroups);
+ }
+
+ @Before
+ public void prepareCase() {
+ ObHTableTestUtil.cleanData();
}
@Test
@@ -53,9 +65,11 @@ public void test_refresh_table_entry() throws Exception {
}
- @After
- public void after() throws IOException {
+ @AfterClass
+ public static void after() throws Exception {
hTable.close();
+ multiCfHTable.close();
+ ObHTableTestUtil.closeConn();
}
@Test
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableMultiColumnFamilyTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableMultiColumnFamilyTest.java
deleted file mode 100644
index 1793bb7f..00000000
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTableMultiColumnFamilyTest.java
+++ /dev/null
@@ -1,639 +0,0 @@
-/*-
- * #%L
- * com.oceanbase:obkv-hbase-client
- * %%
- * Copyright (C) 2022 - 2024 OceanBase Group
- * %%
- * OBKV HBase Client Framework is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- * #L%
- */
-
-package com.alipay.oceanbase.hbase;
-
-import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.client.*;
-import org.apache.hadoop.hbase.filter.PrefixFilter;
-import org.junit.*;
-import org.junit.rules.ExpectedException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.hadoop.hbase.util.Bytes.toBytes;
-import static org.junit.Assert.*;
-
-public class OHTableMultiColumnFamilyTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- protected HTableInterface hTable;
-
- @Before
- public void before() throws Exception {
- hTable = ObHTableTestUtil.newOHTableClient("test_multi_cf");
- ((OHTableClient) hTable).init();
- }
-
- @After
- public void finish() throws IOException {
- hTable.close();
- }
-
- @Test
- public void testMultiColumnFamilyPut() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 30;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
- hTable.flushCommits();
-
- Scan scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- ResultScanner scanner = hTable.getScanner(scan);
- int count = 0;
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- count++;
- }
- assertEquals(count, rows);
- }
-
- @Ignore
- public void testMultiColumnFamilyAppend() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 30;
-
- for (int i = 0; i < rows; ++i) {
- Append append = new Append(toBytes("Key" + i));
- append.add(family1, family1_column1, family1_value);
- append.add(family1, family1_column2, family1_value);
- append.add(family1, family1_column3, family1_value);
- append.add(family2, family2_column1, family2_value);
- append.add(family2, family2_column2, family2_value);
- append.add(family3, family3_column1, family3_value);
- hTable.append(append);
- }
- hTable.flushCommits();
-
- Scan scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- ResultScanner scanner = hTable.getScanner(scan);
- int count = 0;
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- count++;
- }
- assertEquals(count, rows);
- }
-
- @Test
- public void testMultiColumnFamilyReverseScan() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 30;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
-
- Scan scan = new Scan();
- scan.addFamily(family1);
- scan.addFamily(family2);
- scan.setReversed(true);
- ResultScanner scanner2 = hTable.getScanner(scan);
-
- for (Result result : scanner2) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- }
- }
-
- @Test
- public void testMultiColumnFamilyScanWithColumns() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 30;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
-
- Scan scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- scan.addColumn(family1, family1_column1);
- scan.addColumn(family2, family2_column1);
- ResultScanner scanner = hTable.getScanner(scan);
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(2, keyValues.length);
- }
- scanner.close();
- scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- scan.addColumn(family1, family1_column1);
- scan.addColumn(family1, family1_column2);
- scan.addColumn(family1, family1_column3);
- scan.addColumn(family2, family2_column1);
- scan.addColumn(family2, family2_column2);
- scanner = hTable.getScanner(scan);
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(5, keyValues.length);
- }
- scanner.close();
- scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- scan.addFamily(family1);
- scan.addFamily(family2);
-
- scanner = hTable.getScanner(scan);
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(5, keyValues.length);
- }
- scanner.close();
- scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- scan.addFamily(family1);
- scan.addFamily(family3);
-
- scanner = hTable.getScanner(scan);
-
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- // f1c1 f1c2 f1c3 f3c1
- assertEquals(4, keyValues.length);
- }
- scanner.close();
- }
-
- @Test
- public void testMultiColumnFamilyScanWithFilter() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 30;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
-
- PrefixFilter filter = new PrefixFilter(toBytes("Key1"));
- Scan scan = new Scan();
- scan.setStartRow(toBytes("Key"));
- scan.setStopRow(toBytes("Kf"));
- scan.setFilter(filter);
- ResultScanner scanner = hTable.getScanner(scan);
-
- // Key1, Key10, Key11, Key12, Key13, Key14, Key15, Key16, Key17, Key18, Key19
- int count = 0;
- for (Result result : scanner) {
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(6, keyValues.length);
- count++;
- }
- assertEquals(11, count);
- }
-
- @Test
- public void testMultiColumnFamilyGet() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- Map expectedValues = new HashMap<>();
- expectedValues.put(family1_column1, family1_value);
- expectedValues.put(family1_column2, family1_value);
- expectedValues.put(family1_column3, family1_value);
- expectedValues.put(family2_column1, family2_value);
- expectedValues.put(family2_column2, family2_value);
- expectedValues.put(family3_column1, family3_value);
-
- int rows = 3;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
- hTable.flushCommits();
-
- // get with empty family
- // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
- Get get = new Get(toBytes("Key1"));
- Result result = hTable.get(get);
- KeyValue[] keyValues = result.raw();
- long timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(6, keyValues.length);
-
- // f1c1 f2c1 f2c2
- Get get2 = new Get(toBytes("Key1"));
- get2.addColumn(family1, family1_column1);
- get2.addColumn(family2, family2_column1);
- get2.addColumn(family2, family2_column2);
- Result result2 = hTable.get(get2);
- keyValues = result2.raw();
- timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- System.out.println(Arrays.toString(result2.raw()));
- assertEquals(3, keyValues.length);
-
- //f2c1 f2c2
- Get get3 = new Get(toBytes("Key1"));
- get3.addFamily(family1);
- get3.addColumn(family2, family2_column1);
- get3.addColumn(family2, family2_column2);
- Result result3 = hTable.get(get3);
- keyValues = result3.raw();
- timestamp = keyValues[0].getTimestamp();
- for (int i = 1; i < keyValues.length; ++i) {
- assertEquals(timestamp, keyValues[i].getTimestamp());
- byte[] qualifier = keyValues[i].getQualifier();
- byte[] expectedValue = expectedValues.get(qualifier);
- if (expectedValue != null) {
- assertEquals(expectedValue, keyValues[i].getValue());
- }
- }
- assertEquals(5, keyValues.length);
- }
-
- @Test
- public void testMultiColumnFamilyDelete() throws Exception {
- byte[] family1 = "family_with_group1".getBytes();
- byte[] family2 = "family_with_group2".getBytes();
- byte[] family3 = "family_with_group3".getBytes();
-
- byte[] family1_column1 = "family1_column1".getBytes();
- byte[] family1_column2 = "family1_column2".getBytes();
- byte[] family1_column3 = "family1_column3".getBytes();
- byte[] family2_column1 = "family2_column1".getBytes();
- byte[] family2_column2 = "family2_column2".getBytes();
- byte[] family3_column1 = "family3_column1".getBytes();
- byte[] family1_value = "VVV1".getBytes();
- byte[] family2_value = "VVV2".getBytes();
- byte[] family3_value = "VVV3".getBytes();
-
- int rows = 10;
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
-
- // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
- Delete delete = new Delete(toBytes("Key1"));
- delete.deleteColumns(family1, family1_column1);
- delete.deleteColumns(family2, family2_column1);
- hTable.delete(delete);
- // f1c2 f1c3 f2c2 f3c1
- Get get = new Get(toBytes("Key1"));
- Result result = hTable.get(get);
- KeyValue[] keyValues = result.raw();
- assertEquals(4, keyValues.length);
- assertFalse(result.containsColumn(family1, family1_column1));
- assertFalse(result.containsColumn(family2, family2_column1));
-
- assertTrue(result.containsColumn(family1, family1_column2));
- assertArrayEquals(result.getValue(family1, family1_column2), family1_value);
- assertTrue(result.containsColumn(family1, family1_column3));
- assertArrayEquals(result.getValue(family1, family1_column3), family1_value);
- assertTrue(result.containsColumn(family2, family2_column2));
- assertArrayEquals(result.getValue(family2, family2_column2), family2_value);
- assertTrue(result.containsColumn(family3, family3_column1));
- assertArrayEquals(result.getValue(family3, family3_column1), family3_value);
-
- // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
- delete = new Delete(toBytes("Key2"));
- delete.deleteFamily(family1);
- delete.deleteFamily(family2);
- // f3c1
- hTable.delete(delete);
- get = new Get(toBytes("Key2"));
- result = hTable.get(get);
- keyValues = result.raw();
- assertEquals(1, keyValues.length);
-
- // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
- delete = new Delete(toBytes("Key3"));
- delete.deleteFamily(family1);
- delete.deleteColumns(family2, family2_column1);
- hTable.delete(delete);
- // f2c2 f3c1
- get = new Get(toBytes("Key3"));
- result = hTable.get(get);
- keyValues = result.raw();
- assertEquals(2, keyValues.length);
-
- // f1c1 f1c2 f1c3 f2c1 f2c2 f3c1
- delete = new Delete(toBytes("Key4"));
- hTable.delete(delete);
- // null
- get = new Get(toBytes("Key4"));
- result = hTable.get(get);
- keyValues = result.raw();
- assertEquals(0, keyValues.length);
-
- // f1c1 f2c1 f2c2
- delete = new Delete(toBytes("Key5"));
- delete.deleteColumns(family1, family1_column2);
- delete.deleteColumns(family1, family1_column3);
- delete.deleteColumns(family3, family3_column1);
- hTable.delete(delete);
- // null
- get = new Get(toBytes("Key5"));
- result = hTable.get(get);
- keyValues = result.raw();
- assertEquals(3, keyValues.length);
-
- for (int i = 0; i < rows; ++i) {
- Put put = new Put(toBytes("Key" + i));
- put.add(family1, family1_column1, family1_value);
- put.add(family1, family1_column2, family1_value);
- put.add(family1, family1_column3, family1_value);
- put.add(family2, family2_column1, family2_value);
- put.add(family2, family2_column2, family2_value);
- put.add(family3, family3_column1, family3_value);
- hTable.put(put);
- }
-
- delete = new Delete(toBytes("Key6"));
- delete.deleteColumn(family1, family1_column2);
- delete.deleteColumn(family2, family2_column1);
- hTable.delete(delete);
- get = new Get(toBytes("Key6"));
- result = hTable.get(get);
- keyValues = result.raw();
- assertEquals(6, keyValues.length);
-
- long lastTimestamp = result.getColumnCells(family1, family1_column1).get(0).getTimestamp();
- assertEquals(lastTimestamp, result.getColumnCells(family1, family1_column3).get(0)
- .getTimestamp());
- assertEquals(lastTimestamp, result.getColumnCells(family2, family2_column2).get(0)
- .getTimestamp());
- assertEquals(lastTimestamp, result.getColumnCells(family3, family3_column1).get(0)
- .getTimestamp());
-
- long oldTimestamp = result.getColumnCells(family1, family1_column2).get(0).getTimestamp();
- assertEquals(oldTimestamp, result.getColumnCells(family2, family2_column1).get(0)
- .getTimestamp());
- assertTrue(lastTimestamp > oldTimestamp);
- }
-}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolLoadTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolLoadTest.java
index 4e66fc0b..d639d4a4 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolLoadTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolLoadTest.java
@@ -17,15 +17,17 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import com.alipay.oceanbase.rpc.exception.ObTableNotExistException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.HTableInterface;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import java.io.IOException;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.Executors;
import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
@@ -34,10 +36,10 @@
import static org.junit.Assert.assertTrue;
public class OHTablePoolLoadTest extends HTableTestBase {
- private OHTablePool ohTablePool;
+ private static OHTablePool ohTablePool;
- @Before
- public void setup() throws IOException {
+ @BeforeClass
+ public static void setup() throws Exception {
Configuration c = new Configuration();
c.set(HBASE_HTABLE_TEST_LOAD_ENABLE, "true");
ohTablePool = new OHTablePool(c, 10);
@@ -56,6 +58,16 @@ public void setup() throws IOException {
}
ohTablePool.setRuntimeBatchExecutor("test", Executors.newFixedThreadPool(3));
hTable = ohTablePool.getTable("test");
+ multiCfHTable = ohTablePool.getTable("test_multi_cf");
+ List tableGroups = new LinkedList<>();
+ tableGroups.add("test");
+ tableGroups.add("test_multi_cf");
+ ObHTableTestUtil.prepareClean(tableGroups);
+ }
+
+ @Before
+ public void prepareCase() {
+ ObHTableTestUtil.cleanData();
}
@Test
@@ -152,4 +164,11 @@ public void testNew() throws IOException {
hTable2.close();
assertTrue(true);
}
+
+ @AfterClass
+ public static void finish() throws IOException, SQLException {
+ hTable.close();
+ multiCfHTable.close();
+ ObHTableTestUtil.closeConn();
+ }
}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolTest.java
index 7ed492d3..d915afdc 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTablePoolTest.java
@@ -17,25 +17,26 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import com.alipay.remoting.util.ConcurrentHashSet;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.util.PoolMap;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import java.io.IOException;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import static com.alipay.oceanbase.hbase.util.ObTableClientManager.OB_TABLE_CLIENT_INSTANCE;
public class OHTablePoolTest extends HTableTestBase {
- protected OHTablePool ohTablePool;
+ protected static OHTablePool ohTablePool;
- private OHTablePool newOHTablePool(final int maxSize, final PoolMap.PoolType poolType) {
+ private static OHTablePool newOHTablePool(final int maxSize, final PoolMap.PoolType poolType) {
OHTablePool pool = new OHTablePool(new Configuration(), maxSize, poolType);
pool.setFullUserName("test", ObHTableTestUtil.FULL_USER_NAME);
pool.setPassword("test", ObHTableTestUtil.PASSWORD);
@@ -52,17 +53,29 @@ private OHTablePool newOHTablePool(final int maxSize, final PoolMap.PoolType poo
return pool;
}
- @Before
- public void setup() throws IOException {
+ @BeforeClass
+ public static void setup() throws Exception {
Configuration c = new Configuration();
ohTablePool = newOHTablePool(10, null);
ohTablePool.setRuntimeBatchExecutor("test", Executors.newFixedThreadPool(3));
hTable = ohTablePool.getTable("test");
+ multiCfHTable = ohTablePool.getTable("test_multi_cf");
+ List tableGroups = new LinkedList<>();
+ tableGroups.add("test");
+ tableGroups.add("test_multi_cf");
+ ObHTableTestUtil.prepareClean(tableGroups);
+ }
+
+ @Before
+ public void prepareCase() {
+ ObHTableTestUtil.cleanData();
}
- @After
- public void finish() throws IOException {
+ @AfterClass
+ public static void finish() throws IOException, SQLException {
hTable.close();
+ multiCfHTable.close();
+ ObHTableTestUtil.closeConn();
}
public void test_current_get_close(final OHTablePool ohTablePool, int concurrency, int maxSize) {
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableTest.java
index b14ca220..f36969ca 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHTableTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableTest.java
@@ -17,16 +17,18 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import com.alipay.oceanbase.rpc.ObTableClient;
import com.alipay.oceanbase.rpc.exception.ObTableNotExistException;
import com.alipay.sofa.common.thread.SofaThreadPoolExecutor;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.HTableInterface;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.*;
import java.io.IOException;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.SynchronousQueue;
import static com.alipay.oceanbase.hbase.util.TableHBaseLoggerFactory.TABLE_HBASE_LOGGER_SPACE;
@@ -35,12 +37,23 @@
import static org.junit.Assert.fail;
public class OHTableTest extends HTableTestBase {
- @Before
- public void setup() throws IOException {
+ @BeforeClass
+ public static void setup() throws Exception {
Configuration c = ObHTableTestUtil.newConfiguration();
c.set("rs.list.acquire.read.timeout", "10000");
+
hTable = new OHTable(c, "test");
+ multiCfHTable = new OHTable(c, "test_multi_cf");
+ List tableGroups = new LinkedList<>();
+ tableGroups.add("test");
+// tableGroups.add("test_multi_cf");
+ ObHTableTestUtil.prepareClean(tableGroups);
+ }
+
+ @Before
+ public void prepareCase() {
+ ObHTableTestUtil.cleanData();
}
@Test
@@ -93,4 +106,11 @@ public void testNew() throws Exception {
}
+ @AfterClass
+ public static void finish() throws IOException, SQLException {
+ hTable.close();
+ multiCfHTable.close();
+ ObHTableTestUtil.closeConn();
+ }
+
}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHVarPrefixPartitionTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHVarPrefixPartitionTest.java
index 3e22e9b0..2dc41621 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/OHVarPrefixPartitionTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/OHVarPrefixPartitionTest.java
@@ -1,5 +1,6 @@
package com.alipay.oceanbase.hbase;
+import com.alipay.oceanbase.hbase.util.ObHTableTestUtil;
import org.junit.After;
import org.junit.Before;
diff --git a/src/test/java/com/alipay/oceanbase/hbase/ObHTableTestUtil.java b/src/test/java/com/alipay/oceanbase/hbase/ObHTableTestUtil.java
deleted file mode 100644
index ba9d25f2..00000000
--- a/src/test/java/com/alipay/oceanbase/hbase/ObHTableTestUtil.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * #%L
- * OBKV HBase Client Framework
- * %%
- * Copyright (C) 2022 OceanBase Group
- * %%
- * OBKV HBase Client Framework is licensed under Mulan PSL v2.
- * You can use this software according to the terms and conditions of the Mulan PSL v2.
- * You may obtain a copy of Mulan PSL v2 at:
- * http://license.coscl.org.cn/MulanPSL2
- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
- * See the Mulan PSL v2 for more details.
- * #L%
- */
-
-package com.alipay.oceanbase.hbase;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseConfiguration;
-
-import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
-
-public class ObHTableTestUtil {
- // please consult your dba for the following configuration.
- public static String PARAM_URL = "";
- public static String FULL_USER_NAME = "";
- public static String PASSWORD = "";
- public static String SYS_USER_NAME = "";
- public static String SYS_PASSWORD = "";
- public static String ODP_ADDR = "";
- public static int ODP_PORT = 0;
- public static boolean ODP_MODE = false;
- public static String DATABASE = "";
-
- public static Configuration newConfiguration() {
- Configuration conf = HBaseConfiguration.create();
- conf.set(HBASE_OCEANBASE_FULL_USER_NAME, FULL_USER_NAME);
- conf.set(HBASE_OCEANBASE_PASSWORD, PASSWORD);
- if (ODP_MODE) {
- // ODP mode
- conf.set(HBASE_OCEANBASE_ODP_ADDR, ODP_ADDR);
- conf.setInt(HBASE_OCEANBASE_ODP_PORT, ODP_PORT);
- conf.setBoolean(HBASE_OCEANBASE_ODP_MODE, ODP_MODE);
- conf.set(HBASE_OCEANBASE_DATABASE, DATABASE);
- } else {
- // OCP mode
- conf.set(HBASE_OCEANBASE_PARAM_URL, PARAM_URL);
- conf.set(HBASE_OCEANBASE_SYS_USER_NAME, SYS_USER_NAME);
- conf.set(HBASE_OCEANBASE_SYS_PASSWORD, SYS_PASSWORD);
- }
- return conf;
- }
-
- public static OHTableClient newOHTableClient(String tableName) {
- return new OHTableClient(tableName, newConfiguration());
- }
-}
\ No newline at end of file
diff --git a/src/test/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtilsTest.java b/src/test/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtilsTest.java
index b228f0a4..bc567fa3 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtilsTest.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/filter/HBaseFilterUtilsTest.java
@@ -19,11 +19,15 @@
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
public class HBaseFilterUtilsTest {
private static final CompareFilter.CompareOp[] ops = { CompareFilter.CompareOp.LESS,
@@ -134,6 +138,39 @@ public void testSingleColumnValueFilter() throws IOException {
}
}
+ @Test
+ public void testSingleColumnValueExcludeFilter() throws IOException {
+ for (int i = 0; i < ops.length; i++) {
+ String expect = String
+ .format(
+ "SingleColumnValueExcludeFilter('family','qualifier',%s,'binary:value',false,true)",
+ opFlags[i]);
+ SingleColumnValueExcludeFilter filter = new SingleColumnValueExcludeFilter(
+ "family".getBytes(), "qualifier".getBytes(), ops[i], "value".getBytes());
+ Assert.assertArrayEquals(expect.getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+ }
+
+ @Test
+ public void testDependentColumnFilter() throws IOException {
+ DependentColumnFilter filter = new DependentColumnFilter("family".getBytes(),
+ "qualifier".getBytes());
+ String expect = "DependentColumnFilter('family','qualifier',false)";
+ Assert.assertArrayEquals(expect.getBytes(), HBaseFilterUtils.toParseableByteArray(filter));
+ filter = new DependentColumnFilter("family".getBytes(), "qualifier".getBytes(), true);
+ expect = "DependentColumnFilter('family','qualifier',true)";
+ Assert.assertArrayEquals(expect.getBytes(), HBaseFilterUtils.toParseableByteArray(filter));
+ for (int i = 0; i < ops.length; ++i) {
+ filter = new DependentColumnFilter("family".getBytes(), "qualifier".getBytes(), false,
+ ops[i], new BinaryComparator("value".getBytes()));
+ expect = String.format(
+ "DependentColumnFilter('family','qualifier',false,%s,'binary:value')", opFlags[i]);
+ Assert.assertArrayEquals(expect.getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+ }
+
@Test
public void testPageFilter() throws IOException {
PageFilter filter = new PageFilter(128);
@@ -159,6 +196,59 @@ public void testColumnPrefixFilter() throws IOException {
HBaseFilterUtils.toParseableByteArray(filter));
}
+ @Test
+ public void testFuzzyRowFilter() throws IOException {
+ List> fuzzyKey = new ArrayList<>();
+ fuzzyKey.add(new Pair(Bytes.toBytes("abc"), Bytes.toBytes("101")));
+ fuzzyKey.add(new Pair(Bytes.toBytes("ddd"), Bytes.toBytes("010")));
+
+ FuzzyRowFilter filter = new FuzzyRowFilter(fuzzyKey);
+ System.out.println(Bytes.toString(HBaseFilterUtils.toParseableByteArray(filter)));
+ Assert.assertArrayEquals("FuzzyRowFilter('abc','101','ddd','010')".getBytes(), HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
+ @Test
+ public void testMultiRowRangeFilter() throws IOException {
+ List ranges = new ArrayList<>();
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("a"), true, Bytes.toBytes("b"), false));
+ ranges.add(new MultiRowRangeFilter.RowRange(Bytes.toBytes("c"), true, Bytes.toBytes("d$%%"), false));
+
+ MultiRowRangeFilter filter = new MultiRowRangeFilter(ranges);
+ System.out.println(Bytes.toString(HBaseFilterUtils.toParseableByteArray(filter)));
+ Assert.assertArrayEquals("MultiRowRangeFilter('a',true,'b',false,'c',true,'d$%%',false)".getBytes(), HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
+ @Test
+ public void testInclusiveStopFilter() throws IOException {
+ InclusiveStopFilter filter = new InclusiveStopFilter(Bytes.toBytes("aaa"));
+ Assert.assertArrayEquals("InclusiveStopFilter('aaa')".getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
+ @Test
+ public void testColumnRangeFilter() throws IOException {
+ ColumnRangeFilter filter = new ColumnRangeFilter(Bytes.toBytes("a"), true,
+ Bytes.toBytes("b"), false);
+ Assert.assertArrayEquals("ColumnRangeFilter('a',true,'b',false)".getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
+ @Test
+ public void testMultipleColumnPrefixFilter() throws IOException {
+ byte[][] prefix = { Bytes.toBytes("a"), Bytes.toBytes("b"), Bytes.toBytes("d"), };
+ MultipleColumnPrefixFilter filter = new MultipleColumnPrefixFilter(prefix);
+ Assert.assertArrayEquals("MultipleColumnPrefixFilter('a','b','d')".getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
+ @Test
+ public void testFamilyFilter() throws IOException {
+ FamilyFilter filter = new FamilyFilter(CompareFilter.CompareOp.NOT_EQUAL,
+ new BinaryComparator(Bytes.toBytes("cf")));
+ Assert.assertArrayEquals("FamilyFilter(!=,'binary:cf')".getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
@Test
public void testColumnCountGetFilter() throws IOException {
ColumnCountGetFilter filter = new ColumnCountGetFilter(513);
@@ -166,6 +256,16 @@ public void testColumnCountGetFilter() throws IOException {
HBaseFilterUtils.toParseableByteArray(filter));
}
+ @Test
+ public void testFirstKeyValueMatchingQualifiersFilter() throws IOException {
+ TreeSet qualifiers = new TreeSet<>(Bytes.BYTES_COMPARATOR);
+ qualifiers.add(Bytes.toBytes("q1"));
+ qualifiers.add(Bytes.toBytes("q2"));
+ FirstKeyValueMatchingQualifiersFilter filter = new FirstKeyValueMatchingQualifiersFilter(qualifiers);
+ Assert.assertArrayEquals("FirstKeyValueMatchingQualifiersFilter('q1','q2')".getBytes(),
+ HBaseFilterUtils.toParseableByteArray(filter));
+ }
+
@Test
public void testPrefixFilter() throws IOException {
PrefixFilter filter = new PrefixFilter("prefix".getBytes());
diff --git a/src/test/java/com/alipay/oceanbase/hbase/util/NativeHBaseUtil.java b/src/test/java/com/alipay/oceanbase/hbase/util/NativeHBaseUtil.java
new file mode 100644
index 00000000..7d6d82b5
--- /dev/null
+++ b/src/test/java/com/alipay/oceanbase/hbase/util/NativeHBaseUtil.java
@@ -0,0 +1,105 @@
+package com.alipay.oceanbase.hbase.util;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.Table;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class NativeHBaseUtil {
+ public static String SQL_PATH = "src/test/java/unit_test_db.sql";
+ public static String MASTER_IP_PORT = "";
+ public static String ZK_QUORUM = "";
+ public static String ZK_PORT = "";
+
+ @Test
+ public void createTable() throws IOException {
+ Configuration config = new Configuration();
+ if (!MASTER_IP_PORT.isEmpty()) {
+ config.set("hbase.master", MASTER_IP_PORT);
+ }
+ config.set("hbase.zookeeper.quorum", ZK_QUORUM);
+ config.set("hbase.zookeeper.property.clientPort", ZK_PORT);
+ // 建立连接
+ Connection connection = ConnectionFactory.createConnection(config);
+ Admin admin = connection.getAdmin();
+
+ // 读取建表语句
+ String sql = new String(Files.readAllBytes(Paths.get(SQL_PATH)));
+ String[] sqlList = sql.split(";");
+ Map tableMap = new LinkedHashMap<>();
+ for (String singleSql : sqlList) {
+ String namespace = null;
+ String realTableName;
+ String family;
+
+ if (singleSql.contains("CREATE TABLE ")) {
+ singleSql.trim();
+ String[] splits = singleSql.split(" ");
+ realTableName = splits[2].substring(1, splits[2].length() - 1);
+ if (realTableName.contains(":")) {
+ String[] tmpStr = realTableName.split(":", 2);
+ namespace = tmpStr[0];
+ realTableName = tmpStr[1];
+ }
+ String[] tmpStr = realTableName.split("\\$", 2);
+ realTableName = tmpStr[0];
+ family = tmpStr[1];
+ HTableDescriptor hTableDescriptor = tableMap.get(realTableName);
+ if (hTableDescriptor == null) {
+ hTableDescriptor = new HTableDescriptor(TableName.valueOf(namespace, realTableName));
+ tableMap.put(realTableName, hTableDescriptor);
+ }
+ if (family != null) {
+ try {
+ HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(family);
+ hColumnDescriptor.setMaxVersions(1000);
+ hTableDescriptor.addFamily(hColumnDescriptor);
+
+ } catch (Exception e) {
+ System.out.println("family has exist");
+ }
+ }
+ // 不分区,结果不会有变化
+ }
+ }
+ for (Map.Entry entry : tableMap.entrySet()) {
+ if (admin.tableExists(entry.getValue().getTableName())) {
+ admin.disableTable(entry.getValue().getTableName());
+ admin.deleteTable(entry.getValue().getTableName());
+ }
+ admin.createTable(entry.getValue());
+ }
+ }
+
+ static public Table getTable(TableName tableName) throws IOException {
+ Configuration config = new Configuration();
+ config.set("hbase.master", MASTER_IP_PORT);
+ config.set("hbase.zookeeper.quorum", ZK_QUORUM);
+ config.set("hbase.zookeeper.property.clientPort", ZK_PORT);
+ // 建立连接
+ Connection connection = ConnectionFactory.createConnection(config);
+ return connection.getTable(tableName);
+ }
+
+ static public Admin getAdmin() throws IOException {
+ Configuration config = new Configuration();
+ config.set("hbase.master", MASTER_IP_PORT);
+ config.set("hbase.zookeeper.quorum", ZK_QUORUM);
+ config.set("hbase.zookeeper.property.clientPort", ZK_PORT);
+ // 建立连接
+ Connection connection = ConnectionFactory.createConnection(config);
+ return connection.getAdmin();
+ }
+
+}
diff --git a/src/test/java/com/alipay/oceanbase/hbase/util/OHTableHotkeyThrottleUtil.java b/src/test/java/com/alipay/oceanbase/hbase/util/OHTableHotkeyThrottleUtil.java
index 950ce5db..aaa3c5a9 100644
--- a/src/test/java/com/alipay/oceanbase/hbase/util/OHTableHotkeyThrottleUtil.java
+++ b/src/test/java/com/alipay/oceanbase/hbase/util/OHTableHotkeyThrottleUtil.java
@@ -18,7 +18,6 @@
package com.alipay.oceanbase.hbase.util;
import com.alipay.oceanbase.hbase.OHTableClient;
-import com.alipay.oceanbase.hbase.ObHTableTestUtil;
import com.alipay.oceanbase.rpc.exception.ObTableUnexpectedException;
import org.apache.hadoop.hbase.client.*;
import org.junit.Assert;
diff --git a/src/test/java/com/alipay/oceanbase/hbase/util/ObHTableTestUtil.java b/src/test/java/com/alipay/oceanbase/hbase/util/ObHTableTestUtil.java
new file mode 100644
index 00000000..41e68bb2
--- /dev/null
+++ b/src/test/java/com/alipay/oceanbase/hbase/util/ObHTableTestUtil.java
@@ -0,0 +1,159 @@
+/*-
+ * #%L
+ * OBKV HBase Client Framework
+ * %%
+ * Copyright (C) 2022 OceanBase Group
+ * %%
+ * OBKV HBase Client Framework is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ * #L%
+ */
+
+package com.alipay.oceanbase.hbase.util;
+
+import com.alipay.oceanbase.hbase.OHTableClient;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HTableDescriptor;
+
+import java.sql.Connection;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.*;
+
+import static com.alipay.oceanbase.hbase.constants.OHConstants.*;
+
+public class ObHTableTestUtil {
+ // please consult your dba for the following configuration.
+ public static String PARAM_URL = "";
+ public static String FULL_USER_NAME = "";
+ public static String PASSWORD = "";
+ public static String SYS_USER_NAME = "";
+ public static String SYS_PASSWORD = "";
+ public static String ODP_ADDR = "";
+ public static int ODP_PORT = 0;
+ public static boolean ODP_MODE = false;
+ public static String DATABASE = "";
+ public static String JDBC_IP = "";
+ public static String JDBC_PORT = "";
+ public static String JDBC_DATABASE = "";
+ public static String JDBC_URL = "jdbc:mysql://" + JDBC_IP + ":" + JDBC_PORT + "/ "
+ + JDBC_DATABASE + "?" + "useUnicode=TRUE&"
+ + "characterEncoding=utf-8&"
+ + "socketTimeout=3000000&" + "connectTimeout=60000";
+
+ public static String SQL_FORMAT = "truncate %s";
+ public static List tableNameList;
+ public static Connection conn;
+ public static Statement stmt;
+
+ static {
+ tableNameList = new LinkedList<>();
+ conn = getConnection();
+ try {
+ stmt = conn.createStatement();
+ } catch (SQLException e) {
+ System.out.println("sql error " + e);
+ }
+ }
+
+ public static void prepareClean(List tableGroupList) throws Exception {
+ for (String tableGroup : tableGroupList) {
+ tableNameList.addAll(getOTableNameList(tableGroup));
+ }
+ }
+
+ public static void cleanData() {
+ try {
+ for (String realTableName : tableNameList) {
+ try {
+ if (realTableName.contains("'")) {
+ realTableName = "`" + realTableName + "`";
+ }
+ stmt.execute(String.format(SQL_FORMAT, realTableName));
+ } catch (Exception e) {
+ System.out.println("clean table data error ." + realTableName + " exception:"
+ + e);
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void closeConn() throws SQLException {
+ stmt.close();
+ conn.close();
+ }
+
+ public static Configuration newConfiguration() {
+ Configuration conf = HBaseConfiguration.create();
+ conf.set(HBASE_OCEANBASE_FULL_USER_NAME, FULL_USER_NAME);
+ conf.set(HBASE_OCEANBASE_PASSWORD, PASSWORD);
+ if (ODP_MODE) {
+ // ODP mode
+ conf.set(HBASE_OCEANBASE_ODP_ADDR, ODP_ADDR);
+ conf.setInt(HBASE_OCEANBASE_ODP_PORT, ODP_PORT);
+ conf.setBoolean(HBASE_OCEANBASE_ODP_MODE, ODP_MODE);
+ conf.set(HBASE_OCEANBASE_DATABASE, DATABASE);
+ } else {
+ // OCP mode
+ conf.set(HBASE_OCEANBASE_PARAM_URL, PARAM_URL);
+ conf.set(HBASE_OCEANBASE_SYS_USER_NAME, SYS_USER_NAME);
+ conf.set(HBASE_OCEANBASE_SYS_PASSWORD, SYS_PASSWORD);
+ }
+ return conf;
+ }
+
+ public static OHTableClient newOHTableClient(String tableName) {
+ return new OHTableClient(tableName, newConfiguration());
+ }
+
+ static public List getOTableNameList(String tableGroup) throws IOException {
+ // 读取建表语句
+ List res = new LinkedList<>();
+ String sql = new String(Files.readAllBytes(Paths.get(NativeHBaseUtil.SQL_PATH)));
+ String[] sqlList = sql.split(";");
+ Map tableMap = new LinkedHashMap<>();
+ for (String singleSql : sqlList) {
+ String realTableName;
+ if (singleSql.contains("CREATE TABLE ")) {
+ singleSql.trim();
+ String[] splits = singleSql.split(" ");
+ String tableGroupName = splits[2].substring(1, splits[2].length() - 1);
+ if (tableGroupName.contains(":")) {
+ String[] tmpStr = tableGroupName.split(":", 2);
+ tableGroupName = tmpStr[1];
+ }
+ realTableName = tableGroupName.split("\\$", 2)[0];
+ if (realTableName.equals(tableGroup)) {
+ res.add(tableGroupName);
+ }
+ }
+ }
+ return res;
+ }
+
+ static public Connection getConnection() {
+ try {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ String[] userNames = FULL_USER_NAME.split("#");
+ Connection conn = DriverManager.getConnection(JDBC_URL, userNames[0], PASSWORD);
+
+ return conn;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/unit_test_db.sql b/src/test/java/unit_test_db.sql
index 6d4432dd..cbb172fe 100644
--- a/src/test/java/unit_test_db.sql
+++ b/src/test/java/unit_test_db.sql
@@ -212,3 +212,56 @@ CREATE TABLE `test_multi_cf$family_with_group3` (
`V` varbinary(1024) DEFAULT NULL,
PRIMARY KEY (`K`, `Q`, `T`)
) TABLEGROUP = test_multi_cf PARTITION BY KEY(`K`) PARTITIONS 3;
+
+CREATE DATABASE IF NOT EXISTS `n1`;
+USE `n1`;
+CREATE TABLE `n1:test$family1` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ PRIMARY KEY (`K`, `Q`, `T`)
+);
+
+CREATE TABLE `n1:test_t$family1` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ PRIMARY KEY (`K`, `Q`, `T`)
+);
+
+CREATE TABLEGROUP `n1:test` SHARDING = 'ADAPTIVE';
+CREATE TABLE `n1:test$family'1` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ PRIMARY KEY (`K`, `Q`, `T`)
+) TABLEGROUP = `n1:test`;
+
+CREATE TABLE `n1:test$family_with_local_index` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ key `idx1`(T) local,
+ PRIMARY KEY (`K`, `Q`, `T`)
+);
+
+CREATE TABLE `n1:test$family_group` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ PRIMARY KEY (`K`, `Q`, `T`)
+) TABLEGROUP = `n1:test`;
+
+CREATE TABLE `n1:test$partitionFamily1` (
+ `K` varbinary(1024) NOT NULL,
+ `Q` varbinary(256) NOT NULL,
+ `T` bigint(20) NOT NULL,
+ `V` varbinary(1024) DEFAULT NULL,
+ PRIMARY KEY (`K`, `Q`, `T`)
+) partition by key(`K`) partitions 17;
+
diff --git a/src/main/resources/hbase-site.xml b/src/test/resources/hbase-site.xml
similarity index 100%
rename from src/main/resources/hbase-site.xml
rename to src/test/resources/hbase-site.xml
|