/// <summary> /// Adds all leaving arcs, including 'finished' arc, if /// the node is final, from this node into the queue. /// </summary> public virtual void AddStartPaths(FST.Arc <T> node, T startOutput, bool allowEmptyString, Int32sRef input) { // De-dup NO_OUTPUT since it must be a singleton: if (startOutput.Equals(fst.Outputs.NoOutput)) { startOutput = fst.Outputs.NoOutput; } FSTPath <T> path = new FSTPath <T>(startOutput, node, input); fst.ReadFirstTargetArc(node, path.Arc, bytesReader); //System.out.println("add start paths"); // Bootstrap: find the min starting arc while (true) { if (allowEmptyString || path.Arc.Label != FST.END_LABEL) { AddIfCompetitive(path); } if (path.Arc.IsLast) { break; } fst.ReadNextArc(path.Arc, bytesReader); } }
// If back plus this arc is competitive then add to queue: protected virtual void AddIfCompetitive(FSTPath <T> path) { Debug.Assert(Queue != null); T cost = Fst.Outputs.Add(path.Cost, path.Arc.Output); //System.out.println(" addIfCompetitive queue.size()=" + queue.size() + " path=" + path + " + label=" + path.arc.label); if (Queue.Count == MaxQueueDepth) { FSTPath <T> bottom = Queue.Max; int comp = Comparator.Compare(cost, bottom.Cost); if (comp > 0) { // Doesn't compete return; } else if (comp == 0) { // Tie break by alpha sort on the input: path.Input.Grow(path.Input.Length + 1); path.Input.Ints[path.Input.Length++] = path.Arc.Label; int cmp = bottom.Input.CompareTo(path.Input); path.Input.Length--; // We should never see dups: Debug.Assert(cmp != 0); if (cmp < 0) { // Doesn't compete return; } } // Competes } else { // Queue isn't full yet, so any path we hit competes: } // copy over the current input to the new input // and add the arc.label to the end IntsRef newInput = new IntsRef(path.Input.Length + 1); Array.Copy(path.Input.Ints, 0, newInput.Ints, 0, path.Input.Length); newInput.Ints[path.Input.Length] = path.Arc.Label; newInput.Length = path.Input.Length + 1; FSTPath <T> newPath = new FSTPath <T>(cost, path.Arc, newInput); Queue.Add(newPath); if (Queue.Count == MaxQueueDepth + 1) { Queue.Last(); } }
public virtual int Compare(FSTPath <T> a, FSTPath <T> b) { int cmp = comparer.Compare(a.Cost, b.Cost); if (cmp == 0) { return(a.Input.CompareTo(b.Input)); } else { return(cmp); } }
/// <summary> /// If back plus this arc is competitive then add to queue: /// </summary> protected virtual void AddIfCompetitive(FSTPath <T> path) { Debug.Assert(queue != null); T cost = fst.Outputs.Add(path.Cost, path.Arc.Output); //System.out.println(" addIfCompetitive queue.size()=" + queue.size() + " path=" + path + " + label=" + path.arc.label); if (queue.Count == maxQueueDepth) { FSTPath <T> bottom = queue.Max; int comp = comparer.Compare(cost, bottom.Cost); if (comp > 0) { // Doesn't compete return; } else if (comp == 0) { // Tie break by alpha sort on the input: path.Input.Grow(path.Input.Length + 1); path.Input.Int32s[path.Input.Length++] = path.Arc.Label; int cmp = bottom.Input.CompareTo(path.Input); path.Input.Length--; // We should never see dups: Debug.Assert(cmp != 0); if (cmp < 0) { // Doesn't compete return; } } // Competes } else { // Queue isn't full yet, so any path we hit competes: } // copy over the current input to the new input // and add the arc.label to the end Int32sRef newInput = new Int32sRef(path.Input.Length + 1); Array.Copy(path.Input.Int32s, 0, newInput.Int32s, 0, path.Input.Length); newInput.Int32s[path.Input.Length] = path.Arc.Label; newInput.Length = path.Input.Length + 1; FSTPath <T> newPath = new FSTPath <T>(cost, path.Arc, newInput); queue.Add(newPath); if (queue.Count == maxQueueDepth + 1) { // LUCENENET NOTE: SortedSet doesn't have atomic operations, // so we need to add some thread safety just in case. // Perhaps it might make sense to wrap SortedSet into a type // that provides thread safety. lock (syncLock) { queue.Remove(queue.Max); } } }