You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by rm...@apache.org on 2025/03/19 22:19:13 UTC
(hbase) 01/01: HBASE-29103 Avoid excessive allocations during reverse scanning when seeking to next row (#6643)
This is an automated email from the ASF dual-hosted git repository.
rmattingly pushed a commit to branch HBASE-29103-branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
commit 77d09a3434620f64b78a40bdd2789308dacf9ec8
Author: jbewing <jb...@live.com>
AuthorDate: Wed Mar 19 18:17:44 2025 -0400
HBASE-29103 Avoid excessive allocations during reverse scanning when seeking to next row (#6643)
Signed-off-by: Nick Dimiduk <nd...@apache.org>
Signed-off-by: Ray Mattingly <rm...@apache.org>
---
.../hbase/regionserver/StoreFileScanner.java | 40 ++++++++++++----------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
index 6e0824a16c6..6ce1a3236c4 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileScanner.java
@@ -63,7 +63,10 @@ public class StoreFileScanner implements KeyValueScanner {
// if have encountered the next row. Only used for reversed scan
private boolean stopSkippingKVsIfNextRow = false;
// A Cell that represents the row before the most previously seeked to row in seekToPreviousRow
- private Cell previousRow = null;
+ // Note: Oftentimes this will contain an instance of a KeyOnly implementation of the Cell as it's
+ // not returned to callers and only used as a hint for seeking (so we can save on
+ // memory/allocations)
+ private ExtendedCell previousRow = null;
// Whether the underlying HFile is using a data block encoding that has lower cost for seeking to
// a row from the beginning of a block (i.e. RIV1). If the data block encoding has a high cost for
// seeks, then we can use a modified reverse scanning algorithm to reduce seeks from the beginning
@@ -519,13 +522,14 @@ public class StoreFileScanner implements KeyValueScanner {
}
/**
- * This variant of the {@link StoreFileScanner#seekToPreviousRow(Cell)} method requires one seek
- * and one reseek. This method maintains state in {@link StoreFileScanner#previousRow} which only
- * makes sense in the context of a sequential row-by-row reverse scan.
+ * This variant of the {@link StoreFileScanner#seekToPreviousRow(ExtendedCell)} method requires
+ * one seek and one reseek. This method maintains state in {@link StoreFileScanner#previousRow}
+ * which only makes sense in the context of a sequential row-by-row reverse scan.
* {@link StoreFileScanner#previousRow} should be reset if that is not the case. The reasoning for
- * why this method is faster than {@link StoreFileScanner#seekToPreviousRowStateless(Cell)} is
- * that seeks are slower as they need to start from the beginning of the file, while reseeks go
- * forward from the current position.
+ * why this method is faster than
+ * {@link StoreFileScanner#seekToPreviousRowStateless(ExtendedCell)} is that seeks are slower as
+ * they need to start from the beginning of the file, while reseeks go forward from the current
+ * position.
*/
private boolean seekToPreviousRowWithHint() throws IOException {
do {
@@ -555,12 +559,12 @@ public class StoreFileScanner implements KeyValueScanner {
}
/**
- * This variant of the {@link StoreFileScanner#seekToPreviousRow(Cell)} method requires two seeks
- * and one reseek. The extra expense/seek is with the intent of speeding up subsequent calls by
- * using the {@link StoreFileScanner#seekToPreviousRowWithHint} which this method seeds the state
- * for by setting {@link StoreFileScanner#previousRow}
+ * This variant of the {@link StoreFileScanner#seekToPreviousRow(ExtendedCell)} method requires
+ * two seeks and one reseek. The extra expense/seek is with the intent of speeding up subsequent
+ * calls by using the {@link StoreFileScanner#seekToPreviousRowWithHint} which this method seeds
+ * the state for by setting {@link StoreFileScanner#previousRow}
*/
- private boolean seekToPreviousRowWithoutHint(Cell originalKey) throws IOException {
+ private boolean seekToPreviousRowWithoutHint(ExtendedCell originalKey) throws IOException {
// Rewind to the cell before the beginning of this row
ExtendedCell keyAtBeginningOfRow = PrivateCellUtil.createFirstOnRow(originalKey);
if (!seekBefore(keyAtBeginningOfRow)) {
@@ -568,7 +572,7 @@ public class StoreFileScanner implements KeyValueScanner {
}
// Rewind before this row and save what we find as a seek hint
- ExtendedCell firstKeyOfPreviousRow = PrivateCellUtil.createFirstOnRow(hfs.getCell());
+ ExtendedCell firstKeyOfPreviousRow = PrivateCellUtil.createFirstOnRow(hfs.getKey());
seekBeforeAndSaveKeyToPreviousRow(firstKeyOfPreviousRow);
// Seek back to the start of the previous row
@@ -596,9 +600,9 @@ public class StoreFileScanner implements KeyValueScanner {
}
/**
- * This variant of the {@link StoreFileScanner#seekToPreviousRow(Cell)} method requires two seeks.
- * It should be used if the cost for seeking is lower i.e. when using a fast seeking data block
- * encoding like RIV1.
+ * This variant of the {@link StoreFileScanner#seekToPreviousRow(ExtendedCell)} method requires
+ * two seeks. It should be used if the cost for seeking is lower i.e. when using a fast seeking
+ * data block encoding like RIV1.
*/
private boolean seekToPreviousRowStateless(ExtendedCell originalKey) throws IOException {
ExtendedCell key = originalKey;
@@ -608,7 +612,7 @@ public class StoreFileScanner implements KeyValueScanner {
return false;
}
- ExtendedCell firstKeyOfPreviousRow = PrivateCellUtil.createFirstOnRow(hfs.getCell());
+ ExtendedCell firstKeyOfPreviousRow = PrivateCellUtil.createFirstOnRow(hfs.getKey());
if (!seekAtOrAfter(firstKeyOfPreviousRow)) {
return false;
}
@@ -651,7 +655,7 @@ public class StoreFileScanner implements KeyValueScanner {
hfs.seekTo();
this.previousRow = null;
} else {
- this.previousRow = hfs.getCell();
+ this.previousRow = hfs.getKey();
}
}