This is an automated email from the ASF dual-hosted git repository.
domgarguilo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new a09859d9d8 Add Add RowRange filters to listtablets command (#6069)
a09859d9d8 is described below
commit a09859d9d80646b5488741b8ea9809e270c4c81f
Author: Dom G. <[email protected]>
AuthorDate: Tue Jan 27 12:58:30 2026 -0500
Add Add RowRange filters to listtablets command (#6069)
* Add Add RowRange filters to listtablets command
---
.../shell/commands/GetAvailabilityCommand.java | 10 +----
.../shell/commands/ListTabletsCommand.java | 21 ++++++++-
.../shell/commands/ListTabletsCommandTest.java | 51 ++++++++++++++++++++++
.../apache/accumulo/test/shell/ShellServerIT.java | 38 ++++++++++++++++
4 files changed, 110 insertions(+), 10 deletions(-)
diff --git
a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAvailabilityCommand.java
b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAvailabilityCommand.java
index 567403066d..8a6f492b98 100644
---
a/shell/src/main/java/org/apache/accumulo/shell/commands/GetAvailabilityCommand.java
+++
b/shell/src/main/java/org/apache/accumulo/shell/commands/GetAvailabilityCommand.java
@@ -31,7 +31,6 @@ public class GetAvailabilityCommand extends TableOperation {
private Option optRow;
private Option optStartRowExclusive;
- private Option optEndRowExclusive;
private RowRange range;
@Override
@@ -73,8 +72,7 @@ public class GetAvailabilityCommand extends TableOperation {
Text startRow = OptUtil.getStartRow(cl);
Text endRow = OptUtil.getEndRow(cl);
final boolean startInclusive =
!cl.hasOption(optStartRowExclusive.getOpt());
- final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
- this.range = RowRange.range(startRow, startInclusive, endRow,
endInclusive);
+ this.range = RowRange.range(startRow, startInclusive, endRow, true);
}
return super.execute(fullCommand, cl, shellState);
}
@@ -84,11 +82,8 @@ public class GetAvailabilityCommand extends TableOperation {
Option optStartRowInclusive =
new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row
(inclusive)");
optStartRowExclusive = new Option("be", "begin-exclusive", false,
- "make start row exclusive (by default it's inclusive");
+ "make start row exclusive (by default it's inclusive)");
optStartRowExclusive.setArgName("begin-exclusive");
- optEndRowExclusive = new Option("ee", "end-exclusive", false,
- "make end row exclusive (by default it's inclusive)");
- optEndRowExclusive.setArgName("end-exclusive");
optRow = new Option("r", "row", true, "tablet row to read");
optRow.setArgName("row");
@@ -96,7 +91,6 @@ public class GetAvailabilityCommand extends TableOperation {
opts.addOption(optStartRowInclusive);
opts.addOption(optStartRowExclusive);
opts.addOption(OptUtil.endRowOpt());
- opts.addOption(optEndRowExclusive);
opts.addOption(optRow);
return opts;
diff --git
a/shell/src/main/java/org/apache/accumulo/shell/commands/ListTabletsCommand.java
b/shell/src/main/java/org/apache/accumulo/shell/commands/ListTabletsCommand.java
index b5fe3d91ed..2b48cdf6c7 100644
---
a/shell/src/main/java/org/apache/accumulo/shell/commands/ListTabletsCommand.java
+++
b/shell/src/main/java/org/apache/accumulo/shell/commands/ListTabletsCommand.java
@@ -41,6 +41,7 @@ import org.apache.accumulo.shell.ShellOptions;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
+import org.apache.hadoop.io.Text;
import com.google.common.annotations.VisibleForTesting;
@@ -55,6 +56,7 @@ public class ListTabletsCommand extends Command {
private Option optHumanReadable;
private Option optNamespace;
private Option disablePaginationOpt;
+ private Option startRowExclusiveOpt;
static final String header =
String.format("%-4s %-15s %-5s %-5s %-9s %-9s %-10s %-30s %-5s %-20s
%-20s %-10s", "NUM",
@@ -76,8 +78,14 @@ public class ListTabletsCommand extends Command {
String name = tableInfo.name;
lines.add("TABLE: " + name);
- try (Stream<TabletInformation> tabletInfoStream =
shellState.getContext().tableOperations()
- .getTabletInformation(name, List.of(RowRange.all()))) {
+ Text startRow = OptUtil.getStartRow(cl);
+ Text endRow = OptUtil.getEndRow(cl);
+ final boolean startInclusive =
!cl.hasOption(startRowExclusiveOpt.getOpt());
+ final RowRange range = (startRow == null && endRow == null) ?
RowRange.all()
+ : RowRange.range(startRow, startInclusive, endRow, true);
+
+ try (Stream<TabletInformation> tabletInfoStream =
+ shellState.getContext().tableOperations().getTabletInformation(name,
List.of(range))) {
final AtomicInteger counter = new AtomicInteger(1);
tabletInfoStream.forEach(tabletInfo -> {
int i = counter.getAndIncrement();
@@ -262,6 +270,15 @@ public class ListTabletsCommand extends Command {
outputFileOpt.setArgName("file");
opts.addOption(outputFileOpt);
+ Option startRowOpt =
+ new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row
(inclusive)");
+ startRowExclusiveOpt = new Option("be", "begin-exclusive", false,
+ "make start row exclusive (by default it's inclusive)");
+ startRowExclusiveOpt.setArgName("begin-exclusive");
+ opts.addOption(startRowOpt);
+ opts.addOption(startRowExclusiveOpt);
+ opts.addOption(OptUtil.endRowOpt());
+
return opts;
}
diff --git
a/shell/src/test/java/org/apache/accumulo/shell/commands/ListTabletsCommandTest.java
b/shell/src/test/java/org/apache/accumulo/shell/commands/ListTabletsCommandTest.java
index 569cf714de..a12c23e3c5 100644
---
a/shell/src/test/java/org/apache/accumulo/shell/commands/ListTabletsCommandTest.java
+++
b/shell/src/test/java/org/apache/accumulo/shell/commands/ListTabletsCommandTest.java
@@ -126,6 +126,44 @@ public class ListTabletsCommandTest {
}
+ private static class NoOpListTabletsCommand extends ListTabletsCommand {
+
+ @Override
+ protected void printResults(CommandLine cl, Shell shellState, List<String>
lines) {
+ // no-op for range option testing
+ }
+ }
+
+ private void runRangeTest(String[] args, RowRange expectedRange) throws
Exception {
+ ListTabletsCommand cmd = new NoOpListTabletsCommand();
+
+ TableId tableId = TableId.of("123");
+
+ AccumuloClient client = EasyMock.createMock(AccumuloClient.class);
+ ClientContext context = EasyMock.createMock(ClientContext.class);
+ TableOperations tableOps = EasyMock.createMock(TableOperations.class);
+ Shell shellState = EasyMock.createMock(Shell.class);
+
+ Options opts = cmd.getOptions();
+ CommandLineParser parser = new DefaultParser();
+ CommandLine cli = parser.parse(opts, args);
+
+
EasyMock.expect(shellState.getAccumuloClient()).andReturn(client).anyTimes();
+ EasyMock.expect(shellState.getContext()).andReturn(context).anyTimes();
+ EasyMock.expect(client.tableOperations()).andReturn(tableOps).anyTimes();
+ EasyMock.expect(context.tableOperations()).andReturn(tableOps).anyTimes();
+ EasyMock.expect(tableOps.getTabletInformation(tableName,
List.of(expectedRange)))
+ .andReturn(Stream.empty());
+
+ Map<String,String> idMap = new TreeMap<>();
+ idMap.put(tableName, tableId.canonical());
+ EasyMock.expect(tableOps.tableIdMap()).andReturn(idMap);
+
+ EasyMock.replay(client, context, tableOps, shellState);
+ cmd.execute(String.join(" ", args), cli, shellState);
+ EasyMock.verify(client, context, tableOps, shellState);
+ }
+
@Test
public void mockTest() throws Exception {
ListTabletsCommand cmd = new TestListTabletsCommand();
@@ -205,4 +243,17 @@ public class ListTabletsCommandTest {
EasyMock.verify(client, context, tableOps, instOps, shellState);
}
+ @Test
+ public void mockTestRangeOptions() throws Exception {
+ runRangeTest(new String[] {"-t", tableName}, RowRange.all());
+ runRangeTest(new String[] {"-t", tableName, "-b", "n"},
+ RowRange.range(new Text("n"), true, null, true));
+ runRangeTest(new String[] {"-t", tableName, "-e", "n"},
+ RowRange.range(null, true, new Text("n"), true));
+ runRangeTest(new String[] {"-t", tableName, "-b", "h", "-e", "t"},
+ RowRange.range(new Text("h"), true, new Text("t"), true));
+ runRangeTest(new String[] {"-t", tableName, "-b", "n", "-e", "u", "-be"},
+ RowRange.range(new Text("n"), false, new Text("u"), true));
+ }
+
}
diff --git
a/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
b/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
index 262c7856f6..38553d7af2 100644
--- a/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/shell/ShellServerIT.java
@@ -1300,6 +1300,12 @@ public class ShellServerIT extends SharedMiniClusterBase
{
assertTrue(result.matches("(?s).*" + tableId + ";s;m\\s+HOSTED.*"));
assertFalse(result.matches("(?s).*" + tableId + "<;s\\s+ONDEMAND.*"));
+ result = ts.exec("getavailability -e m");
+ assertTrue(result.matches("(?s).*" + tableId + ";d<\\s+ONDEMAND.*"));
+ assertTrue(result.matches("(?s).*" + tableId + ";m;d\\s+ONDEMAND.*"));
+ assertFalse(result.matches("(?s).*" + tableId + ";s;m\\s+HOSTED.*"));
+ assertFalse(result.matches("(?s).*" + tableId + "<;s\\s+ONDEMAND.*"));
+
} finally {
if (splitsFilePath != null) {
Files.delete(splitsFilePath);
@@ -2385,6 +2391,38 @@ public class ShellServerIT extends SharedMiniClusterBase
{
assertTrue(
results.contains(tableId2 + " t +INF
ONDEMAND"));
+ String filtered = ts.exec("listtablets -np -t " + table1 + " -b h -e t",
true);
+ assertTrue(
+ filtered.contains(tableId1 + " g n
ONDEMAND"));
+ assertTrue(
+ filtered.contains(tableId1 + " n u
HOSTED"));
+ assertFalse(filtered.contains(tableId1 + " -INF g"));
+ assertFalse(filtered.contains(tableId1 + " u
+INF"));
+
+ filtered = ts.exec("listtablets -np -t " + table1 + " -b n", true);
+ assertFalse(filtered.contains(tableId1 + " -INF g"));
+ assertTrue(
+ filtered.contains(tableId1 + " g n
ONDEMAND"));
+ assertTrue(
+ filtered.contains(tableId1 + " n u
HOSTED"));
+ assertTrue(
+ filtered.contains(tableId1 + " u +INF
ONDEMAND"));
+
+ filtered = ts.exec("listtablets -np -t " + table1 + " -e n", true);
+ assertTrue(
+ filtered.contains(tableId1 + " -INF g
HOSTED"));
+ assertTrue(
+ filtered.contains(tableId1 + " g n
ONDEMAND"));
+ assertFalse(
+ filtered.contains(tableId1 + " n u
HOSTED"));
+ assertFalse(filtered.contains(tableId1 + " u
+INF"));
+
+ filtered = ts.exec("listtablets -np -t " + table1 + " -b n -be", true);
+ assertFalse(filtered.contains(tableId1 + " -INF g"));
+ assertFalse(filtered.contains(tableId1 + " g n"));
+ assertTrue(filtered.contains(tableId1 + " n u"));
+ assertTrue(filtered.contains(tableId1 + " u +INF"));
+
// verify the sum of the tablets sizes, number of entries, and dir name
match the data in a
// metadata scan
String metadata = ts.exec("scan -np -t accumulo.metadata -b " + tableId1 +
" -c loc,file");