Skip to content

Commit bf50db7

Browse files
authored
orders iterators by name when priority the same (#6075)
1 parent 6474192 commit bf50db7

3 files changed

Lines changed: 120 additions & 1 deletion

File tree

core/src/main/java/org/apache/accumulo/core/iteratorsImpl/IteratorConfigUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ public class IteratorConfigUtil {
5555
private static final Logger log = LoggerFactory.getLogger(IteratorConfigUtil.class);
5656

5757
public static final Comparator<IterInfo> ITER_INFO_COMPARATOR =
58-
Comparator.comparingInt(IterInfo::getPriority);
58+
Comparator.comparingInt(IterInfo::getPriority)
59+
.thenComparing(iterInfo -> iterInfo.getIterName() == null ? "" : iterInfo.getIterName());
5960

6061
/**
6162
* Fetch the correct configuration key prefix for the given scope. Throws an

test/src/main/java/org/apache/accumulo/test/functional/CompactionIT.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
import org.apache.accumulo.test.VerifyIngest.VerifyParams;
104104
import org.apache.accumulo.test.compaction.CompactionExecutorIT;
105105
import org.apache.accumulo.test.compaction.ExternalCompaction_1_IT.FSelector;
106+
import org.apache.accumulo.test.functional.ScanIteratorIT.AppendingIterator;
106107
import org.apache.accumulo.test.util.Wait;
107108
import org.apache.hadoop.conf.Configuration;
108109
import org.apache.hadoop.fs.FileSystem;
@@ -988,6 +989,56 @@ public void testMigrationCancelCompaction() throws Exception {
988989
}
989990
}
990991

992+
@Test
993+
public void testIteratorOrder() throws Exception {
994+
String[] names = getUniqueNames(2);
995+
try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) {
996+
997+
// create a table with minor compaction iterators configured to ensure those iterators are
998+
// applied in the correct order
999+
NewTableConfiguration ntc = new NewTableConfiguration()
1000+
.attachIterator(AppendingIterator.configure(50, "x"), EnumSet.of(IteratorScope.minc))
1001+
.attachIterator(AppendingIterator.configure(100, "a"), EnumSet.of(IteratorScope.minc));
1002+
c.tableOperations().create(names[0], ntc);
1003+
1004+
// create a table with major compaction iterators configured to ensure those iterators are
1005+
// applied in the correct order
1006+
NewTableConfiguration ntc2 = new NewTableConfiguration()
1007+
.attachIterator(AppendingIterator.configure(50, "x"), EnumSet.of(IteratorScope.majc))
1008+
.attachIterator(AppendingIterator.configure(100, "a"), EnumSet.of(IteratorScope.majc));
1009+
c.tableOperations().create(names[1], ntc2);
1010+
1011+
try (var writer = c.createBatchWriter(names[0]);
1012+
var writer2 = c.createBatchWriter(names[1])) {
1013+
Mutation m = new Mutation("r1");
1014+
m.put("", "", "base:");
1015+
writer.addMutation(m);
1016+
writer2.addMutation(m);
1017+
}
1018+
1019+
try (var mincScanner = c.createScanner(names[0]);
1020+
var majcScanner = c.createScanner(names[1])) {
1021+
// iterators should not be applied yet
1022+
assertEquals("base:", mincScanner.iterator().next().getValue().toString());
1023+
assertEquals("base:", majcScanner.iterator().next().getValue().toString());
1024+
1025+
c.tableOperations().flush(names[0], null, null, true);
1026+
assertEquals("base:xa", mincScanner.iterator().next().getValue().toString());
1027+
assertEquals("base:", majcScanner.iterator().next().getValue().toString());
1028+
1029+
// The user compaction iterators with priority 50 and 100 have the same priority as table
1030+
// level iterators.
1031+
List<IteratorSetting> iters = List.of(AppendingIterator.configure(70, "m"),
1032+
AppendingIterator.configure(50, "b"), AppendingIterator.configure(100, "c"));
1033+
c.tableOperations().compact(names[1],
1034+
new CompactionConfig().setWait(true).setFlush(true).setIterators(iters));
1035+
assertEquals("base:xa", mincScanner.iterator().next().getValue().toString());
1036+
assertEquals("base:bxmac", majcScanner.iterator().next().getValue().toString());
1037+
1038+
}
1039+
}
1040+
}
1041+
9911042
/**
9921043
* Counts the number of tablets and files in a table.
9931044
*/

test/src/main/java/org/apache/accumulo/test/functional/ScanIteratorIT.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
import static org.apache.accumulo.harness.AccumuloITBase.SUNNY_DAY;
2222
import static org.junit.jupiter.api.Assertions.assertEquals;
2323

24+
import java.io.IOException;
2425
import java.time.Duration;
2526
import java.util.ArrayList;
2627
import java.util.Collections;
28+
import java.util.EnumSet;
2729
import java.util.HashSet;
2830
import java.util.Map;
2931
import java.util.Map.Entry;
32+
import java.util.Objects;
3033

3134
import org.apache.accumulo.cluster.ClusterUser;
3235
import org.apache.accumulo.core.client.Accumulo;
@@ -38,11 +41,17 @@
3841
import org.apache.accumulo.core.client.Scanner;
3942
import org.apache.accumulo.core.client.ScannerBase;
4043
import org.apache.accumulo.core.client.TableNotFoundException;
44+
import org.apache.accumulo.core.client.admin.CompactionConfig;
45+
import org.apache.accumulo.core.client.admin.NewTableConfiguration;
4146
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
4247
import org.apache.accumulo.core.data.Key;
4348
import org.apache.accumulo.core.data.Mutation;
4449
import org.apache.accumulo.core.data.Range;
4550
import org.apache.accumulo.core.data.Value;
51+
import org.apache.accumulo.core.iterators.IteratorEnvironment;
52+
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
53+
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
54+
import org.apache.accumulo.core.iterators.WrappingIterator;
4655
import org.apache.accumulo.core.security.Authorizations;
4756
import org.apache.accumulo.core.security.TablePermission;
4857
import org.apache.accumulo.harness.AccumuloClusterHarness;
@@ -250,4 +259,62 @@ private void writeTestMutation(AccumuloClient userC)
250259
batchWriter.flush();
251260
}
252261
}
262+
263+
public static class AppendingIterator extends WrappingIterator {
264+
265+
private String append;
266+
267+
@Override
268+
public void init(SortedKeyValueIterator<Key,Value> source, Map<String,String> options,
269+
IteratorEnvironment env) throws IOException {
270+
super.init(source, options, env);
271+
append = Objects.requireNonNull(options.get("append"));
272+
}
273+
274+
@Override
275+
public Value getTopValue() {
276+
var val = super.getTopValue();
277+
return new Value(val.toString() + append);
278+
}
279+
280+
public static IteratorSetting configure(int prio, String append) {
281+
IteratorSetting iter = new IteratorSetting(prio, "append_" + append, AppendingIterator.class);
282+
iter.addOption("append", append);
283+
return iter;
284+
}
285+
}
286+
287+
// Ensures scan iterators run in the expected order
288+
@Test
289+
public void testIteratorOrder() throws Exception {
290+
291+
String tableName = getUniqueNames(2)[1];
292+
try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) {
293+
var scopes = EnumSet.of(IteratorScope.scan);
294+
NewTableConfiguration ntc =
295+
new NewTableConfiguration().attachIterator(AppendingIterator.configure(50, "x"), scopes)
296+
.attachIterator(AppendingIterator.configure(100, "a"), scopes);
297+
c.tableOperations().create(tableName, ntc);
298+
299+
try (var writer = c.createBatchWriter(tableName)) {
300+
Mutation m = new Mutation("r1");
301+
m.put("", "", "base:");
302+
writer.addMutation(m);
303+
}
304+
305+
try (var scanner = c.createScanner(tableName)) {
306+
assertEquals("base:xa", scanner.iterator().next().getValue().toString());
307+
scanner.addScanIterator(AppendingIterator.configure(70, "m"));
308+
assertEquals("base:xma", scanner.iterator().next().getValue().toString());
309+
// These have the same priority as a table iterator so the iterators should be ordered by
310+
// their name in that case
311+
scanner.addScanIterator(AppendingIterator.configure(50, "b"));
312+
scanner.addScanIterator(AppendingIterator.configure(100, "c"));
313+
assertEquals("base:bxmac", scanner.iterator().next().getValue().toString());
314+
// There are no compaction iterators, so this should not change value
315+
c.tableOperations().compact(tableName, new CompactionConfig().setWait(true));
316+
assertEquals("base:bxmac", scanner.iterator().next().getValue().toString());
317+
}
318+
}
319+
}
253320
}

0 commit comments

Comments
 (0)