This is an automated email from the ASF dual-hosted git repository.
junegunn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new 1de0aefd27b HBASE-29696 Fix incorrect TableInputFormat split
boundaries (#8491)
1de0aefd27b is described below
commit 1de0aefd27b5f13d022735325389bce1d82f670d
Author: Ma Zhengxuan <[email protected]>
AuthorDate: Thu Jul 30 13:48:43 2026 +0800
HBASE-29696 Fix incorrect TableInputFormat split boundaries (#8491)
Signed-off-by: Junegunn Choi <[email protected]>
Reviewed-by: Andrew Olson <[email protected]>
---
.../hbase/mapreduce/TableInputFormatBase.java | 3 +++
.../hbase/mapreduce/TestTableInputFormatBase.java | 21 +++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java
index 11ea6e58770..40e96d51516 100644
---
a/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java
+++
b/hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/TableInputFormatBase.java
@@ -407,6 +407,9 @@ public abstract class TableInputFormatBase extends
InputFormat<ImmutableBytesWri
// Split Region into n chunks evenly
byte[][] splitKeys = Bytes.split(startRow, endRow, true, n - 1);
+ // Restore the original boundaries after using synthetic ones to calculate
the split keys.
+ splitKeys[0] = ts.getStartRow();
+ splitKeys[splitKeys.length - 1] = ts.getEndRow();
for (int i = 0; i < splitKeys.length - 1; i++) {
// In the table input format for single table we do not need to
// store the scan object in table split because it can be memory
intensive and redundant
diff --git
a/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestTableInputFormatBase.java
b/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestTableInputFormatBase.java
index 124221e4478..d13d729be49 100644
---
a/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestTableInputFormatBase.java
+++
b/hbase-mapreduce/src/test/java/org/apache/hadoop/hbase/mapreduce/TestTableInputFormatBase.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.hbase.mapreduce;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -27,6 +28,7 @@ import java.io.IOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
@@ -52,6 +54,7 @@ import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.JobContext;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@@ -62,6 +65,24 @@ import org.mockito.stubbing.Answer;
@Tag(SmallTests.TAG)
public class TestTableInputFormatBase {
+ @Test
+ public void testCreateNInputSplitsUniformPreservesOriginalBoundaries()
throws IOException {
+ TableInputFormat inputFormat = new TableInputFormat();
+ for (byte[] startRow : new byte[][] { HConstants.EMPTY_START_ROW,
Bytes.toBytes("start") }) {
+ TableSplit split =
+ new TableSplit(TableName.valueOf("test"), startRow,
HConstants.EMPTY_END_ROW, "localhost");
+
+ List<InputSplit> splits = inputFormat.createNInputSplitsUniform(split,
2);
+
+ assertEquals(2, splits.size());
+ TableSplit first = (TableSplit) splits.get(0);
+ TableSplit last = (TableSplit) splits.get(1);
+ assertArrayEquals(startRow, first.getStartRow());
+ assertArrayEquals(first.getEndRow(), last.getStartRow());
+ assertArrayEquals(HConstants.EMPTY_END_ROW, last.getEndRow());
+ }
+ }
+
@Test
public void testReuseRegionSizeCalculator() throws IOException {
JobContext context = mock(JobContext.class);