From b24ae3109b8e168828749b0d85f5a28dcb8c1d7b Mon Sep 17 00:00:00 2001 From: maochongxin Date: Tue, 11 Nov 2025 21:46:14 +0800 Subject: [PATCH 1/3] hotkey get opt case From 611f1c959fb057a86751323ef3fd5a4156028afa Mon Sep 17 00:00:00 2001 From: maochongxin Date: Fri, 12 Dec 2025 11:24:10 +0800 Subject: [PATCH 2/3] add batch get case --- .../com/alipay/oceanbase/hbase/OHTable.java | 10 ++ .../hbase/OHTableGetOptimizeTest.java | 156 ++++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java index 11e5728d..4b0e5878 100644 --- a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java +++ b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java @@ -2122,6 +2122,16 @@ private ObTableQuery buildObTableQuery(final Get get, Collection columnQ obTableQuery.setScanRangeColumns("K", "Q", "T"); byte[] hotOnly = get.getAttribute(HBASE_HTABLE_QUERY_HOT_ONLY); obTableQuery.setHotOnly(hotOnly != null && Arrays.equals(hotOnly, "true".getBytes())); + boolean hotKeyGetOptimizeEnableBool = false; + byte[] hotKeyGetOptimizeEnable = get.getAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE); + if (hotKeyGetOptimizeEnable == null) { + boolean hotKeyGetOptimizeEnableGlobal = configuration.getBoolean(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL, false); + hotKeyGetOptimizeEnableBool = hotKeyGetOptimizeEnableGlobal; + } else { + hotKeyGetOptimizeEnableBool = Boolean.parseBoolean(Bytes.toString(hotKeyGetOptimizeEnable)); + } + + obTableQuery.setGetOptimized(hotKeyGetOptimizeEnableBool); return obTableQuery; } diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java index 518027a1..f6507c4a 100644 --- a/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java +++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java @@ -101,6 +101,14 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); Assert.assertEquals(t3, r.rawCells()[0].getTimestamp()); + get = new Get(toBytes(key1)); + get.addColumn(family1.getBytes(), column1.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + r = hTable.get(get); + Assert.assertEquals(1, r.rawCells().length); + Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + Assert.assertEquals(t3, r.rawCells()[0].getTimestamp()); + // Test min(1, 10) = 1 get = new Get(toBytes(key1)); get.addColumn(family1.getBytes(), column1.getBytes()); @@ -109,6 +117,16 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + get = new Get(toBytes(key1)); + get.addColumn(family1.getBytes(), column1.getBytes()); + get.setMaxVersions(10); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + r = hTable.get(get); + Assert.assertEquals(1, r.rawCells().length); + Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + + + // Get with setMaxVersions(1) put = new Put(toBytes(key2)); put.addColumn(family2.getBytes(), column1.getBytes(), t1, toBytes(value1)); @@ -131,6 +149,16 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); Assert.assertEquals(t3, r.rawCells()[0].getTimestamp()); + get = new Get(toBytes(key2)); + get.addColumn(family2.getBytes(), column1.getBytes()); + get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + r = hTable.get(get); + Assert.assertEquals(1, r.rawCells().length); + Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + Assert.assertEquals(t3, r.rawCells()[0].getTimestamp()); + + // Verify multiple versions exist when requesting them get = new Get(toBytes(key2)); get.addColumn(family2.getBytes(), column1.getBytes()); @@ -140,6 +168,16 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); Assert.assertEquals(value2, Bytes.toString(r.rawCells()[1].getValueArray(), r.rawCells()[1].getValueOffset(), r.rawCells()[1].getValueLength())); Assert.assertEquals(value1, Bytes.toString(r.rawCells()[2].getValueArray(), r.rawCells()[2].getValueOffset(), r.rawCells()[2].getValueLength())); + + get = new Get(toBytes(key2)); + get.addColumn(family2.getBytes(), column1.getBytes()); + get.setMaxVersions(10); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + r = hTable.get(get); + Assert.assertTrue(r.rawCells().length >= 3); + Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + Assert.assertEquals(value2, Bytes.toString(r.rawCells()[1].getValueArray(), r.rawCells()[1].getValueOffset(), r.rawCells()[1].getValueLength())); + Assert.assertEquals(value1, Bytes.toString(r.rawCells()[2].getValueArray(), r.rawCells()[2].getValueOffset(), r.rawCells()[2].getValueLength())); } /** @@ -1043,4 +1081,122 @@ public void testGetOptimizeWithoutQualifierTimestampAndMaxVersion1() throws Exce Assert.assertEquals(timestamps[4], r2.rawCells()[i].getTimestamp()); } } + + @Test + public void testGetOptimizeWithGlobalSetting() throws Exception { + Configuration c = ObHTableTestUtil.newConfiguration(); + c.set("rs.list.acquire.read.timeout", "10000"); + c.set(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL, "true"); + hTable = new OHTable(c, "test_get_optimize"); + + String family = "family_max_version_1"; + String key = "global_setting_key"; + String col = "col"; + + long baseTime = System.currentTimeMillis(); + for (int i = 1; i <= 5; i++) { + Put put = new Put(toBytes(key)); + put.addColumn(family.getBytes(), col.getBytes(), baseTime + i, toBytes("value_" + i)); + hTable.put(put); + } + + Get get = new Get(toBytes(key)); + get.addColumn(family.getBytes(), col.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + Result r = hTable.get(get); + Assert.assertEquals(1, r.rawCells().length); + Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); + + + get = new Get(toBytes(key)); + get.addColumn(family.getBytes(), col.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); + Result r2 = hTable.get(get); + Assert.assertEquals(1, r2.rawCells().length); + Assert.assertEquals("value_5", Bytes.toString(r2.rawCells()[0].getValueArray(), r2.rawCells()[0].getValueOffset(), r2.rawCells()[0].getValueLength())); + + + get = new Get(toBytes(key)); + get.addColumn(family.getBytes(), col.getBytes()); + Result r3 = hTable.get(get); + Assert.assertEquals(1, r3.rawCells().length); + Assert.assertEquals("value_5", Bytes.toString(r3.rawCells()[0].getValueArray(), r3.rawCells()[0].getValueOffset(), r3.rawCells()[0].getValueLength())); + } + + + // test batch get single cf with global setting + @Test + public void testGetOptimizeBatchGetSingleCfWithGlobalSetting() throws Exception { + Configuration c = ObHTableTestUtil.newConfiguration(); + c.set("rs.list.acquire.read.timeout", "10000"); + c.set(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL, "true"); + hTable = new OHTable(c, "test_get_optimize"); + + String family = "family_max_version_1"; + String col = "col"; + + // Use different keys for batch get test + List keys = Arrays.asList("batch_key_01", "batch_key_02", "batch_key_03", "batch_key_04", "batch_key_05"); + long baseTime = System.currentTimeMillis(); + + // Put multiple versions for each key + for (String key : keys) { + for (int i = 1; i <= 3; i++) { + Put put = new Put(toBytes(key)); + put.addColumn(family.getBytes(), col.getBytes(), baseTime + i, toBytes(key + "_v" + i)); + hTable.put(put); + } + } + + List gets = new ArrayList<>(); + for (String key : keys) { + Get get = new Get(toBytes(key)); + get.addColumn(family.getBytes(), col.getBytes()); + gets.add(get); + } + + // Test with statement-level setting to false (should override global setting) + for (Get get : gets) { + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); + } + + Result[] results = hTable.get(gets); + Assert.assertEquals(5, results.length); + for (int i = 0; i < results.length; i++) { + Assert.assertEquals(1, results[i].rawCells().length); + // Should return latest version (v3) when optimize is disabled + Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); + } + + // Test with statement-level setting to true (should override global setting) + for (Get get : gets) { + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); + } + + results = hTable.get(gets); + Assert.assertEquals(5, results.length); + for (int i = 0; i < results.length; i++) { + Assert.assertEquals(1, results[i].rawCells().length); + // Should return latest version (v3) when optimize is enabled + Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); + } + + // Test without statement-level setting (should use global setting which is true) + gets = new ArrayList<>(); + for (String key : keys) { + Get get = new Get(toBytes(key)); + get.addColumn(family.getBytes(), col.getBytes()); + // Don't set statement-level attribute, should use global setting + gets.add(get); + } + + results = hTable.get(gets); + Assert.assertEquals(5, results.length); + for (int i = 0; i < results.length; i++) { + Assert.assertEquals(1, results[i].rawCells().length); + // Should return latest version (v3) using global setting + Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); + } + } + } From 5fe53740a4433d2084c31b646ca1b35dcf5c88ff Mon Sep 17 00:00:00 2001 From: maochongxin Date: Thu, 11 Dec 2025 15:16:50 +0800 Subject: [PATCH 3/3] Add client configuration to control hot key optimization enablement --- .../com/alipay/oceanbase/hbase/OHTable.java | 14 +++ .../hbase/constants/OHConstants.java | 11 ++ .../hbase/OHTableGetOptimizeTest.java | 114 ++++++------------ 3 files changed, 62 insertions(+), 77 deletions(-) diff --git a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java index 4b0e5878..f3e19c91 100644 --- a/src/main/java/com/alipay/oceanbase/hbase/OHTable.java +++ b/src/main/java/com/alipay/oceanbase/hbase/OHTable.java @@ -2094,6 +2094,20 @@ private ObTableQuery buildObTableQuery(ObHTableFilter filter, final Scan scan) { obTableQuery.setScanRangeColumns("K", "Q", "T"); byte[] hotOnly = scan.getAttribute(HBASE_HTABLE_QUERY_HOT_ONLY); obTableQuery.setHotOnly(hotOnly != null && Arrays.equals(hotOnly, "true".getBytes())); + // HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE is a statement-level setting, while HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL is a global setting. + // The statement-level setting takes precedence over the global setting. + // If the statement-level setting is not configured, use the global setting. + // If the statement-level setting is configured, use the statement-level setting. + boolean hotKeyGetOptimizeEnableBool = false; + byte[] hotKeyGetOptimizeEnable = scan.getAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE); + if (hotKeyGetOptimizeEnable == null) { + boolean hotKeyGetOptimizeEnableGlobal = configuration.getBoolean(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL, false); + hotKeyGetOptimizeEnableBool = hotKeyGetOptimizeEnableGlobal; + } else { + hotKeyGetOptimizeEnableBool = Boolean.parseBoolean(Bytes.toString(hotKeyGetOptimizeEnable)); + } + + obTableQuery.setGetOptimized(hotKeyGetOptimizeEnableBool); return obTableQuery; } 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 8f896111..f8263a57 100644 --- a/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java +++ b/src/main/java/com/alipay/oceanbase/hbase/constants/OHConstants.java @@ -134,6 +134,17 @@ public final class OHConstants { */ public static final String HBASE_HTABLE_READ_CONSISTENCY = "hbase.htable.read.consistency"; + + /** + * use to specify whether to enable the hotkey get optimize when performing a query. + */ + public static final String HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE = "hbase.htable.hotkey.get.optimize.enable"; + + /** + * use to specify whether to enable the hotkey get optimize globally. + */ + public static final String HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL = "hbase.htable.hotkey.get.optimize.enable.global"; + /** * use to specify the idc when performing a query. */ diff --git a/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java b/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java index f6507c4a..18368589 100644 --- a/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java +++ b/src/test/java/com/alipay/oceanbase/hbase/OHTableGetOptimizeTest.java @@ -27,6 +27,8 @@ import java.sql.SQLException; import java.util.*; +import static com.alipay.oceanbase.hbase.constants.OHConstants.HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE; +import static com.alipay.oceanbase.hbase.constants.OHConstants.HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL; import static org.apache.hadoop.hbase.util.Bytes.toBytes; /** @@ -96,6 +98,7 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { // Get with single column Get get = new Get(toBytes(key1)); get.addColumn(family1.getBytes(), column1.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -113,6 +116,7 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { get = new Get(toBytes(key1)); get.addColumn(family1.getBytes(), column1.getBytes()); get.setMaxVersions(10); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -144,6 +148,7 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { get = new Get(toBytes(key2)); get.addColumn(family2.getBytes(), column1.getBytes()); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -163,6 +168,7 @@ public void testGetOptimizeWithMaxVersion1() throws Exception { get = new Get(toBytes(key2)); get.addColumn(family2.getBytes(), column1.getBytes()); get.setMaxVersions(10); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertTrue(r.rawCells().length >= 3); Assert.assertEquals(value3, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -216,6 +222,7 @@ public void testGetOptimizeSingleColumn() throws Exception { Get get = new Get(toBytes(key)); get.addColumn(family.getBytes(), col1.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_c1_v3", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -234,6 +241,7 @@ public void testGetOptimizeSingleColumn() throws Exception { get = new Get(toBytes(key)); get.addColumn(family.getBytes(), col2.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r2 = hTable.get(get); Assert.assertEquals(1, r2.rawCells().length); Assert.assertEquals("value_c2_v2", Bytes.toString(r2.rawCells()[0].getValueArray(), r2.rawCells()[0].getValueOffset(), r2.rawCells()[0].getValueLength())); @@ -282,6 +290,10 @@ public void testGetOptimizeBatchGet() throws Exception { gets.add(get); } + for (Get get : gets) { + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); + } + Result[] results = hTable.get(gets); Assert.assertEquals(3, results.length); for (int i = 0; i < results.length; i++) { @@ -320,6 +332,7 @@ public void testGetOptimizeExplicitMaxVersion1() throws Exception { Get get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -328,6 +341,7 @@ public void testGetOptimizeExplicitMaxVersion1() throws Exception { get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); get.setMaxVersions(3); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(3, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -337,6 +351,7 @@ public void testGetOptimizeExplicitMaxVersion1() throws Exception { // Get with default MaxVersions get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -379,6 +394,7 @@ public void testGetOptimizeWithTimeRange() throws Exception { Get get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); get.setTimeRange(t1, t2 + 1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); // With MaxVersions=1 at table level, should get only 1 version Assert.assertTrue(r.rawCells().length >= 1); @@ -390,6 +406,7 @@ public void testGetOptimizeWithTimeRange() throws Exception { get.addColumn(family.getBytes(), column.getBytes()); get.setTimeRange(t1, t3 + 1); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_t3", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -436,6 +453,7 @@ public void testGetOptimizeWithSpecificTimestamp() throws Exception { Get get = new Get(toBytes(key)); get.addColumn(family1.getBytes(), column.getBytes()); get.setTimeStamp(t2); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_t2", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -445,6 +463,7 @@ public void testGetOptimizeWithSpecificTimestamp() throws Exception { get = new Get(toBytes(key)); get.addColumn(family1.getBytes(), column.getBytes()); get.setTimeStamp(t1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_t1", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -454,6 +473,7 @@ public void testGetOptimizeWithSpecificTimestamp() throws Exception { get = new Get(toBytes(key)); get.addColumn(family1.getBytes(), column.getBytes()); get.setTimeStamp(t3); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_t3", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -478,6 +498,7 @@ public void testGetOptimizeWithSpecificTimestamp() throws Exception { get.addColumn(family2.getBytes(), column.getBytes()); get.setTimeStamp(t2); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value2_t2", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -488,6 +509,7 @@ public void testGetOptimizeWithSpecificTimestamp() throws Exception { get = new Get(toBytes(key2)); get.addColumn(family2.getBytes(), column.getBytes()); get.setTimeStamp(nonExistentTs); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(0, r.rawCells().length); } @@ -522,6 +544,7 @@ public void testGetOptimizeWithSpecificTimestampMultiVersions() throws Exception Get get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); get.setTimeStamp(timestamps[i]); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_" + i, Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -533,6 +556,7 @@ public void testGetOptimizeWithSpecificTimestampMultiVersions() throws Exception get.addColumn(family.getBytes(), column.getBytes()); get.setTimeStamp(timestamps[2]); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_2", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -543,6 +567,7 @@ public void testGetOptimizeWithSpecificTimestampMultiVersions() throws Exception get = new Get(toBytes(key)); get.addColumn(family.getBytes(), column.getBytes()); get.setTimeStamp(betweenTs); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(0, r.rawCells().length); } @@ -611,6 +636,7 @@ public void testGetOptimizeWithMultipleQualifiersOnMaxVersion1Table() throws Exc get.addColumn(family.getBytes(), col1.getBytes()); get.addColumn(family.getBytes(), col2.getBytes()); get.addColumn(family.getBytes(), col3.getBytes()); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(3, r.rawCells().length); @@ -666,6 +692,7 @@ public void testGetOptimizeWithMultipleQualifiersAndExplicitMaxVersion1() throws get.addColumn(family.getBytes(), col3.getBytes()); get.addColumn(family.getBytes(), col4.getBytes()); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(4, r.rawCells().length); @@ -687,6 +714,7 @@ public void testGetOptimizeWithMultipleQualifiersAndExplicitMaxVersion1() throws get.addColumn(family.getBytes(), col1.getBytes()); get.addColumn(family.getBytes(), col2.getBytes()); get.setMaxVersions(3); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(6, r.rawCells().length); @@ -740,6 +768,7 @@ public void testGetOptimizeWithMultipleQualifiersAndTimestamp() throws Exception get.addColumn(family.getBytes(), col2.getBytes()); get.addColumn(family.getBytes(), col3.getBytes()); get.setTimeStamp(t2); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(3, r.rawCells().length); @@ -788,6 +817,7 @@ public void testTableMaxVersionPrecedence() throws Exception { Get get = new Get(toBytes(key)); get.addColumn(family.getBytes(), col.getBytes()); get.setMaxVersions(3); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -796,6 +826,7 @@ public void testTableMaxVersionPrecedence() throws Exception { get = new Get(toBytes(key)); get.addColumn(family.getBytes(), col.getBytes()); get.setMaxVersions(5); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -804,6 +835,7 @@ public void testTableMaxVersionPrecedence() throws Exception { get = new Get(toBytes(key)); get.addColumn(family.getBytes(), col.getBytes()); get.setMaxVersions(10); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); r = hTable.get(get); Assert.assertEquals(1, r.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r.rawCells()[0].getValueArray(), r.rawCells()[0].getValueOffset(), r.rawCells()[0].getValueLength())); @@ -844,6 +876,7 @@ public void testTableMaxVersionPrecedenceWithMultipleQualifiers() throws Excepti get.addColumn(family.getBytes(), col2.getBytes()); get.addColumn(family.getBytes(), col3.getBytes()); get.setMaxVersions(3); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(3, r.rawCells().length); @@ -939,6 +972,7 @@ public void testGetOptimizeWithoutQualifierAndExplicitMaxVersion1() throws Excep Get get = new Get(toBytes(key)); get.addFamily(family.getBytes()); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(4, r.rawCells().length); @@ -999,6 +1033,7 @@ public void testGetOptimizeWithoutQualifierAndTimestamp() throws Exception { Get get = new Get(toBytes(key)); get.addFamily(family.getBytes()); get.setTimeStamp(t2); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(3, r.rawCells().length); @@ -1051,6 +1086,7 @@ public void testGetOptimizeWithoutQualifierTimestampAndMaxVersion1() throws Exce get.addFamily(family.getBytes()); get.setTimeStamp(timestamps[2]); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r = hTable.get(get); Assert.assertEquals(4, r.rawCells().length); @@ -1074,6 +1110,7 @@ public void testGetOptimizeWithoutQualifierTimestampAndMaxVersion1() throws Exce get.addFamily(family.getBytes()); get.setTimeStamp(timestamps[4]); get.setMaxVersions(1); + get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); Result r2 = hTable.get(get); Assert.assertEquals(4, r2.rawCells().length); @@ -1122,81 +1159,4 @@ public void testGetOptimizeWithGlobalSetting() throws Exception { Assert.assertEquals(1, r3.rawCells().length); Assert.assertEquals("value_5", Bytes.toString(r3.rawCells()[0].getValueArray(), r3.rawCells()[0].getValueOffset(), r3.rawCells()[0].getValueLength())); } - - - // test batch get single cf with global setting - @Test - public void testGetOptimizeBatchGetSingleCfWithGlobalSetting() throws Exception { - Configuration c = ObHTableTestUtil.newConfiguration(); - c.set("rs.list.acquire.read.timeout", "10000"); - c.set(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE_GLOBAL, "true"); - hTable = new OHTable(c, "test_get_optimize"); - - String family = "family_max_version_1"; - String col = "col"; - - // Use different keys for batch get test - List keys = Arrays.asList("batch_key_01", "batch_key_02", "batch_key_03", "batch_key_04", "batch_key_05"); - long baseTime = System.currentTimeMillis(); - - // Put multiple versions for each key - for (String key : keys) { - for (int i = 1; i <= 3; i++) { - Put put = new Put(toBytes(key)); - put.addColumn(family.getBytes(), col.getBytes(), baseTime + i, toBytes(key + "_v" + i)); - hTable.put(put); - } - } - - List gets = new ArrayList<>(); - for (String key : keys) { - Get get = new Get(toBytes(key)); - get.addColumn(family.getBytes(), col.getBytes()); - gets.add(get); - } - - // Test with statement-level setting to false (should override global setting) - for (Get get : gets) { - get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "false".getBytes()); - } - - Result[] results = hTable.get(gets); - Assert.assertEquals(5, results.length); - for (int i = 0; i < results.length; i++) { - Assert.assertEquals(1, results[i].rawCells().length); - // Should return latest version (v3) when optimize is disabled - Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); - } - - // Test with statement-level setting to true (should override global setting) - for (Get get : gets) { - get.setAttribute(HBASE_HTABLE_HOTKEY_GET_OPTIMIZE_ENABLE, "true".getBytes()); - } - - results = hTable.get(gets); - Assert.assertEquals(5, results.length); - for (int i = 0; i < results.length; i++) { - Assert.assertEquals(1, results[i].rawCells().length); - // Should return latest version (v3) when optimize is enabled - Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); - } - - // Test without statement-level setting (should use global setting which is true) - gets = new ArrayList<>(); - for (String key : keys) { - Get get = new Get(toBytes(key)); - get.addColumn(family.getBytes(), col.getBytes()); - // Don't set statement-level attribute, should use global setting - gets.add(get); - } - - results = hTable.get(gets); - Assert.assertEquals(5, results.length); - for (int i = 0; i < results.length; i++) { - Assert.assertEquals(1, results[i].rawCells().length); - // Should return latest version (v3) using global setting - Assert.assertEquals(keys.get(i) + "_v3", Bytes.toString(results[i].rawCells()[0].getValueArray(), results[i].rawCells()[0].getValueOffset(), results[i].rawCells()[0].getValueLength())); - } - } - }