Example #1
0
        /// <summary>
        /// The terms array must be newly created <see cref="TermsEnum"/>, ie
        /// <see cref="TermsEnum.Next()"/> has not yet been called.
        /// </summary>
        public TermsEnum Reset(TermsEnumIndex[] termsEnumsIndex)
        {
            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(termsEnumsIndex.Length <= top.Length);
            }
            numSubs  = 0;
            numTop   = 0;
            termComp = null;
            queue.Clear();
            for (int i = 0; i < termsEnumsIndex.Length; i++)
            {
                TermsEnumIndex termsEnumIndex = termsEnumsIndex[i];
                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(termsEnumIndex != null);
                }

                // init our term comp
                if (termComp == null)
                {
                    queue.termComp = termComp = termsEnumIndex.TermsEnum.Comparer;
                }
                else
                {
                    // We cannot merge sub-readers that have
                    // different TermComps
                    IComparer <BytesRef> subTermComp = termsEnumIndex.TermsEnum.Comparer;
                    if (subTermComp != null && !subTermComp.Equals(termComp))
                    {
                        throw new InvalidOperationException("sub-readers have different BytesRef.Comparers: " + subTermComp + " vs " + termComp + "; cannot merge");
                    }
                }

                BytesRef term = termsEnumIndex.TermsEnum.Next();
                if (term != null)
                {
                    TermsEnumWithSlice entry = subs[termsEnumIndex.SubIndex];
                    entry.Reset(termsEnumIndex.TermsEnum, term);
                    queue.Add(entry);
                    currentSubs[numSubs++] = entry;
                }
                else
                {
                    // field has no terms
                }
            }

            if (queue.Count == 0)
            {
                return(TermsEnum.EMPTY);
            }
            else
            {
                return(this);
            }
        }
Example #2
0
 /// <summary>
 /// Sole constructor. </summary>
 /// <param name="slices"> Which sub-reader slices we should
 /// merge.</param>
 public MultiTermsEnum(ReaderSlice[] slices)
 {
     queue               = new TermMergeQueue(slices.Length);
     top                 = new TermsEnumWithSlice[slices.Length];
     subs                = new TermsEnumWithSlice[slices.Length];
     subDocs             = new MultiDocsEnum.EnumWithSlice[slices.Length];
     subDocsAndPositions = new MultiDocsAndPositionsEnum.EnumWithSlice[slices.Length];
     for (int i = 0; i < slices.Length; i++)
     {
         subs[i]                      = new TermsEnumWithSlice(i, slices[i]);
         subDocs[i]                   = new MultiDocsEnum.EnumWithSlice();
         subDocs[i].Slice             = slices[i];
         subDocsAndPositions[i]       = new MultiDocsAndPositionsEnum.EnumWithSlice();
         subDocsAndPositions[i].Slice = slices[i];
     }
     currentSubs = new TermsEnumWithSlice[slices.Length];
 }
Example #3
0
        public override DocsAndPositionsEnum DocsAndPositions(IBits liveDocs, DocsAndPositionsEnum reuse, DocsAndPositionsFlags flags)
        {
            MultiDocsAndPositionsEnum docsAndPositionsEnum;

            // Can only reuse if incoming enum is also a MultiDocsAndPositionsEnum
            if (reuse != null && reuse is MultiDocsAndPositionsEnum)
            {
                docsAndPositionsEnum = (MultiDocsAndPositionsEnum)reuse;
                // ... and was previously created w/ this MultiTermsEnum:
                if (!docsAndPositionsEnum.CanReuse(this))
                {
                    docsAndPositionsEnum = new MultiDocsAndPositionsEnum(this, subs.Length);
                }
            }
            else
            {
                docsAndPositionsEnum = new MultiDocsAndPositionsEnum(this, subs.Length);
            }

            MultiBits multiLiveDocs;

            if (liveDocs is MultiBits)
            {
                multiLiveDocs = (MultiBits)liveDocs;
            }
            else
            {
                multiLiveDocs = null;
            }

            int upto = 0;

            for (int i = 0; i < numTop; i++)
            {
                TermsEnumWithSlice entry = top[i];

                IBits b;

                if (multiLiveDocs != null)
                {
                    // Optimize for common case: requested skip docs is a
                    // congruent sub-slice of MultiBits: in this case, we
                    // just pull the liveDocs from the sub reader, rather
                    // than making the inefficient
                    // Slice(Multi(sub-readers)):
                    MultiBits.SubResult sub = multiLiveDocs.GetMatchingSub(top[i].SubSlice);
                    if (sub.Matches)
                    {
                        b = sub.Result;
                    }
                    else
                    {
                        // custom case: requested skip docs is foreign:
                        // must slice it on every access (very
                        // inefficient)
                        b = new BitsSlice(liveDocs, top[i].SubSlice);
                    }
                }
                else if (liveDocs != null)
                {
                    b = new BitsSlice(liveDocs, top[i].SubSlice);
                }
                else
                {
                    // no deletions
                    b = null;
                }

                if (Debugging.AssertsEnabled)
                {
                    Debugging.Assert(entry.Index < docsAndPositionsEnum.subDocsAndPositionsEnum.Length, () => entry.Index + " vs " + docsAndPositionsEnum.subDocsAndPositionsEnum.Length + "; " + subs.Length);
                }
                DocsAndPositionsEnum subPostings = entry.Terms.DocsAndPositions(b, docsAndPositionsEnum.subDocsAndPositionsEnum[entry.Index], flags);

                if (subPostings != null)
                {
                    docsAndPositionsEnum.subDocsAndPositionsEnum[entry.Index] = subPostings;
                    subDocsAndPositions[upto].DocsAndPositionsEnum            = subPostings;
                    subDocsAndPositions[upto].Slice = entry.SubSlice;
                    upto++;
                }
                else
                {
                    if (entry.Terms.Docs(b, null, DocsFlags.NONE) != null)
                    {
                        // At least one of our subs does not store
                        // offsets or positions -- we can't correctly
                        // produce a MultiDocsAndPositions enum
                        return(null);
                    }
                }
            }

            if (upto == 0)
            {
                return(null);
            }
            else
            {
                return(docsAndPositionsEnum.Reset(subDocsAndPositions, upto));
            }
        }
Example #4
0
        public override DocsEnum Docs(IBits liveDocs, DocsEnum reuse, DocsFlags flags)
        {
            MultiDocsEnum docsEnum;

            // Can only reuse if incoming enum is also a MultiDocsEnum
            if (reuse != null && reuse is MultiDocsEnum)
            {
                docsEnum = (MultiDocsEnum)reuse;
                // ... and was previously created w/ this MultiTermsEnum:
                if (!docsEnum.CanReuse(this))
                {
                    docsEnum = new MultiDocsEnum(this, subs.Length);
                }
            }
            else
            {
                docsEnum = new MultiDocsEnum(this, subs.Length);
            }

            MultiBits multiLiveDocs;

            if (liveDocs is MultiBits)
            {
                multiLiveDocs = (MultiBits)liveDocs;
            }
            else
            {
                multiLiveDocs = null;
            }

            int upto = 0;

            for (int i = 0; i < numTop; i++)
            {
                TermsEnumWithSlice entry = top[i];

                IBits b;

                if (multiLiveDocs != null)
                {
                    // optimize for common case: requested skip docs is a
                    // congruent sub-slice of MultiBits: in this case, we
                    // just pull the liveDocs from the sub reader, rather
                    // than making the inefficient
                    // Slice(Multi(sub-readers)):
                    MultiBits.SubResult sub = multiLiveDocs.GetMatchingSub(entry.SubSlice);
                    if (sub.Matches)
                    {
                        b = sub.Result;
                    }
                    else
                    {
                        // custom case: requested skip docs is foreign:
                        // must slice it on every access
                        b = new BitsSlice(liveDocs, entry.SubSlice);
                    }
                }
                else if (liveDocs != null)
                {
                    b = new BitsSlice(liveDocs, entry.SubSlice);
                }
                else
                {
                    // no deletions
                    b = null;
                }

                Debug.Assert(entry.Index < docsEnum.subDocsEnum.Length, entry.Index + " vs " + docsEnum.subDocsEnum.Length + "; " + subs.Length);
                DocsEnum subDocsEnum = entry.Terms.Docs(b, docsEnum.subDocsEnum[entry.Index], flags);
                if (subDocsEnum != null)
                {
                    docsEnum.subDocsEnum[entry.Index] = subDocsEnum;
                    subDocs[upto].DocsEnum            = subDocsEnum;
                    subDocs[upto].Slice = entry.SubSlice;
                    upto++;
                }
                else
                {
                    // should this be an error?
                    Debug.Assert(false, "One of our subs cannot provide a docsenum");
                }
            }

            if (upto == 0)
            {
                return(null);
            }
            else
            {
                return(docsEnum.Reset(subDocs, upto));
            }
        }