public override FieldComparator NewComparator(string fieldname, int numHits, int sortPos, bool reversed)
        {
            // we keep parallel slots: the parent ids and the child ids
            int[] parentSlots = new int[numHits];
            int[] childSlots  = new int[numHits];

            SortField[]       parentFields      = parentSort.GetSort();
            int[]             parentReverseMul  = new int[parentFields.Length];
            FieldComparator[] parentComparators = new FieldComparator[parentFields.Length];
            for (int i = 0; i < parentFields.Length; i++)
            {
                parentReverseMul[i]  = parentFields[i].Reverse ? -1 : 1;
                parentComparators[i] = parentFields[i].GetComparator(1, i);
            }

            SortField[]       childFields      = childSort.GetSort();
            int[]             childReverseMul  = new int[childFields.Length];
            FieldComparator[] childComparators = new FieldComparator[childFields.Length];
            for (int i = 0; i < childFields.Length; i++)
            {
                childReverseMul[i]  = childFields[i].Reverse ? -1 : 1;
                childComparators[i] = childFields[i].GetComparator(1, i);
            }

            // NOTE: we could return parent ID as value but really our sort "value" is more complex...
            // So we throw UOE for now. At the moment you really should only use this at indexing time.
            return(new FieldComparatorAnonymousInnerClassHelper(this, parentSlots,
                                                                childSlots, parentReverseMul, parentComparators, childReverseMul, childComparators));
        }
Exemple #2
0
 private ToParentBlockJoinFieldComparator(FieldComparator wrappedComparator, Filter parentFilter, Filter childFilter, int spareSlot)
 {
     _wrappedComparator = wrappedComparator;
     _parentFilter      = parentFilter;
     _childFilter       = childFilter;
     _spareSlot         = spareSlot;
 }
 public int Compare(ICollectedSearchGroup o1, ICollectedSearchGroup o2)
 {
     for (int compIDX = 0; ; compIDX++)
     {
         FieldComparator fc = outerInstance.comparators[compIDX];
         int             c  = outerInstance.reversed[compIDX] * fc.Compare(o1.ComparatorSlot, o2.ComparatorSlot);
         if (c != 0)
         {
             return(c);
         }
         else if (compIDX == outerInstance.compIDXEnd)
         {
             return(o1.TopDoc - o2.TopDoc);
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Returns a mapping from the old document ID to its new location in the
        /// sorted index. Implementations can use the auxiliary
        /// <see cref="Sort(int, DocComparator)"/> to compute the old-to-new permutation
        /// given a list of documents and their corresponding values.
        /// <para>
        /// A return value of <c>null</c> is allowed and means that
        /// <c>reader</c> is already sorted.
        /// </para>
        /// <para>
        /// <b>NOTE:</b> deleted documents are expected to appear in the mapping as
        /// well, they will however be marked as deleted in the sorted view.
        /// </para>
        /// </summary>
        internal DocMap Sort(AtomicReader reader)
        {
            SortField[] fields     = sort_Renamed.GetSort();
            int[]       reverseMul = new int[fields.Length];

            FieldComparator[] comparators = new FieldComparator[fields.Length];

            for (int i = 0; i < fields.Length; i++)
            {
                reverseMul[i]  = fields[i].Reverse ? -1 : 1;
                comparators[i] = fields[i].GetComparator(1, i);
                comparators[i].SetNextReader(reader.AtomicContext);
                comparators[i].Scorer = FAKESCORER;
            }
            DocComparator comparator = new DocComparatorAnonymousInnerClassHelper(this, reverseMul, comparators);

            return(Sort(reader.MaxDoc, comparator));
        }
Exemple #5
0
        public override FieldComparator SetNextReader(AtomicReaderContext context)
        {
            DocIdSet innerDocuments = _childFilter.GetDocIdSet(context, null);

            if (IsEmpty(innerDocuments))
            {
                _childDocuments = null;
            }
            else if (innerDocuments is FixedBitSet)
            {
                _childDocuments = (FixedBitSet)innerDocuments;
            }
            else
            {
                DocIdSetIterator iterator = innerDocuments.GetIterator();
                _childDocuments = iterator != null?ToFixedBitSet(iterator, context.AtomicReader.MaxDoc) : null;
            }
            DocIdSet rootDocuments = _parentFilter.GetDocIdSet(context, null);

            if (IsEmpty(rootDocuments))
            {
                _parentDocuments = null;
            }
            else if (rootDocuments is FixedBitSet)
            {
                _parentDocuments = (FixedBitSet)rootDocuments;
            }
            else
            {
                DocIdSetIterator iterator = rootDocuments.GetIterator();
                _parentDocuments = iterator != null?ToFixedBitSet(iterator, context.AtomicReader.MaxDoc) : null;
            }

            _wrappedComparator = _wrappedComparator.SetNextReader(context);
            return(this);
        }
 public LuceneCustomDocComparator(FieldComparator luceneComparator)
 {
     this._luceneComparator = luceneComparator;
 }
 public LuceneCustomDocComparatorSource(string fieldname, FieldComparator luceneComparator)
 {
     _fieldname        = fieldname;
     _luceneComparator = luceneComparator;
 }
        public override void Collect(int doc)
        {
            //System.out.println("FP.collect doc=" + doc);

            // If orderedGroups != null we already have collected N groups and
            // can short circuit by comparing this document to the bottom group,
            // without having to find what group this document belongs to.

            // Even if this document belongs to a group in the top N, we'll know that
            // we don't have to update that group.

            // Downside: if the number of unique groups is very low, this is
            // wasted effort as we will most likely be updating an existing group.
            if (orderedGroups != null)
            {
                for (int compIDX = 0; ; compIDX++)
                {
                    int c = reversed[compIDX] * comparators[compIDX].CompareBottom(doc);
                    if (c < 0)
                    {
                        // Definitely not competitive. So don't even bother to continue
                        return;
                    }
                    else if (c > 0)
                    {
                        // Definitely competitive.
                        break;
                    }
                    else if (compIDX == compIDXEnd)
                    {
                        // Here c=0. If we're at the last comparator, this doc is not
                        // competitive, since docs are visited in doc Id order, which means
                        // this doc cannot compete with any other document in the queue.
                        return;
                    }
                }
            }

            // TODO: should we add option to mean "ignore docs that
            // don't have the group field" (instead of stuffing them
            // under null group)?
            TGroupValue groupValue = GetDocGroupValue(doc);

            CollectedSearchGroup <TGroupValue> group;

            if (!groupMap.TryGetValue(groupValue, out group))
            {
                // First time we are seeing this group, or, we've seen
                // it before but it fell out of the top N and is now
                // coming back

                if (groupMap.Count < topNGroups)
                {
                    // Still in startup transient: we have not
                    // seen enough unique groups to start pruning them;
                    // just keep collecting them

                    // Add a new CollectedSearchGroup:
                    CollectedSearchGroup <TGroupValue> sg = new CollectedSearchGroup <TGroupValue>();
                    sg.GroupValue     = CopyDocGroupValue(groupValue, default(TGroupValue));
                    sg.ComparatorSlot = groupMap.Count;
                    sg.TopDoc         = docBase + doc;
                    foreach (FieldComparator fc in comparators)
                    {
                        fc.Copy(sg.ComparatorSlot, doc);
                    }
                    groupMap[sg.GroupValue] = sg;

                    if (groupMap.Count == topNGroups)
                    {
                        // End of startup transient: we now have max
                        // number of groups; from here on we will drop
                        // bottom group when we insert new one:
                        BuildSortedSet();
                    }

                    return;
                }

                // We already tested that the document is competitive, so replace
                // the bottom group with this new group.
                //CollectedSearchGroup<TGroupValue> bottomGroup = orderedGroups.PollLast();
                CollectedSearchGroup <TGroupValue> bottomGroup;
                lock (orderedGroups)
                {
                    bottomGroup = orderedGroups.Last();
                    orderedGroups.Remove(bottomGroup);
                }
                Debug.Assert(orderedGroups.Count == topNGroups - 1);

                groupMap.Remove(bottomGroup.GroupValue);

                // reuse the removed CollectedSearchGroup
                bottomGroup.GroupValue = CopyDocGroupValue(groupValue, bottomGroup.GroupValue);
                bottomGroup.TopDoc     = docBase + doc;

                foreach (FieldComparator fc in comparators)
                {
                    fc.Copy(bottomGroup.ComparatorSlot, doc);
                }

                groupMap[bottomGroup.GroupValue] = bottomGroup;
                orderedGroups.Add(bottomGroup);
                Debug.Assert(orderedGroups.Count == topNGroups);

                int lastComparatorSlot = orderedGroups.Last().ComparatorSlot;
                foreach (FieldComparator fc in comparators)
                {
                    fc.Bottom = lastComparatorSlot;
                }

                return;
            }

            // Update existing group:
            for (int compIDX = 0; ; compIDX++)
            {
                FieldComparator fc = comparators[compIDX];
                fc.Copy(spareSlot, doc);

                int c = reversed[compIDX] * fc.Compare(group.ComparatorSlot, spareSlot);
                if (c < 0)
                {
                    // Definitely not competitive.
                    return;
                }
                else if (c > 0)
                {
                    // Definitely competitive; set remaining comparators:
                    for (int compIDX2 = compIDX + 1; compIDX2 < comparators.Length; compIDX2++)
                    {
                        comparators[compIDX2].Copy(spareSlot, doc);
                    }
                    break;
                }
                else if (compIDX == compIDXEnd)
                {
                    // Here c=0. If we're at the last comparator, this doc is not
                    // competitive, since docs are visited in doc Id order, which means
                    // this doc cannot compete with any other document in the queue.
                    return;
                }
            }

            // Remove before updating the group since lookup is done via comparators
            // TODO: optimize this

            CollectedSearchGroup <TGroupValue> prevLast;

            if (orderedGroups != null)
            {
                lock (orderedGroups)
                {
                    prevLast = orderedGroups.Last();
                    orderedGroups.Remove(group);
                }
                Debug.Assert(orderedGroups.Count == topNGroups - 1);
            }
            else
            {
                prevLast = null;
            }

            group.TopDoc = docBase + doc;

            // Swap slots
            int tmp = spareSlot;

            spareSlot            = group.ComparatorSlot;
            group.ComparatorSlot = tmp;

            // Re-add the changed group
            if (orderedGroups != null)
            {
                orderedGroups.Add(group);
                Debug.Assert(orderedGroups.Count == topNGroups);
                var newLast = orderedGroups.Last();
                // If we changed the value of the last group, or changed which group was last, then update bottom:
                if (group == newLast || prevLast != newLast)
                {
                    foreach (FieldComparator fc in comparators)
                    {
                        fc.Bottom = newLast.ComparatorSlot;
                    }
                }
            }
        }
Exemple #9
0
 public TestFieldComparator(FieldComparator comparator, List <string> diagnostics)
 {
     _comparator  = comparator ?? throw new ArgumentNullException(nameof(comparator));
     _diagnostics = diagnostics;
 }
Exemple #10
0
 /// <summary>
 /// Create ToParentBlockJoinFieldComparator.Highest
 /// </summary>
 /// <param name="wrappedComparator">The <see cref="FieldComparator"/> on the child / nested level. </param>
 /// <param name="parentFilter">Filter (must produce FixedBitSet per-segment) that identifies the parent documents. </param>
 /// <param name="childFilter">Filter that defines which child / nested documents participates in sorting. </param>
 /// <param name="spareSlot">The extra slot inside the wrapped comparator that is used to compare which nested document
 ///                  inside the parent document scope is most competitive. </param>
 public Highest(FieldComparator wrappedComparator, Filter parentFilter, Filter childFilter, int spareSlot)
     : base(wrappedComparator, parentFilter, childFilter, spareSlot)
 {
 }