protected internal virtual bool DoNext() { for (; ;) { switch (OuterInstance.AcceptPosition(this)) { case AcceptStatus.YES: return(true); case AcceptStatus.NO: if (!Spans.Next()) { return(false); } break; case AcceptStatus.NO_AND_ADVANCE: if (!Spans.SkipTo(Spans.Doc() + 1)) { return(false); } break; } } }
public override bool Next() { if (firstTime) { more = spans.Next(); firstTime = false; } if (!more) { return(false); } freq = 0.0f; doc = spans.Doc(); while (more && doc == spans.Doc()) { int matchLength = spans.End() - spans.Start(); freq += GetSimilarity().SloppyFreq(matchLength); more = spans.Next(); } return(more || freq != 0.0f); }
/// <summary>Check whether two Spans in the same document are ordered.</summary> /// <param name="spans1"> /// </param> /// <param name="spans2"> /// </param> /// <returns> true iff spans1 starts before spans2 /// or the spans start at the same position, /// and spans1 ends before spans2. /// </returns> internal static bool DocSpansOrdered(Spans spans1, Spans spans2) { System.Diagnostics.Debug.Assert(spans1.Doc() == spans2.Doc(), "doc1 " + spans1.Doc() + " != doc2 " + spans2.Doc()); int start1 = spans1.Start(); int start2 = spans2.Start(); /* Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() : */ return((start1 == start2)?(spans1.End() < spans2.End()):(start1 < start2)); }
public override bool Next() { if (moreInclude) // move to next include { moreInclude = includeSpans.Next(); } while (moreInclude && moreExclude) { if (includeSpans.Doc() > excludeSpans.Doc()) // skip exclude { moreExclude = excludeSpans.SkipTo(includeSpans.Doc()); } while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start() - OuterInstance.Pre) // while exclude is before { moreExclude = excludeSpans.Next(); // increment exclude } if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() + OuterInstance.Post <= excludeSpans.Start()) // if no intersection { break; // we found a match } moreInclude = includeSpans.Next(); // intersected: keep scanning } return(moreInclude); }
public override bool Next() { if (moreInclude) { // move to next include moreInclude = includeSpans.Next(); } while (moreInclude && moreExclude) { if (includeSpans.Doc() > excludeSpans.Doc()) { // skip exclude moreExclude = excludeSpans.SkipTo(includeSpans.Doc()); } while (moreExclude && includeSpans.Doc() == excludeSpans.Doc() && excludeSpans.End() <= includeSpans.Start()) { moreExclude = excludeSpans.Next(); // increment exclude } if (!moreExclude || includeSpans.Doc() != excludeSpans.Doc() || includeSpans.End() <= excludeSpans.Start()) { break; // we found a match } moreInclude = includeSpans.Next(); // intersected: keep scanning } return(moreInclude); }
public override int Advance(int target) { if (!More) { return(Doc = NO_MORE_DOCS); } if (Spans.Doc() < target) // setFreqCurrentDoc() leaves spans.doc() ahead { More = Spans.SkipTo(target); } if (!SetFreqCurrentDoc()) { Doc = NO_MORE_DOCS; } return(Doc); }
private void CheckSpans(Spans spans, int numSpans, int[] numPayloads) { int cnt = 0; while (spans.Next() == true) { if (VERBOSE) { Console.WriteLine("\nSpans Dump --"); } if (spans.PayloadAvailable) { var payload = spans.Payload; if (VERBOSE) { Console.WriteLine("payloads for span:" + payload.Count); foreach (var bytes in payload) { Console.WriteLine("doc:" + spans.Doc() + " s:" + spans.Start() + " e:" + spans.End() + " " + Encoding.UTF8.GetString((byte[])(Array)bytes)); } } Assert.AreEqual(numPayloads[cnt], payload.Count); } else { Assert.IsFalse(numPayloads.Length > 0 && numPayloads[cnt] > 0, "Expected spans:" + numPayloads[cnt] + " found: 0"); } cnt++; } Assert.AreEqual(numSpans, cnt); }
private void TstNextSpans(Spans spans, int doc, int start, int end) { Assert.IsTrue(spans.Next(), "next"); Assert.AreEqual(doc, spans.Doc(), "doc"); Assert.AreEqual(start, spans.Start(), "start"); Assert.AreEqual(end, spans.End(), "end"); }
/// <summary>The subSpans are ordered in the same doc, so there is a possible match. /// Compute the slop while making the match as short as possible by advancing /// all subSpans except the last one in reverse order. /// </summary> private bool ShrinkToAfterShortestMatch() { matchStart = subSpans[subSpans.Length - 1].Start(); matchEnd = subSpans[subSpans.Length - 1].End(); int matchSlop = 0; int lastStart = matchStart; int lastEnd = matchEnd; for (int i = subSpans.Length - 2; i >= 0; i--) { Spans prevSpans = subSpans[i]; int prevStart = prevSpans.Start(); int prevEnd = prevSpans.End(); while (true) { // Advance prevSpans until after (lastStart, lastEnd) if (!prevSpans.Next()) { inSameDoc = false; more = false; break; // Check remaining subSpans for final match. } else if (matchDoc != prevSpans.Doc()) { inSameDoc = false; // The last subSpans is not advanced here. break; // Check remaining subSpans for last match in this document. } else { int ppStart = prevSpans.Start(); int ppEnd = prevSpans.End(); // Cannot avoid invoking .end() if (!DocSpansOrdered(ppStart, ppEnd, lastStart, lastEnd)) { break; // Check remaining subSpans. } else { // prevSpans still before (lastStart, lastEnd) prevStart = ppStart; prevEnd = ppEnd; } } } System.Diagnostics.Debug.Assert(prevStart <= matchStart); if (matchStart > prevEnd) { // Only non overlapping spans add to slop. matchSlop += (matchStart - prevEnd); } /* Do not break on (matchSlop > allowedSlop) here to make sure * that subSpans[0] is advanced after the match, if any. */ matchStart = prevStart; lastStart = prevStart; lastEnd = prevEnd; } return(matchSlop <= allowedSlop); // ordered and allowed slop }
public override int Advance(int target, IState state) { if (!more) { return(doc = NO_MORE_DOCS); } if (spans.Doc() < target) { // setFreqCurrentDoc() leaves spans.doc() ahead more = spans.SkipTo(target, state); } if (!SetFreqCurrentDoc(state)) { doc = NO_MORE_DOCS; } return(doc); }
public virtual void TestSpanOrMovesForward() { Spans spans = OrSpans(new System.String[] { "w1", "xx" }); spans.Next(); int doc = spans.Doc(); Assert.AreEqual(0, doc); spans.SkipTo(0); doc = spans.Doc(); // LUCENE-1583: // according to Spans, a skipTo to the same doc or less // should still call next() on the underlying Spans Assert.AreEqual(1, doc); }
public override int Doc() { if (Current == null) { return(DocIdSetIterator.NO_MORE_DOCS); } return(Current.Doc() + Leaves[LeafOrd].DocBase); }
public override bool SkipTo(int target) { if (firstTime) { more = spans.SkipTo(target); firstTime = false; } if (!more) { return(false); } if (spans.Doc() < target) { // setFreqCurrentDoc() leaves spans.doc() ahead more = spans.SkipTo(target); } return(SetFreqCurrentDoc()); }
public virtual void TestSpansSkipTo() { SpanTermQuery t1 = new SpanTermQuery(new Term("field", "seventy")); SpanTermQuery t2 = new SpanTermQuery(new Term("field", "seventy")); Spans s1 = t1.GetSpans(searcher.IndexReader, null); Spans s2 = t2.GetSpans(searcher.IndexReader, null); Assert.IsTrue(s1.Next(null)); Assert.IsTrue(s2.Next(null)); bool hasMore = true; do { hasMore = SkipToAccoringToJavaDocs(s1, s1.Doc()); Assert.AreEqual(hasMore, s2.SkipTo(s2.Doc(), null)); Assert.AreEqual(s1.Doc(), s2.Doc()); }while (hasMore); }
public virtual void TestSpansSkipTo() { SpanTermQuery t1 = new SpanTermQuery(new Term("field", "seventy")); SpanTermQuery t2 = new SpanTermQuery(new Term("field", "seventy")); Spans s1 = MultiSpansWrapper.Wrap(Searcher.TopReaderContext, t1); Spans s2 = MultiSpansWrapper.Wrap(Searcher.TopReaderContext, t2); Assert.IsTrue(s1.Next()); Assert.IsTrue(s2.Next()); bool hasMore = true; do { hasMore = SkipToAccoringToJavaDocs(s1, s1.Doc() + 1); Assert.AreEqual(hasMore, s2.SkipTo(s2.Doc() + 1)); Assert.AreEqual(s1.Doc(), s2.Doc()); } while (hasMore); }
public virtual void TestSpanNearOrderedOverlap() { bool ordered = true; int slop = 1; SpanNearQuery snq = new SpanNearQuery(new SpanQuery[] { MakeSpanTermQuery("t1"), MakeSpanTermQuery("t2"), MakeSpanTermQuery("t3") }, slop, ordered); Spans spans = snq.GetSpans(searcher.GetIndexReader()); Assert.IsTrue(spans.Next(), "first range"); Assert.AreEqual(11, spans.Doc(), "first doc"); Assert.AreEqual(0, spans.Start(), "first start"); Assert.AreEqual(4, spans.End(), "first end"); Assert.IsTrue(spans.Next(), "second range"); Assert.AreEqual(11, spans.Doc(), "second doc"); Assert.AreEqual(2, spans.Start(), "second start"); Assert.AreEqual(6, spans.End(), "second end"); Assert.IsFalse(spans.Next(), "third range"); }
/// <summary> /// Skips to the first match beyond the current, whose document number is /// greater than or equal to <i>target</i>. <p>Returns true iff there is such /// a match. <p>Behaves as if written: <pre> /// boolean skipTo(int target) { /// do { /// if (!next()) /// return false; /// } while (target > doc()); /// return true; /// } /// </pre> /// </summary> private bool SkipToAccoringToJavaDocs(Spans s, int target) { do { if (!s.Next()) { return(false); } } while (target > s.Doc()); return(true); }
public virtual void TestSpanOrDoubleSkip() { Spans spans = OrSpans(new System.String[] { "w5", "yy" }); Assert.IsTrue(spans.SkipTo(3), "initial skipTo"); Assert.AreEqual(3, spans.Doc(), "doc"); Assert.AreEqual(4, spans.Start(), "start"); Assert.AreEqual(5, spans.End(), "end"); TstNextSpans(spans, 7, 3, 4); Assert.IsFalse(spans.Next(), "final next"); }
public override bool LessThan(object o1, object o2) { Spans spans1 = (Spans)o1; Spans spans2 = (Spans)o2; if (spans1.Doc() == spans2.Doc()) { if (spans1.Start() == spans2.Start()) { return(spans1.End() < spans2.End()); } else { return(spans1.Start() < spans2.Start()); } } else { return(spans1.Doc() < spans2.Doc()); } }
private void CheckSpans(Spans spans, int numSpans, int[] numPayloads) { int cnt = 0; while (spans.Next() == true) { if (DEBUG) { System.Console.Out.WriteLine("\nSpans Dump --"); } if (spans.IsPayloadAvailable()) { System.Collections.Generic.ICollection <byte[]> payload = spans.GetPayload(); if (DEBUG) { System.Console.Out.WriteLine("payloads for span:" + payload.Count); } System.Collections.IEnumerator it = payload.GetEnumerator(); while (it.MoveNext()) { byte[] bytes = (byte[])it.Current; if (DEBUG) { System.Console.Out.WriteLine("doc:" + spans.Doc() + " s:" + spans.Start() + " e:" + spans.End() + " " + new System.String(System.Text.UTF8Encoding.UTF8.GetChars(bytes))); } } Assert.AreEqual(numPayloads[cnt], payload.Count); } else { Assert.IsFalse(numPayloads.Length > 0 && numPayloads[cnt] > 0, "Expected spans:" + numPayloads[cnt] + " found: 0"); } cnt++; } Assert.AreEqual(numSpans, cnt); }
public virtual System.String S(Spans span) { return(S(span.Doc(), span.Start(), span.End())); }
private void CheckSpans(Spans spans, int numSpans, int[] numPayloads) { int cnt = 0; while (spans.Next() == true) { if (DEBUG) System.Console.Out.WriteLine("\nSpans Dump --"); if (spans.IsPayloadAvailable()) { System.Collections.Generic.ICollection<byte[]> payload = spans.GetPayload(); if (DEBUG) System.Console.Out.WriteLine("payloads for span:" + payload.Count); System.Collections.IEnumerator it = payload.GetEnumerator(); while (it.MoveNext()) { byte[] bytes = (byte[]) it.Current; if (DEBUG) System.Console.Out.WriteLine("doc:" + spans.Doc() + " s:" + spans.Start() + " e:" + spans.End() + " " + new System.String(System.Text.UTF8Encoding.UTF8.GetChars(bytes))); } Assert.AreEqual(numPayloads[cnt], payload.Count); } else { Assert.IsFalse(numPayloads.Length > 0 && numPayloads[cnt] > 0, "Expected spans:" + numPayloads[cnt] + " found: 0"); } cnt++; } Assert.AreEqual(numSpans, cnt); }
public virtual string s(Spans span) { return(s(span.Doc(), span.Start(), span.End())); }
/// <summary> /// The subSpans are ordered in the same doc, so there is a possible match. /// Compute the slop while making the match as short as possible by advancing /// all subSpans except the last one in reverse order. /// </summary> private bool ShrinkToAfterShortestMatch() { MatchStart = subSpans[subSpans.Length - 1].Start(); MatchEnd = subSpans[subSpans.Length - 1].End(); var possibleMatchPayloads = new HashSet <byte[]>(); if (subSpans[subSpans.Length - 1].PayloadAvailable) { //LUCENE TO-DO UnionWith or AddAll(Set<>, IEnumerable<>) possibleMatchPayloads.UnionWith(subSpans[subSpans.Length - 1].Payload); } IList <byte[]> possiblePayload = null; int matchSlop = 0; int lastStart = MatchStart; int lastEnd = MatchEnd; for (int i = subSpans.Length - 2; i >= 0; i--) { Spans prevSpans = subSpans[i]; if (CollectPayloads && prevSpans.PayloadAvailable) { var payload = prevSpans.Payload; possiblePayload = new List <byte[]>(payload.Count); possiblePayload.AddRange(payload); } int prevStart = prevSpans.Start(); int prevEnd = prevSpans.End(); while (true) // Advance prevSpans until after (lastStart, lastEnd) { if (!prevSpans.Next()) { InSameDoc = false; More = false; break; // Check remaining subSpans for final match. } else if (MatchDoc != prevSpans.Doc()) { InSameDoc = false; // The last subSpans is not advanced here. break; // Check remaining subSpans for last match in this document. } else { int ppStart = prevSpans.Start(); int ppEnd = prevSpans.End(); // Cannot avoid invoking .end() if (!DocSpansOrdered(ppStart, ppEnd, lastStart, lastEnd)) { break; // Check remaining subSpans. } // prevSpans still before (lastStart, lastEnd) else { prevStart = ppStart; prevEnd = ppEnd; if (CollectPayloads && prevSpans.PayloadAvailable) { var payload = prevSpans.Payload; possiblePayload = new List <byte[]>(payload.Count); possiblePayload.AddRange(payload); } } } } if (CollectPayloads && possiblePayload != null) { possibleMatchPayloads.UnionWith(possiblePayload); } Debug.Assert(prevStart <= MatchStart); if (MatchStart > prevEnd) // Only non overlapping spans add to slop. { matchSlop += (MatchStart - prevEnd); } /* Do not break on (matchSlop > allowedSlop) here to make sure * that subSpans[0] is advanced after the match, if any. */ MatchStart = prevStart; lastStart = prevStart; lastEnd = prevEnd; } bool match = matchSlop <= AllowedSlop; if (CollectPayloads && match && possibleMatchPayloads.Count > 0) { MatchPayload.AddRange(possibleMatchPayloads); } return(match); // ordered and allowed slop }
public virtual string s(Spans span) { return s(span.Doc(), span.Start(), span.End()); }
/// <summary> /// Skips to the first match beyond the current, whose document number is /// greater than or equal to <i>target</i>. <p>Returns true iff there is such /// a match. <p>Behaves as if written: <pre> /// boolean skipTo(int target) { /// do { /// if (!next()) /// return false; /// } while (target > doc()); /// return true; /// } /// </pre> /// </summary> private bool SkipToAccoringToJavaDocs(Spans s, int target) { do { if (!s.Next()) { return false; } } while (target > s.Doc()); return true; }
public virtual System.String S(Spans span) { return S(span.Doc(), span.Start(), span.End()); }
public virtual int Doc() { return(spans.Doc()); }
public override int Doc() { return(Spans.Doc()); }
public virtual void TestSpanNearUnOrdered() { //See http://www.gossamer-threads.com/lists/lucene/java-dev/52270 for discussion about this test SpanNearQuery snq; snq = new SpanNearQuery(new SpanQuery[] { MakeSpanTermQuery("u1"), MakeSpanTermQuery("u2") }, 0, false); Spans spans = snq.GetSpans(searcher.GetIndexReader()); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(4, spans.Doc(), "doc"); Assert.AreEqual(1, spans.Start(), "start"); Assert.AreEqual(3, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(5, spans.Doc(), "doc"); Assert.AreEqual(2, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(8, spans.Doc(), "doc"); Assert.AreEqual(2, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(9, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(2, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(10, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(2, spans.End(), "end"); Assert.IsTrue(spans.Next() == false, "Has next and it shouldn't: " + spans.Doc()); SpanNearQuery u1u2 = new SpanNearQuery(new SpanQuery[] { MakeSpanTermQuery("u1"), MakeSpanTermQuery("u2") }, 0, false); snq = new SpanNearQuery(new SpanQuery[] { u1u2, MakeSpanTermQuery("u2") }, 1, false); spans = snq.GetSpans(searcher.GetIndexReader()); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(4, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(3, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); //unordered spans can be subsets Assert.AreEqual(4, spans.Doc(), "doc"); Assert.AreEqual(1, spans.Start(), "start"); Assert.AreEqual(3, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(5, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(5, spans.Doc(), "doc"); Assert.AreEqual(2, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(8, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(8, spans.Doc(), "doc"); Assert.AreEqual(2, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(9, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(2, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(9, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(4, spans.End(), "end"); Assert.IsTrue(spans.Next(), "Does not have next and it should"); Assert.AreEqual(10, spans.Doc(), "doc"); Assert.AreEqual(0, spans.Start(), "start"); Assert.AreEqual(2, spans.End(), "end"); Assert.IsTrue(spans.Next() == false, "Has next and it shouldn't"); }
/// <summary> /// Check whether two Spans in the same document are ordered. </summary> /// <returns> true iff spans1 starts before spans2 /// or the spans start at the same position, /// and spans1 ends before spans2. </returns> internal static bool DocSpansOrdered(Spans spans1, Spans spans2) { Debug.Assert(spans1.Doc() == spans2.Doc(), "doc1 " + spans1.Doc() + " != doc2 " + spans2.Doc()); int start1 = spans1.Start(); int start2 = spans2.Start(); /* Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() : */ return (start1 == start2) ? (spans1.End() < spans2.End()) : (start1 < start2); }
/// <summary>The subSpans are ordered in the same doc, so there is a possible match. /// Compute the slop while making the match as short as possible by advancing /// all subSpans except the last one in reverse order. /// </summary> private bool ShrinkToAfterShortestMatch() { matchStart = subSpans[subSpans.Length - 1].Start(); matchEnd = subSpans[subSpans.Length - 1].End(); System.Collections.Generic.Dictionary <byte[], byte[]> possibleMatchPayloads = new System.Collections.Generic.Dictionary <byte[], byte[]>(); if (subSpans[subSpans.Length - 1].IsPayloadAvailable()) { System.Collections.Generic.ICollection <byte[]> payload = subSpans[subSpans.Length - 1].GetPayload(); foreach (byte[] pl in payload) { if (!possibleMatchPayloads.ContainsKey(pl)) { possibleMatchPayloads.Add(pl, pl); } } } System.Collections.Generic.List <byte[]> possiblePayload = null; int matchSlop = 0; int lastStart = matchStart; int lastEnd = matchEnd; for (int i = subSpans.Length - 2; i >= 0; i--) { Spans prevSpans = subSpans[i]; if (collectPayloads && prevSpans.IsPayloadAvailable()) { System.Collections.Generic.ICollection <byte[]> payload = prevSpans.GetPayload(); possiblePayload = new System.Collections.Generic.List <byte[]>(payload.Count); possiblePayload.AddRange(payload); } int prevStart = prevSpans.Start(); int prevEnd = prevSpans.End(); while (true) { // Advance prevSpans until after (lastStart, lastEnd) if (!prevSpans.Next()) { inSameDoc = false; more = false; break; // Check remaining subSpans for final match. } else if (matchDoc != prevSpans.Doc()) { inSameDoc = false; // The last subSpans is not advanced here. break; // Check remaining subSpans for last match in this document. } else { int ppStart = prevSpans.Start(); int ppEnd = prevSpans.End(); // Cannot avoid invoking .end() if (!DocSpansOrdered(ppStart, ppEnd, lastStart, lastEnd)) { break; // Check remaining subSpans. } else { // prevSpans still before (lastStart, lastEnd) prevStart = ppStart; prevEnd = ppEnd; if (collectPayloads && prevSpans.IsPayloadAvailable()) { System.Collections.Generic.ICollection <byte[]> payload = prevSpans.GetPayload(); possiblePayload = new System.Collections.Generic.List <byte[]>(payload.Count); possiblePayload.AddRange(payload); } } } } if (collectPayloads && possiblePayload != null) { foreach (byte[] pl in possiblePayload) { if (!possibleMatchPayloads.ContainsKey(pl)) { possibleMatchPayloads.Add(pl, pl); } } } System.Diagnostics.Debug.Assert(prevStart <= matchStart); if (matchStart > prevEnd) { // Only non overlapping spans add to slop. matchSlop += (matchStart - prevEnd); } /* Do not break on (matchSlop > allowedSlop) here to make sure * that subSpans[0] is advanced after the match, if any. */ matchStart = prevStart; lastStart = prevStart; lastEnd = prevEnd; } bool match = matchSlop <= allowedSlop; if (collectPayloads && match && possibleMatchPayloads.Count > 0) { matchPayload.AddRange(possibleMatchPayloads.Keys); } return(match); // ordered and allowed slop }