Index: lucene/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java =================================================================== --- lucene/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java (revision 1025979) +++ lucene/src/java/org/apache/lucene/util/automaton/MinimizationOperations.java (working copy) @@ -56,11 +56,6 @@ //if (a.hash_code == 0) a.hash_code = 1; } - private static void initialize(ArrayList list, int size) { - for (int i = 0; i < size; i++) - list.add(null); - } - /** * Minimizes the given automaton using Hopcroft's algorithm. */ @@ -73,66 +68,55 @@ } a.totalize(); - int[] sigma = a.getStartPoints(); + final int[] sigma = a.getStartPoints(); + // initialize data structures - ArrayList>> reverse = new ArrayList>>(); final State[] states = a.getNumberedStates(); - + @SuppressWarnings("unchecked") final LinkedList[][] reverse = + (LinkedList[][]) new LinkedList[states.length][sigma.length]; + @SuppressWarnings("unchecked") final LinkedList[] partition = + (LinkedList[]) new LinkedList[states.length]; + @SuppressWarnings("unchecked") final ArrayList[] splitblock = + (ArrayList[]) new ArrayList[states.length]; + final int[] block = new int[states.length]; + final StateList[][] active = new StateList[states.length][sigma.length]; + final StateListNode[][] active2 = new StateListNode[states.length][sigma.length]; + final LinkedList pending = new LinkedList(); + final boolean[][] pending2 = new boolean[sigma.length][states.length]; + final ArrayList split = new ArrayList(); + final boolean[] split2 = new boolean[states.length]; + final ArrayList refine = new ArrayList(); + final boolean[] refine2 = new boolean[states.length]; for (int q = 0; q < states.length; q++) { - ArrayList> v = new ArrayList>(); - initialize(v, sigma.length); - reverse.add(v); - } - boolean[][] reverse_nonempty = new boolean[states.length][sigma.length]; - ArrayList> partition = new ArrayList>(); - initialize(partition, states.length); - int[] block = new int[states.length]; - StateList[][] active = new StateList[states.length][sigma.length]; - StateListNode[][] active2 = new StateListNode[states.length][sigma.length]; - LinkedList pending = new LinkedList(); - boolean[][] pending2 = new boolean[sigma.length][states.length]; - ArrayList split = new ArrayList(); - boolean[] split2 = new boolean[states.length]; - ArrayList refine = new ArrayList(); - boolean[] refine2 = new boolean[states.length]; - ArrayList> splitblock = new ArrayList>(); - initialize(splitblock, states.length); - for (int q = 0; q < states.length; q++) { - splitblock.set(q, new ArrayList()); - partition.set(q, new LinkedList()); + splitblock[q] = new ArrayList(); + partition[q] = new LinkedList(); for (int x = 0; x < sigma.length; x++) { - reverse.get(q).set(x, new LinkedList()); active[q][x] = new StateList(); } } // find initial partition and reverse edges for (int q = 0; q < states.length; q++) { - State qq = states[q]; - int j; - if (qq.accept) j = 0; - else j = 1; - partition.get(j).add(qq); + final State qq = states[q]; + final int j = qq.accept ? 0 : 1; + partition[j].add(qq); block[qq.number] = j; for (int x = 0; x < sigma.length; x++) { - int y = sigma[x]; - State p = qq.step(y); - reverse.get(p.number).get(x).add(qq); - reverse_nonempty[p.number][x] = true; + final LinkedList[] r = + reverse[qq.step(sigma[x]).number]; + if (r[x] == null) + r[x] = new LinkedList(); + r[x].add(qq); } } // initialize active sets for (int j = 0; j <= 1; j++) for (int x = 0; x < sigma.length; x++) - for (State qq : partition.get(j)) - if (reverse_nonempty[qq.number][x]) active2[qq.number][x] = active[j][x] - .add(qq); + for (State qq : partition[j]) + if (reverse[qq.number][x] != null) + active2[qq.number][x] = active[j][x].add(qq); // initialize pending for (int x = 0; x < sigma.length; x++) { - int a0 = active[0][x].size; - int a1 = active[1][x].size; - int j; - if (a0 <= a1) j = 0; - else j = 1; + final int j = (active[0][x].size <= active[1][x].size) ? 0 : 1; pending.add(new IntPair(j, x)); pending2[x][j] = true; } @@ -140,33 +124,36 @@ int k = 2; while (!pending.isEmpty()) { IntPair ip = pending.removeFirst(); - int p = ip.n1; - int x = ip.n2; + final int p = ip.n1; + final int x = ip.n2; pending2[x][p] = false; // find states that need to be split off their blocks - for (StateListNode m = active[p][x].first; m != null; m = m.next) - for (State s : reverse.get(m.q.number).get(x)) + for (StateListNode m = active[p][x].first; m != null; m = m.next) { + final LinkedList r = reverse[m.q.number][x]; + if (r != null) for (State s : r) { if (!split2[s.number]) { split2[s.number] = true; split.add(s); - int j = block[s.number]; - splitblock.get(j).add(s); + final int j = block[s.number]; + splitblock[j].add(s); if (!refine2[j]) { refine2[j] = true; refine.add(j); } } + } + } // refine blocks for (int j : refine) { - if (splitblock.get(j).size() < partition.get(j).size()) { - LinkedList b1 = partition.get(j); - LinkedList b2 = partition.get(k); - for (State s : splitblock.get(j)) { + if (splitblock[j].size() < partition[j].size()) { + final LinkedList b1 = partition[j]; + final LinkedList b2 = partition[k]; + for (State s : splitblock[j]) { b1.remove(s); b2.add(s); block[s.number] = k; for (int c = 0; c < sigma.length; c++) { - StateListNode sn = active2[s.number][c]; + final StateListNode sn = active2[s.number][c]; if (sn != null && sn.sl == active[j][c]) { sn.remove(); active2[s.number][c] = active[k][c].add(s); @@ -175,8 +162,8 @@ } // update pending for (int c = 0; c < sigma.length; c++) { - int aj = active[j][c].size; - int ak = active[k][c].size; + final int aj = active[j][c].size; + final int ak = active[k][c].size; if (!pending2[c][j] && 0 < aj && aj <= ak) { pending2[c][j] = true; pending.add(new IntPair(j, c)); @@ -187,10 +174,10 @@ } k++; } - for (State s : splitblock.get(j)) + for (State s : splitblock[j]) split2[s.number] = false; refine2[j] = false; - splitblock.get(j).clear(); + splitblock[j].clear(); } split.clear(); refine.clear(); @@ -198,9 +185,9 @@ // make a new state for each equivalence class, set initial state State[] newstates = new State[k]; for (int n = 0; n < newstates.length; n++) { - State s = new State(); + final State s = new State(); newstates[n] = s; - for (State q : partition.get(n)) { + for (State q : partition[n]) { if (q == a.initial) a.initial = s; s.accept = q.accept; s.number = q.number; // select representative @@ -209,7 +196,7 @@ } // build transitions and set acceptance for (int n = 0; n < newstates.length; n++) { - State s = newstates[n]; + final State s = newstates[n]; s.accept = states[s.number].accept; for (Transition t : states[s.number].getTransitions()) s.addTransition(new Transition(t.min, t.max, newstates[t.to.number]));