/// <summary> /// Returns the <see cref="TermInfo"/> for a <see cref="Term"/> in the set, or <c>null</c>. </summary> private TermInfo Get(Term term, bool mustSeekEnum) { if (size == 0) { return(null); } EnsureIndexIsRead(); TermInfoAndOrd tiOrd = termsCache.Get(new CloneableTerm(term)); ThreadResources resources = GetThreadResources(); if (!mustSeekEnum && tiOrd != null) { return(tiOrd); } return(SeekEnum(resources.termEnum, term, tiOrd, true)); }
internal TermInfo SeekEnum(SegmentTermEnum enumerator, Term term, TermInfoAndOrd tiOrd, bool useCache) { if (size == 0) { return(null); } // optimize sequential access: first try scanning cached enum w/o seeking if (enumerator.Term() != null && ((enumerator.Prev() != null && CompareAsUTF16(term, enumerator.Prev()) > 0) || CompareAsUTF16(term, enumerator.Term()) >= 0)) // term is at or past current { int enumOffset = (int)(enumerator.position / totalIndexInterval) + 1; if (indexLength == enumOffset || index.CompareTo(term, enumOffset) < 0) // but before end of block { // no need to seek TermInfo ti; int numScans = enumerator.ScanTo(term); if (enumerator.Term() != null && CompareAsUTF16(term, enumerator.Term()) == 0) { ti = enumerator.termInfo; if (numScans > 1) { // we only want to put this TermInfo into the cache if // scanEnum skipped more than one dictionary entry. // this prevents RangeQueries or WildcardQueries to // wipe out the cache when they iterate over a large numbers // of terms in order if (tiOrd == null) { if (useCache) { termsCache.Put(new CloneableTerm(DeepCopyOf(term)), new TermInfoAndOrd(ti, enumerator.position)); } } else if (Debugging.AssertsEnabled) { Debugging.Assert(SameTermInfo(ti, tiOrd, enumerator)); Debugging.Assert((int)enumerator.position == tiOrd.termOrd); } } } else { ti = null; } return(ti); } } // random-access: must seek int indexPos; if (tiOrd != null) { indexPos = (int)(tiOrd.termOrd / totalIndexInterval); } else { // Must do binary search: indexPos = index.GetIndexOffset(term); } index.SeekEnum(enumerator, indexPos); enumerator.ScanTo(term); TermInfo ti_; if (enumerator.Term() != null && CompareAsUTF16(term, enumerator.Term()) == 0) { ti_ = enumerator.termInfo; if (tiOrd == null) { if (useCache) { termsCache.Put(new CloneableTerm(DeepCopyOf(term)), new TermInfoAndOrd(ti_, enumerator.position)); } } else if (Debugging.AssertsEnabled) { Debugging.Assert(SameTermInfo(ti_, tiOrd, enumerator)); Debugging.Assert(enumerator.position == tiOrd.termOrd); } } else { ti_ = null; } return(ti_); }
internal TermInfo SeekEnum(SegmentTermEnum enumerator, Term term, TermInfoAndOrd tiOrd, bool useCache) { if (Size_Renamed == 0) { return null; } // optimize sequential access: first try scanning cached enum w/o seeking if (enumerator.Term() != null && ((enumerator.Prev() != null && CompareAsUTF16(term, enumerator.Prev()) > 0) || CompareAsUTF16(term, enumerator.Term()) >= 0)) // term is at or past current { int enumOffset = (int)(enumerator.Position / TotalIndexInterval) + 1; if (IndexLength == enumOffset || Index.CompareTo(term, enumOffset) < 0) // but before end of block { // no need to seek TermInfo ti; int numScans = enumerator.ScanTo(term); if (enumerator.Term() != null && CompareAsUTF16(term, enumerator.Term()) == 0) { ti = enumerator.TermInfo_Renamed; if (numScans > 1) { // we only want to put this TermInfo into the cache if // scanEnum skipped more than one dictionary entry. // this prevents RangeQueries or WildcardQueries to // wipe out the cache when they iterate over a large numbers // of terms in order if (tiOrd == null) { if (useCache) { TermsCache.Put(new CloneableTerm(DeepCopyOf(term)), new TermInfoAndOrd(ti, enumerator.Position)); } } else { Debug.Assert(SameTermInfo(ti, tiOrd, enumerator)); Debug.Assert(enumerator.Position == tiOrd.TermOrd); } } } else { ti = null; } return ti; } } // random-access: must seek int indexPos; if (tiOrd != null) { indexPos = (int)(tiOrd.TermOrd / TotalIndexInterval); } else { // Must do binary search: indexPos = Index.GetIndexOffset(term); } Index.SeekEnum(enumerator, indexPos); enumerator.ScanTo(term); TermInfo ti_; if (enumerator.Term() != null && CompareAsUTF16(term, enumerator.Term()) == 0) { ti_ = enumerator.TermInfo_Renamed; if (tiOrd == null) { if (useCache) { TermsCache.Put(new CloneableTerm(DeepCopyOf(term)), new TermInfoAndOrd(ti_, enumerator.Position)); } } else { Debug.Assert(SameTermInfo(ti_, tiOrd, enumerator)); Debug.Assert(enumerator.Position == tiOrd.TermOrd); } } else { ti_ = null; } return ti_; }