You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2025/02/07 13:49:54 UTC
(lucene) branch branch_10x updated: Deprecate Operations.concat(a1, a2) and Operations.union(a1, a2) (#14209)
This is an automated email from the ASF dual-hosted git repository.
rmuir pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new 84891a0af8b Deprecate Operations.concat(a1, a2) and Operations.union(a1, a2) (#14209)
84891a0af8b is described below
commit 84891a0af8b2e208a93cd97304ea548c4c2a3042
Author: Robert Muir <rm...@apache.org>
AuthorDate: Fri Feb 7 08:33:27 2025 -0500
Deprecate Operations.concat(a1, a2) and Operations.union(a1, a2) (#14209)
These algorithms run in linear time: it is trappy to offer two-arg
options: they encourage users to use them in a loop and create quadratic
time.
Send a strong signal to the user's editor/IDE to avoid trouble in the
first place:
* Deprecate two-arg methods in favor of the List-based versions
* Rename parameter 'l' to 'list'
* Add javadoc @param to parameter 'list'
---
lucene/CHANGES.txt | 3 +
.../apache/lucene/util/automaton/Operations.java | 28 ++++++---
.../lucene/analysis/TestGraphTokenizers.java | 21 +++----
.../apache/lucene/search/TestAutomatonQuery.java | 8 ++-
.../lucene/util/automaton/TestAutomaton.java | 69 +++++++++++++---------
.../lucene/util/automaton/TestDeterminism.java | 4 +-
.../util/automaton/TestFiniteStringsIterator.java | 7 ++-
.../util/automaton/TestLevenshteinAutomata.java | 66 +++++++++------------
.../TestLimitedFiniteStringsIterator.java | 4 +-
.../lucene/util/automaton/TestNFARunAutomaton.java | 3 +-
.../lucene/util/automaton/TestOperations.java | 35 ++++++-----
.../lucene/util/automaton/TestRegExpParsing.java | 46 +++++++++------
.../search/suggest/document/ContextQuery.java | 16 ++---
.../tests/util/automaton/AutomatonTestUtil.java | 4 +-
14 files changed, 177 insertions(+), 137 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 5f1df581302..105ed74f298 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -13,6 +13,9 @@ API Changes
* GITHUB#14134: Added Bits#applyMask API to help apply live docs as a mask on a
bit set of matches. (Adrien Grand)
+* GITHUB#14209: Deprecate Operations.union(Automaton,Automaton) and
+ concatenate(Automaton,Automaton) in favor of the methods taking List. (Robert Muir)
+
New Features
---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/Operations.java b/lucene/core/src/java/org/apache/lucene/util/automaton/Operations.java
index fb255f8a02e..2a1a0086fdc 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/Operations.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/Operations.java
@@ -69,7 +69,10 @@ public final class Operations {
* Returns an automaton that accepts the concatenation of the languages of the given automata.
*
* <p>Complexity: linear in total number of states.
+ *
+ * @deprecated use {@link #concatenate(List)} instead
*/
+ @Deprecated
public static Automaton concatenate(Automaton a1, Automaton a2) {
return concatenate(Arrays.asList(a1, a2));
}
@@ -78,12 +81,14 @@ public final class Operations {
* Returns an automaton that accepts the concatenation of the languages of the given automata.
*
* <p>Complexity: linear in total number of states.
+ *
+ * @param list List of automata to be joined
*/
- public static Automaton concatenate(List<Automaton> l) {
+ public static Automaton concatenate(List<Automaton> list) {
Automaton result = new Automaton();
// First pass: create all states
- for (Automaton a : l) {
+ for (Automaton a : list) {
if (a.getNumStates() == 0) {
result.finishState();
return result;
@@ -98,11 +103,11 @@ public final class Operations {
// states of A to init state of next A:
int stateOffset = 0;
Transition t = new Transition();
- for (int i = 0; i < l.size(); i++) {
- Automaton a = l.get(i);
+ for (int i = 0; i < list.size(); i++) {
+ Automaton a = list.get(i);
int numStates = a.getNumStates();
- Automaton nextA = (i == l.size() - 1) ? null : l.get(i + 1);
+ Automaton nextA = (i == list.size() - 1) ? null : list.get(i + 1);
for (int s = 0; s < numStates; s++) {
int numTransitions = a.initTransition(s, t);
@@ -127,7 +132,7 @@ public final class Operations {
if (followA.isAccept(0)) {
// Keep chaining if followA accepts empty string
followOffset += followA.getNumStates();
- followA = (upto == l.size() - 1) ? null : l.get(upto + 1);
+ followA = (upto == list.size() - 1) ? null : list.get(upto + 1);
upto++;
} else {
break;
@@ -474,7 +479,10 @@ public final class Operations {
* Returns an automaton that accepts the union of the languages of the given automata.
*
* <p>Complexity: linear in number of states.
+ *
+ * @deprecated use {@link #union(Collection)} instead
*/
+ @Deprecated
public static Automaton union(Automaton a1, Automaton a2) {
return union(Arrays.asList(a1, a2));
}
@@ -483,21 +491,23 @@ public final class Operations {
* Returns an automaton that accepts the union of the languages of the given automata.
*
* <p>Complexity: linear in number of states.
+ *
+ * @param list List of automata to be unioned.
*/
- public static Automaton union(Collection<Automaton> l) {
+ public static Automaton union(Collection<Automaton> list) {
Automaton result = new Automaton();
// Create initial state:
result.createState();
// Copy over all automata
- for (Automaton a : l) {
+ for (Automaton a : list) {
result.copy(a);
}
// Add epsilon transition from new initial state
int stateOffset = 1;
- for (Automaton a : l) {
+ for (Automaton a : list) {
if (a.getNumStates() == 0) {
continue;
}
diff --git a/lucene/core/src/test/org/apache/lucene/analysis/TestGraphTokenizers.java b/lucene/core/src/test/org/apache/lucene/analysis/TestGraphTokenizers.java
index 4737694702f..0f3a9e6c62c 100644
--- a/lucene/core/src/test/org/apache/lucene/analysis/TestGraphTokenizers.java
+++ b/lucene/core/src/test/org/apache/lucene/analysis/TestGraphTokenizers.java
@@ -454,7 +454,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
});
final Automaton a1 = join(s2a("a"), SEP_A, HOLE_A, SEP_A, HOLE_A, SEP_A, s2a("b"));
final Automaton a2 = join(s2a("x"), SEP_A, s2a("b"));
- assertSameLanguage(Operations.union(a1, a2), ts);
+ assertSameLanguage(Operations.union(List.of(a1, a2)), ts);
}
// for debugging!
@@ -515,7 +515,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
new CannedTokenStream(new Token[] {token("abc", 1, 1), token("xyz", 0, 1)});
final Automaton a1 = s2a("abc");
final Automaton a2 = s2a("xyz");
- assertSameLanguage(Operations.union(a1, a2), ts);
+ assertSameLanguage(Operations.union(List.of(a1, a2)), ts);
}
public void testOverlappedTokensLattice() throws Exception {
@@ -527,7 +527,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
});
final Automaton a1 = s2a("xyz");
final Automaton a2 = join("abc", "def");
- assertSameLanguage(Operations.union(a1, a2), ts);
+ assertSameLanguage(Operations.union(List.of(a1, a2)), ts);
}
public void testSynOverHole() throws Exception {
@@ -537,8 +537,8 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
new Token[] {
token("a", 1, 1), token("X", 0, 2), token("b", 2, 1),
});
- final Automaton a1 = Operations.union(join(s2a("a"), SEP_A, HOLE_A), s2a("X"));
- final Automaton expected = Operations.concatenate(a1, join(SEP_A, s2a("b")));
+ final Automaton a1 = Operations.union(List.of(join(s2a("a"), SEP_A, HOLE_A), s2a("X")));
+ final Automaton expected = Operations.concatenate(List.of(a1, join(SEP_A, s2a("b"))));
assertSameLanguage(expected, ts);
}
@@ -550,7 +550,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
token("xyz", 1, 1), token("abc", 0, 3), token("def", 2, 1),
});
final Automaton expected =
- Operations.union(join(s2a("xyz"), SEP_A, HOLE_A, SEP_A, s2a("def")), s2a("abc"));
+ Operations.union(List.of(join(s2a("xyz"), SEP_A, HOLE_A, SEP_A, s2a("def")), s2a("abc")));
assertSameLanguage(expected, ts);
}
@@ -563,7 +563,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
});
final Automaton a1 = s2a("xyz");
final Automaton a2 = join("abc", "def", "ghi");
- assertSameLanguage(Operations.union(a1, a2), ts);
+ assertSameLanguage(Operations.union(List.of(a1, a2)), ts);
}
public void testToDot() throws Exception {
@@ -599,7 +599,7 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
new Token[] {
token("a", 1, 1), token("X", 0, 10),
});
- assertSameLanguage(Operations.union(s2a("a"), s2a("X")), ts);
+ assertSameLanguage(Operations.union(List.of(s2a("a"), s2a("X"))), ts);
}
/** Returns all paths */
@@ -659,8 +659,9 @@ public class TestGraphTokenizers extends BaseTokenStreamTestCase {
});
assertSameLanguage(
Operations.union(
- join(s2a("abc"), SEP_A, s2a("xyz")),
- join(s2a("abc"), SEP_A, HOLE_A, SEP_A, s2a("def"), SEP_A, s2a("ghi"))),
+ List.of(
+ join(s2a("abc"), SEP_A, s2a("xyz")),
+ join(s2a("abc"), SEP_A, HOLE_A, SEP_A, s2a("def"), SEP_A, s2a("ghi")))),
ts);
}
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestAutomatonQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestAutomatonQuery.java
index 4b10562de26..ce38a992893 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestAutomatonQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestAutomatonQuery.java
@@ -133,7 +133,8 @@ public class TestAutomatonQuery extends LuceneTestCase {
1,
Operations.determinize(
Automata.makeDecimalInterval(0, 2000, 0), Operations.DEFAULT_DETERMINIZE_WORK_LIMIT));
- assertAutomatonHits(2, Operations.union(Automata.makeChar('a'), Automata.makeChar('b')));
+ assertAutomatonHits(
+ 2, Operations.union(List.of(Automata.makeChar('a'), Automata.makeChar('b'))));
assertAutomatonHits(0, Operations.intersection(Automata.makeChar('a'), Automata.makeChar('b')));
assertAutomatonHits(
1,
@@ -151,7 +152,8 @@ public class TestAutomatonQuery extends LuceneTestCase {
AutomatonQuery a3 =
new AutomatonQuery(
newTerm("foobar"),
- Operations.concatenate(Automata.makeString("foo"), Automata.makeString("bar")));
+ Operations.concatenate(
+ List.of(Automata.makeString("foo"), Automata.makeString("bar"))));
// different than a1 (same term, but different language)
AutomatonQuery a4 = new AutomatonQuery(newTerm("foobar"), Automata.makeString("different"));
// different than a1 (different term, same language)
@@ -189,7 +191,7 @@ public class TestAutomatonQuery extends LuceneTestCase {
*/
public void testRewritePrefix() throws IOException {
Automaton pfx = Automata.makeString("do");
- Automaton prefixAutomaton = Operations.concatenate(pfx, Automata.makeAnyString());
+ Automaton prefixAutomaton = Operations.concatenate(List.of(pfx, Automata.makeAnyString()));
AutomatonQuery aq = new AutomatonQuery(newTerm("bogus"), prefixAutomaton);
assertEquals(3, automatonQueryNrHits(aq));
}
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestAutomaton.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestAutomaton.java
index 11ba6bee79c..b3adaad65d1 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestAutomaton.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestAutomaton.java
@@ -86,12 +86,14 @@ public class TestAutomaton extends LuceneTestCase {
Automaton a1 = Automata.makeString("foobar");
Automaton a2 =
Operations.removeDeadStates(
- Operations.concatenate(Automata.makeString("foo"), Automata.makeString("bar")));
+ Operations.concatenate(
+ List.of(Automata.makeString("foo"), Automata.makeString("bar"))));
assertTrue(AutomatonTestUtil.sameLanguage(a1, a2));
}
public void testCommonPrefixString() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("foobar"), Automata.makeAnyString());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("foobar"), Automata.makeAnyString()));
assertEquals("foobar", Operations.getCommonPrefix(a));
}
@@ -114,31 +116,36 @@ public class TestAutomaton extends LuceneTestCase {
public void testAlternatives() throws Exception {
Automaton a = Automata.makeChar('a');
Automaton c = Automata.makeChar('c');
- assertEquals("", Operations.getCommonPrefix(Operations.union(a, c)));
+ assertEquals("", Operations.getCommonPrefix(Operations.union(List.of(a, c))));
}
public void testCommonPrefixLeadingWildcard() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeAnyChar(), Automata.makeString("boo"));
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeAnyChar(), Automata.makeString("boo")));
assertEquals("", Operations.getCommonPrefix(a));
}
public void testCommonPrefixTrailingWildcard() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("boo"), Automata.makeAnyChar());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("boo"), Automata.makeAnyChar()));
assertEquals("boo", Operations.getCommonPrefix(a));
}
public void testCommonPrefixLeadingKleenStar() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeAnyString(), Automata.makeString("boo"));
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeAnyString(), Automata.makeString("boo")));
assertEquals("", Operations.getCommonPrefix(a));
}
public void testCommonPrefixTrailingKleenStar() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("boo"), Automata.makeAnyString());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("boo"), Automata.makeAnyString()));
assertEquals("boo", Operations.getCommonPrefix(a));
}
public void testCommonPrefixDeadStates() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeAnyString(), Automata.makeString("boo"));
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeAnyString(), Automata.makeString("boo")));
// reverse it twice, to create some dead states
// TODO: is it possible to fix reverse() to not create dead states?!
Automaton withDeadStates = Operations.reverse(Operations.reverse(a));
@@ -152,7 +159,8 @@ public class TestAutomaton extends LuceneTestCase {
}
public void testCommonPrefixRemoveDeadStates() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeAnyString(), Automata.makeString("boo"));
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeAnyString(), Automata.makeString("boo")));
// reverse it twice, to create some dead states
// TODO: is it possible to fix reverse() to not create dead states?!
Automaton withDeadStates = Operations.reverse(Operations.reverse(a));
@@ -201,12 +209,14 @@ public class TestAutomaton extends LuceneTestCase {
}
public void testCommonPrefixUnicode() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("boo😂😂😂"), Automata.makeAnyChar());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("boo😂😂😂"), Automata.makeAnyChar()));
assertEquals("boo😂😂😂", Operations.getCommonPrefix(a));
}
public void testConcatenate1() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("m"), Automata.makeAnyString());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("m"), Automata.makeAnyString()));
assertTrue(Operations.run(a, "m"));
assertTrue(Operations.run(a, "me"));
assertTrue(Operations.run(a, "me too"));
@@ -373,23 +383,26 @@ public class TestAutomaton extends LuceneTestCase {
}
public void testCommonSuffixTrailingWildcard() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("boo"), Automata.makeAnyChar());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("boo"), Automata.makeAnyChar()));
assertEquals(newBytesRef(), Operations.getCommonSuffixBytesRef(a));
}
public void testCommonSuffixLeadingKleenStar() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeAnyString(), Automata.makeString("boo"));
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeAnyString(), Automata.makeString("boo")));
assertEquals(newBytesRef("boo"), Operations.getCommonSuffixBytesRef(a));
}
public void testCommonSuffixTrailingKleenStar() throws Exception {
- Automaton a = Operations.concatenate(Automata.makeString("boo"), Automata.makeAnyString());
+ Automaton a =
+ Operations.concatenate(List.of(Automata.makeString("boo"), Automata.makeAnyString()));
assertEquals(newBytesRef(), Operations.getCommonSuffixBytesRef(a));
}
public void testCommonSuffixUnicode() throws Exception {
Automaton a =
- Operations.concatenate(Automata.makeAnyString(), Automata.makeString("boo😂😂😂"));
+ Operations.concatenate(List.of(Automata.makeAnyString(), Automata.makeString("boo😂😂😂")));
Automaton binary = new UTF32ToUTF8().convert(a);
assertEquals(newBytesRef("boo😂😂😂"), Operations.getCommonSuffixBytesRef(binary));
}
@@ -702,10 +715,10 @@ public class TestAutomaton extends LuceneTestCase {
public void testConcatEmpty() throws Exception {
// If you concat empty automaton to anything the result should still be empty:
- Automaton a = Operations.concatenate(Automata.makeEmpty(), Automata.makeString("foo"));
+ Automaton a = Operations.concatenate(List.of(Automata.makeEmpty(), Automata.makeString("foo")));
assertEquals(new HashSet<IntsRef>(), TestOperations.getFiniteStrings(a));
- a = Operations.concatenate(Automata.makeString("foo"), Automata.makeEmpty());
+ a = Operations.concatenate(List.of(Automata.makeString("foo"), Automata.makeEmpty()));
assertEquals(new HashSet<IntsRef>(), TestOperations.getFiniteStrings(a));
}
@@ -778,12 +791,12 @@ public class TestAutomaton extends LuceneTestCase {
if (VERBOSE) {
System.out.println(" randomNoOp: concat empty string");
}
- return Operations.concatenate(a, Automata.makeEmptyString());
+ return Operations.concatenate(List.of(a, Automata.makeEmptyString()));
case 5:
if (VERBOSE) {
System.out.println(" randomNoOp: union empty automaton");
}
- return Operations.union(a, Automata.makeEmpty());
+ return Operations.union(List.of(a, Automata.makeEmpty()));
case 6:
if (VERBOSE) {
System.out.println(" randomNoOp: do nothing!");
@@ -881,9 +894,9 @@ public class TestAutomaton extends LuceneTestCase {
}
terms = newTerms;
boolean wasDeterministic = a.isDeterministic();
- a = Operations.concatenate(Automata.makeString(prefix.utf8ToString()), a);
+ a = Operations.concatenate(List.of(Automata.makeString(prefix.utf8ToString()), a));
if (wasDeterministic) {
- assertTrue(a.isDeterministic());
+ assertEquals(wasDeterministic, a.isDeterministic());
}
}
break;
@@ -903,7 +916,7 @@ public class TestAutomaton extends LuceneTestCase {
newTerms.add(newTerm.toBytesRef());
}
terms = newTerms;
- a = Operations.concatenate(a, Automata.makeString(suffix.utf8ToString()));
+ a = Operations.concatenate(List.of(a, Automata.makeString(suffix.utf8ToString())));
}
break;
@@ -941,7 +954,7 @@ public class TestAutomaton extends LuceneTestCase {
}
terms.addAll(newTerms);
Automaton newA = unionTerms(newTerms);
- a = Operations.union(a, newA);
+ a = Operations.union(List.of(a, newA));
}
break;
@@ -1114,7 +1127,7 @@ public class TestAutomaton extends LuceneTestCase {
System.out.println(
" op=union interval min=" + min + " max=" + max + " digits=" + digits);
}
- a = Operations.union(a, Automata.makeDecimalInterval(min, max, digits));
+ a = Operations.union(List.of(a, Automata.makeDecimalInterval(min, max, digits)));
StringBuilder b = new StringBuilder();
for (int i = 0; i < digits; i++) {
b.append('0');
@@ -1143,7 +1156,7 @@ public class TestAutomaton extends LuceneTestCase {
if (VERBOSE) {
System.out.println(" op=add the empty string");
}
- a = Operations.union(a, Automata.makeEmptyString());
+ a = Operations.union(List.of(a, Automata.makeEmptyString()));
terms.add(newBytesRef());
break;
@@ -1170,7 +1183,7 @@ public class TestAutomaton extends LuceneTestCase {
if (VERBOSE) {
System.out.println(" do suffix");
}
- a = Operations.concatenate(a, randomNoOp(a2));
+ a = Operations.concatenate(List.of(a, randomNoOp(a2)));
BytesRefBuilder newTerm = new BytesRefBuilder();
for (BytesRef term : terms) {
for (BytesRef suffix : addTerms) {
@@ -1184,7 +1197,7 @@ public class TestAutomaton extends LuceneTestCase {
if (VERBOSE) {
System.out.println(" do prefix");
}
- a = Operations.concatenate(randomNoOp(a2), a);
+ a = Operations.concatenate(List.of(randomNoOp(a2), a));
BytesRefBuilder newTerm = new BytesRefBuilder();
for (BytesRef term : terms) {
for (BytesRef prefix : addTerms) {
@@ -1707,7 +1720,7 @@ public class TestAutomaton extends LuceneTestCase {
}
public void testMakeCharSetTwo() {
- Automaton expected = Operations.union(Automata.makeChar('a'), Automata.makeChar('A'));
+ Automaton expected = Operations.union(List.of(Automata.makeChar('a'), Automata.makeChar('A')));
Automaton actual = Automata.makeCharSet(new int[] {'a', 'A'});
assertTrue(AutomatonTestUtil.sameLanguage(expected, actual));
assertTrue(actual.isDeterministic());
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestDeterminism.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestDeterminism.java
index e69568d3873..b9aa90df876 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestDeterminism.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestDeterminism.java
@@ -18,6 +18,7 @@ package org.apache.lucene.util.automaton;
import static org.apache.lucene.util.automaton.Operations.DEFAULT_DETERMINIZE_WORK_LIMIT;
+import java.util.List;
import org.apache.lucene.tests.util.LuceneTestCase;
import org.apache.lucene.tests.util.automaton.AutomatonTestUtil;
@@ -58,7 +59,8 @@ public class TestDeterminism extends LuceneTestCase {
// a union a = a
equivalent =
Operations.determinize(
- Operations.removeDeadStates(Operations.union(a, a)), DEFAULT_DETERMINIZE_WORK_LIMIT);
+ Operations.removeDeadStates(Operations.union(List.of(a, a))),
+ DEFAULT_DETERMINIZE_WORK_LIMIT);
assertTrue(AutomatonTestUtil.sameLanguage(a, equivalent));
// a intersect a = a
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestFiniteStringsIterator.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestFiniteStringsIterator.java
index 8070d7af479..b8d16ac9b2e 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestFiniteStringsIterator.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestFiniteStringsIterator.java
@@ -96,7 +96,8 @@ public class TestFiniteStringsIterator extends LuceneTestCase {
/** Basic test for getFiniteStrings */
public void testFiniteStringsBasic() {
- Automaton a = Operations.union(Automata.makeString("dog"), Automata.makeString("duck"));
+ Automaton a =
+ Operations.union(List.of(Automata.makeString("dog"), Automata.makeString("duck")));
a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
FiniteStringsIterator iterator = new FiniteStringsIterator(a);
List<IntsRef> actual = getFiniteStrings(iterator);
@@ -117,7 +118,7 @@ public class TestFiniteStringsIterator extends LuceneTestCase {
TestUtil.randomFixedLengthUnicodeString(random(), chars, 0, chars.length);
String bigString2 = new String(chars);
Automaton a =
- Operations.union(Automata.makeString(bigString1), Automata.makeString(bigString2));
+ Operations.union(List.of(Automata.makeString(bigString1), Automata.makeString(bigString2)));
FiniteStringsIterator iterator = new FiniteStringsIterator(a);
List<IntsRef> actual = getFiniteStrings(iterator);
assertEquals(2, actual.size());
@@ -149,7 +150,7 @@ public class TestFiniteStringsIterator extends LuceneTestCase {
}
public void testShortAccept() {
- Automaton a = Operations.union(Automata.makeString("x"), Automata.makeString("xy"));
+ Automaton a = Operations.union(List.of(Automata.makeString("x"), Automata.makeString("xy")));
a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
FiniteStringsIterator iterator = new FiniteStringsIterator(a);
List<IntsRef> actual = getFiniteStrings(iterator);
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java
index bc6d268c15e..fc6a04e80c3 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestLevenshteinAutomata.java
@@ -16,8 +16,6 @@
*/
package org.apache.lucene.util.automaton;
-import static org.apache.lucene.util.automaton.Operations.DEFAULT_DETERMINIZE_WORK_LIMIT;
-
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.tests.util.LuceneTestCase;
@@ -134,15 +132,10 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
* Return an automaton that accepts all 1-character insertions, deletions, and substitutions of s.
*/
private Automaton naiveLev1(String s) {
- Automaton a = Automata.makeString(s);
- a = Operations.union(a, insertionsOf(s));
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- a = Operations.union(a, deletionsOf(s));
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- a = Operations.union(a, substitutionsOf(s));
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
-
- return a;
+ return Operations.determinize(
+ Operations.union(
+ List.of(Automata.makeString(s), insertionsOf(s), deletionsOf(s), substitutionsOf(s))),
+ Operations.DEFAULT_DETERMINIZE_WORK_LIMIT);
}
/**
@@ -150,10 +143,15 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
* transpositions of s.
*/
private Automaton naiveLev1T(String s) {
- Automaton a = naiveLev1(s);
- a = Operations.union(a, transpositionsOf(s));
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- return a;
+ return Operations.determinize(
+ Operations.union(
+ List.of(
+ Automata.makeString(s),
+ insertionsOf(s),
+ deletionsOf(s),
+ substitutionsOf(s),
+ transpositionsOf(s))),
+ Operations.DEFAULT_DETERMINIZE_WORK_LIMIT);
}
/** Return an automaton that accepts all 1-character insertions of s (inserting one character) */
@@ -161,15 +159,13 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
List<Automaton> list = new ArrayList<>();
for (int i = 0; i <= s.length(); i++) {
- Automaton a = Automata.makeString(s.substring(0, i));
- a = Operations.concatenate(a, Automata.makeAnyChar());
- a = Operations.concatenate(a, Automata.makeString(s.substring(i)));
- list.add(a);
+ Automaton pre = Automata.makeString(s.substring(0, i));
+ Automaton middle = Automata.makeAnyChar();
+ Automaton post = Automata.makeString(s.substring(i));
+ list.add(Operations.concatenate(List.of(pre, middle, post)));
}
- Automaton a = Operations.union(list);
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- return a;
+ return Operations.union(list);
}
/** Return an automaton that accepts all 1-character deletions of s (deleting one character). */
@@ -177,14 +173,12 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
List<Automaton> list = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
- Automaton a = Automata.makeString(s.substring(0, i));
- a = Operations.concatenate(a, Automata.makeString(s.substring(i + 1)));
- list.add(a);
+ Automaton pre = Automata.makeString(s.substring(0, i));
+ Automaton post = Automata.makeString(s.substring(i + 1));
+ list.add(Operations.concatenate(List.of(pre, post)));
}
- Automaton a = Operations.union(list);
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- return a;
+ return Operations.union(list);
}
/**
@@ -194,15 +188,13 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
List<Automaton> list = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
- Automaton a = Automata.makeString(s.substring(0, i));
- a = Operations.concatenate(a, Automata.makeAnyChar());
- a = Operations.concatenate(a, Automata.makeString(s.substring(i + 1)));
- list.add(a);
+ Automaton pre = Automata.makeString(s.substring(0, i));
+ Automaton middle = Automata.makeAnyChar();
+ Automaton post = Automata.makeString(s.substring(i + 1));
+ list.add(Operations.concatenate(List.of(pre, middle, post)));
}
- Automaton a = Operations.union(list);
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- return a;
+ return Operations.union(list);
}
/**
@@ -224,9 +216,7 @@ public class TestLevenshteinAutomata extends LuceneTestCase {
list.add(Automata.makeString(st));
}
}
- Automaton a = Operations.union(list);
- a = MinimizationOperations.minimize(a, DEFAULT_DETERMINIZE_WORK_LIMIT);
- return a;
+ return Operations.union(list);
}
private void assertBruteForce(String input, Automaton dfa, int distance) {
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestLimitedFiniteStringsIterator.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestLimitedFiniteStringsIterator.java
index 3d69bcde4ec..4b0873812f3 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestLimitedFiniteStringsIterator.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestLimitedFiniteStringsIterator.java
@@ -78,7 +78,7 @@ public class TestLimitedFiniteStringsIterator extends LuceneTestCase {
}
public void testLimit() {
- Automaton a = Operations.union(Automata.makeString("foo"), Automata.makeString("bar"));
+ Automaton a = Operations.union(List.of(Automata.makeString("foo"), Automata.makeString("bar")));
// Test without limit
FiniteStringsIterator withoutLimit = new LimitedFiniteStringsIterator(a, -1);
@@ -90,7 +90,7 @@ public class TestLimitedFiniteStringsIterator extends LuceneTestCase {
}
public void testSize() {
- Automaton a = Operations.union(Automata.makeString("foo"), Automata.makeString("bar"));
+ Automaton a = Operations.union(List.of(Automata.makeString("foo"), Automata.makeString("bar")));
LimitedFiniteStringsIterator iterator = new LimitedFiniteStringsIterator(a, -1);
List<IntsRef> actual = getFiniteStrings(iterator);
assertEquals(2, actual.size());
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestNFARunAutomaton.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestNFARunAutomaton.java
index c577c1de8de..338916f2f81 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestNFARunAutomaton.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestNFARunAutomaton.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -172,7 +173,7 @@ public class TestNFARunAutomaton extends LuceneTestCase {
if (a == null) {
a = Automata.makeString(term);
} else {
- a = Operations.union(a, Automata.makeString(term));
+ a = Operations.union(List.of(a, Automata.makeString(term)));
}
}
if (a.isDeterministic()) {
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestOperations.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestOperations.java
index 3de263030d6..c6fde722290 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestOperations.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestOperations.java
@@ -65,8 +65,8 @@ public class TestOperations extends LuceneTestCase {
/** Test concatenation with empty language returns empty */
public void testEmptyLanguageConcatenate() {
- Automaton a = Automata.makeString("a");
- Automaton concat = Operations.concatenate(a, Automata.makeEmpty());
+ Automaton concat =
+ Operations.concatenate(List.of(Automata.makeString("a"), Automata.makeEmpty()));
assertTrue(Operations.isEmpty(concat));
}
@@ -111,9 +111,10 @@ public class TestOperations extends LuceneTestCase {
Automaton singleton = Automata.makeString("");
Automaton expandedSingleton = singleton;
// an NFA (two transitions for 't' from initial state)
- Automaton nfa = Operations.union(Automata.makeString("this"), Automata.makeString("three"));
- Automaton concat1 = Operations.concatenate(expandedSingleton, nfa);
- Automaton concat2 = Operations.concatenate(singleton, nfa);
+ Automaton nfa =
+ Operations.union(List.of(Automata.makeString("this"), Automata.makeString("three")));
+ Automaton concat1 = Operations.concatenate(List.of(expandedSingleton, nfa));
+ Automaton concat2 = Operations.concatenate(List.of(singleton, nfa));
assertFalse(concat2.isDeterministic());
assertTrue(
AutomatonTestUtil.sameLanguage(
@@ -167,7 +168,7 @@ public class TestOperations extends LuceneTestCase {
TestUtil.randomFixedLengthUnicodeString(random(), chars, 0, chars.length);
String bigString2 = new String(chars);
Automaton a =
- Operations.union(Automata.makeString(bigString1), Automata.makeString(bigString2));
+ Operations.union(List.of(Automata.makeString(bigString1), Automata.makeString(bigString2)));
IllegalArgumentException exc =
expectThrows(IllegalArgumentException.class, () -> AutomatonTestUtil.isFinite(a));
assertTrue(exc.getMessage().contains("input automaton is too large"));
@@ -185,27 +186,31 @@ public class TestOperations extends LuceneTestCase {
Automaton tricky =
Operations.repeat(
Operations.union(
- Automata.makeCharRange(Character.MIN_CODE_POINT, 100),
- Automata.makeCharRange(101, Character.MAX_CODE_POINT)));
+ List.of(
+ Automata.makeCharRange(Character.MIN_CODE_POINT, 100),
+ Automata.makeCharRange(101, Character.MAX_CODE_POINT))));
assertTrue(Operations.isTotal(tricky));
// not total, but close
Automaton tricky2 =
Operations.repeat(
Operations.union(
- Automata.makeCharRange(Character.MIN_CODE_POINT + 1, 100),
- Automata.makeCharRange(101, Character.MAX_CODE_POINT)));
+ List.of(
+ Automata.makeCharRange(Character.MIN_CODE_POINT + 1, 100),
+ Automata.makeCharRange(101, Character.MAX_CODE_POINT))));
assertFalse(Operations.isTotal(tricky2));
Automaton tricky3 =
Operations.repeat(
Operations.union(
- Automata.makeCharRange(Character.MIN_CODE_POINT, 99),
- Automata.makeCharRange(101, Character.MAX_CODE_POINT)));
+ List.of(
+ Automata.makeCharRange(Character.MIN_CODE_POINT, 99),
+ Automata.makeCharRange(101, Character.MAX_CODE_POINT))));
assertFalse(Operations.isTotal(tricky3));
Automaton tricky4 =
Operations.repeat(
Operations.union(
- Automata.makeCharRange(Character.MIN_CODE_POINT, 100),
- Automata.makeCharRange(101, Character.MAX_CODE_POINT - 1)));
+ List.of(
+ Automata.makeCharRange(Character.MIN_CODE_POINT, 100),
+ Automata.makeCharRange(101, Character.MAX_CODE_POINT - 1))));
assertFalse(Operations.isTotal(tricky4));
}
@@ -327,7 +332,7 @@ public class TestOperations extends LuceneTestCase {
assertTrue(AutomatonTestUtil.sameLanguage(abs, Operations.repeat(ab)));
assertSame(abs, Operations.repeat(abs));
- Automaton absThenC = Operations.concatenate(abs, Automata.makeChar('c'));
+ Automaton absThenC = Operations.concatenate(List.of(abs, Automata.makeChar('c')));
Automaton absThenCs = new Automaton();
absThenCs.createState();
absThenCs.createState();
diff --git a/lucene/core/src/test/org/apache/lucene/util/automaton/TestRegExpParsing.java b/lucene/core/src/test/org/apache/lucene/util/automaton/TestRegExpParsing.java
index e0aec1e5351..51a14761d38 100644
--- a/lucene/core/src/test/org/apache/lucene/util/automaton/TestRegExpParsing.java
+++ b/lucene/core/src/test/org/apache/lucene/util/automaton/TestRegExpParsing.java
@@ -17,6 +17,7 @@
package org.apache.lucene.util.automaton;
import java.io.IOException;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.tests.util.LuceneTestCase;
@@ -74,7 +75,7 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton actual = re.toAutomaton();
assertTrue(actual.isDeterministic());
- Automaton expected = Operations.union(Automata.makeChar('c'), Automata.makeChar('C'));
+ Automaton expected = Operations.union(List.of(Automata.makeChar('c'), Automata.makeChar('C')));
assertSameLanguage(expected, actual);
}
@@ -100,7 +101,7 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton actual = re.toAutomaton();
assertTrue(actual.isDeterministic());
- Automaton expected = Operations.union(Automata.makeChar('c'), Automata.makeChar('C'));
+ Automaton expected = Operations.union(List.of(Automata.makeChar('c'), Automata.makeChar('C')));
assertSameLanguage(expected, actual);
}
@@ -146,7 +147,8 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton expected =
Operations.union(
- Automata.makeCharRange(0, 'b'), Automata.makeCharRange('d', Integer.MAX_VALUE));
+ List.of(
+ Automata.makeCharRange(0, 'b'), Automata.makeCharRange('d', Integer.MAX_VALUE)));
assertSameLanguage(expected, actual);
}
@@ -196,7 +198,8 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton expected =
Operations.union(
- Automata.makeCharRange(0, 'a'), Automata.makeCharRange('e', Integer.MAX_VALUE));
+ List.of(
+ Automata.makeCharRange(0, 'a'), Automata.makeCharRange('e', Integer.MAX_VALUE)));
assertSameLanguage(expected, actual);
}
@@ -245,10 +248,13 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton actual = re.toAutomaton();
assertTrue(actual.isDeterministic());
- Automaton expected = Automata.makeChar(' ');
- expected = Operations.union(expected, Automata.makeChar('\n'));
- expected = Operations.union(expected, Automata.makeChar('\r'));
- expected = Operations.union(expected, Automata.makeChar('\t'));
+ Automaton expected =
+ Operations.union(
+ List.of(
+ Automata.makeChar(' '),
+ Automata.makeChar('\n'),
+ Automata.makeChar('\r'),
+ Automata.makeChar('\t')));
assertSameLanguage(expected, actual);
}
@@ -287,10 +293,13 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton actual = re.toAutomaton();
assertTrue(actual.isDeterministic());
- Automaton expected = Automata.makeCharRange('a', 'z');
- expected = Operations.union(expected, Automata.makeCharRange('A', 'Z'));
- expected = Operations.union(expected, Automata.makeCharRange('0', '9'));
- expected = Operations.union(expected, Automata.makeChar('_'));
+ Automaton expected =
+ Operations.union(
+ List.of(
+ Automata.makeCharRange('a', 'z'),
+ Automata.makeCharRange('A', 'Z'),
+ Automata.makeCharRange('0', '9'),
+ Automata.makeChar('_')));
assertSameLanguage(expected, actual);
}
@@ -544,11 +553,10 @@ public class TestRegExpParsing extends LuceneTestCase {
Automaton actual = re.toAutomaton();
assertTrue(actual.isDeterministic());
- Automaton c1 = Operations.union(Automata.makeChar('b'), Automata.makeChar('B'));
- Automaton c2 = Operations.union(Automata.makeChar('o'), Automata.makeChar('O'));
+ Automaton c1 = Operations.union(List.of(Automata.makeChar('b'), Automata.makeChar('B')));
+ Automaton c2 = Operations.union(List.of(Automata.makeChar('o'), Automata.makeChar('O')));
- Automaton expected = Operations.concatenate(c1, c2);
- expected = Operations.concatenate(expected, c2);
+ Automaton expected = Operations.concatenate(List.of(c1, c2, c2));
assertSameLanguage(expected, actual);
}
@@ -587,7 +595,8 @@ public class TestRegExpParsing extends LuceneTestCase {
assertTrue(actual.isDeterministic());
Automaton expected =
- Operations.concatenate(Automata.makeCharRange('b', 'c'), Automata.makeCharRange('e', 'f'));
+ Operations.concatenate(
+ List.of(Automata.makeCharRange('b', 'c'), Automata.makeCharRange('e', 'f')));
assertSameLanguage(expected, actual);
}
@@ -641,7 +650,8 @@ public class TestRegExpParsing extends LuceneTestCase {
assertTrue(actual.isDeterministic());
Automaton expected =
- Operations.union(Automata.makeCharRange('b', 'c'), Automata.makeCharRange('e', 'f'));
+ Operations.union(
+ List.of(Automata.makeCharRange('b', 'c'), Automata.makeCharRange('e', 'f')));
assertSameLanguage(expected, actual);
}
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
index 496d3b9232d..71418f231c8 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
@@ -195,9 +195,10 @@ public class ContextQuery extends CompletionQuery implements Accountable {
// include the SEP_LABEL in the query as well
Automaton optionalSepLabel =
Operations.optional(Automata.makeChar(ConcatenateGraphFilter.SEP_LABEL));
- Automaton prefixAutomaton = Operations.concatenate(optionalSepLabel, innerAutomaton);
Automaton contextsAutomaton =
- Operations.concatenate(toContextAutomaton(contexts, matchAllContexts), prefixAutomaton);
+ Operations.concatenate(
+ List.of(
+ toContextAutomaton(contexts, matchAllContexts), optionalSepLabel, innerAutomaton));
contextsAutomaton =
Operations.determinize(contextsAutomaton, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT);
@@ -230,18 +231,19 @@ public class ContextQuery extends CompletionQuery implements Accountable {
final Automaton matchAllAutomaton = Operations.repeat(Automata.makeAnyString());
final Automaton sep = Automata.makeChar(ContextSuggestField.CONTEXT_SEPARATOR);
if (matchAllContexts || contexts.size() == 0) {
- return Operations.concatenate(matchAllAutomaton, sep);
+ return Operations.concatenate(List.of(matchAllAutomaton, sep));
} else {
List<Automaton> automataList = new ArrayList<>();
for (Map.Entry<IntsRef, ContextMetaData> entry : contexts.entrySet()) {
final ContextMetaData contextMetaData = entry.getValue();
final IntsRef ref = entry.getKey();
- Automaton contextAutomaton = Automata.makeString(ref.ints, ref.offset, ref.length);
+ final List<Automaton> contextAutomaton = new ArrayList<>();
+ contextAutomaton.add(Automata.makeString(ref.ints, ref.offset, ref.length));
if (contextMetaData.exact == false) {
- contextAutomaton = Operations.concatenate(contextAutomaton, matchAllAutomaton);
+ contextAutomaton.add(matchAllAutomaton);
}
- contextAutomaton = Operations.concatenate(contextAutomaton, sep);
- automataList.add(contextAutomaton);
+ contextAutomaton.add(sep);
+ automataList.add(Operations.concatenate(contextAutomaton));
}
Automaton contextsAutomaton = Operations.union(automataList);
return contextsAutomaton;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/util/automaton/AutomatonTestUtil.java b/lucene/test-framework/src/java/org/apache/lucene/tests/util/automaton/AutomatonTestUtil.java
index 5a308f37133..686c12323a4 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/tests/util/automaton/AutomatonTestUtil.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/tests/util/automaton/AutomatonTestUtil.java
@@ -285,9 +285,9 @@ public class AutomatonTestUtil {
// combine them in random ways
switch (random.nextInt(4)) {
case 0:
- return Operations.concatenate(a1, a2);
+ return Operations.concatenate(List.of(a1, a2));
case 1:
- return Operations.union(a1, a2);
+ return Operations.union(List.of(a1, a2));
case 2:
return Operations.intersection(a1, a2);
default: