From 948970be58d9e966242242632cda7d58c7f24c29 Mon Sep 17 00:00:00 2001 From: Patrick Zhai Date: Wed, 27 Dec 2023 22:49:35 -0800 Subject: [PATCH] Fix bug where NFARunAutomaton#getTransition does not set Transition correctly (#12909) --- .../util/automaton/NFARunAutomaton.java | 13 ++++--- .../util/automaton/TestNFARunAutomaton.java | 34 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/NFARunAutomaton.java b/lucene/core/src/java/org/apache/lucene/util/automaton/NFARunAutomaton.java index 6ff52baebbc..02c14ed457d 100644 --- a/lucene/core/src/java/org/apache/lucene/util/automaton/NFARunAutomaton.java +++ b/lucene/core/src/java/org/apache/lucene/util/automaton/NFARunAutomaton.java @@ -193,8 +193,12 @@ public class NFARunAutomaton implements ByteRunnable, TransitionAccessor { // numTransitions times } assert dStates[t.source].transitions[t.transitionUpto] != NOT_COMPUTED; - t.dest = dStates[t.source].transitions[t.transitionUpto]; + setTransitionAccordingly(t); + } + + private void setTransitionAccordingly(Transition t) { + t.dest = dStates[t.source].transitions[t.transitionUpto]; t.min = points[t.transitionUpto]; if (t.transitionUpto == points.length - 1) { t.max = alphabetSize - 1; @@ -222,12 +226,7 @@ public class NFARunAutomaton implements ByteRunnable, TransitionAccessor { } assert outgoingTransitions == index; - t.min = points[t.transitionUpto]; - if (t.transitionUpto == points.length - 1) { - t.max = alphabetSize - 1; - } else { - t.max = points[t.transitionUpto + 1] - 1; - } + setTransitionAccordingly(t); } private class DState { 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 f838a26b180..3ae55ac46d2 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 @@ -73,6 +73,40 @@ public class TestNFARunAutomaton extends LuceneTestCase { } } + public void testRandomAccessTransition() { + Automaton nfa = new RegExp(AutomatonTestUtil.randomRegexp(random()), RegExp.NONE).toAutomaton(); + while (nfa.isDeterministic()) { + nfa = new RegExp(AutomatonTestUtil.randomRegexp(random()), RegExp.NONE).toAutomaton(); + } + NFARunAutomaton runAutomaton1, runAutomaton2; + runAutomaton1 = new NFARunAutomaton(nfa); + runAutomaton2 = new NFARunAutomaton(nfa); + assertRandomAccessTransition(runAutomaton1, runAutomaton2, 0, new HashSet<>()); + } + + private void assertRandomAccessTransition( + NFARunAutomaton automaton1, NFARunAutomaton automaton2, int state, Set visited) { + if (visited.contains(state)) { + return; + } + visited.add(state); + + Transition t1 = new Transition(); + Transition t2 = new Transition(); + automaton1.initTransition(state, t1); + if (random().nextBoolean()) { + // init is not really necessary for t2 + automaton2.initTransition(state, t2); + } + int numStates = automaton2.getNumTransitions(state); + for (int i = 0; i < numStates; i++) { + automaton1.getNextTransition(t1); + automaton2.getTransition(state, i, t2); + assertEquals(t1.toString(), t2.toString()); + assertRandomAccessTransition(automaton1, automaton2, t1.dest, visited); + } + } + public void testRandomAutomatonQuery() throws IOException { final int docNum = 50; final int automatonNum = 50;