diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/FST.java b/lucene/core/src/java/org/apache/lucene/util/fst/FST.java index a3b85cf5e31..2f67c300f97 100644 --- a/lucene/core/src/java/org/apache/lucene/util/fst/FST.java +++ b/lucene/core/src/java/org/apache/lucene/util/fst/FST.java @@ -746,7 +746,7 @@ public final class FST implements Accountable { } } - public Arc readFirstRealTargetArc(long nodeAddress, Arc arc, final BytesReader in) + private void readFirstArcInfo(long nodeAddress, Arc arc, final BytesReader in) throws IOException { in.setPosition(nodeAddress); // System.out.println(" flags=" + arc.flags); @@ -770,7 +770,11 @@ public final class FST implements Accountable { arc.nextArc = nodeAddress; arc.bytesPerArc = 0; } + } + public Arc readFirstRealTargetArc(long nodeAddress, Arc arc, final BytesReader in) + throws IOException { + readFirstArcInfo(nodeAddress, arc, in); return readNextRealArc(arc, in); } @@ -1081,22 +1085,30 @@ public final class FST implements Accountable { } // Linear scan - readFirstRealTargetArc(follow.target(), arc, in); - + readFirstArcInfo(follow.target(), arc, in); + in.setPosition(arc.nextArc()); while (true) { - // System.out.println(" non-bs cycle"); - // TODO: we should fix this code to not have to create - // object for the output of every arc we scan... only - // for the matching arc, if found - if (arc.label() == labelToMatch) { - // System.out.println(" found!"); - return arc; - } else if (arc.label() > labelToMatch) { + assert arc.bytesPerArc() == 0; + flags = arc.flags = in.readByte(); + long pos = in.getPosition(); + int label = readLabel(in); + if (label == labelToMatch) { + in.setPosition(pos); + return readArc(arc, in); + } else if (label > labelToMatch) { return null; } else if (arc.isLast()) { return null; } else { - readNextRealArc(arc, in); + if (flag(flags, BIT_ARC_HAS_OUTPUT)) { + outputs.skipOutput(in); + } + if (flag(flags, BIT_ARC_HAS_FINAL_OUTPUT)) { + outputs.skipFinalOutput(in); + } + if (flag(flags, BIT_STOP_NODE) == false && flag(flags, BIT_TARGET_NEXT) == false) { + readUnpackedNodeTarget(in); + } } } } @@ -1116,7 +1128,7 @@ public final class FST implements Accountable { outputs.skipFinalOutput(in); } - if (!flag(flags, BIT_STOP_NODE) && !flag(flags, BIT_TARGET_NEXT)) { + if (flag(flags, BIT_STOP_NODE) == false && flag(flags, BIT_TARGET_NEXT) == false) { readUnpackedNodeTarget(in); }