private static DocIdSetIterator approximation(PhraseQuery.PostingsAndFreq[] postings) { List<DocIdSetIterator> iterators = new ArrayList<>(); for (PhraseQuery.PostingsAndFreq posting : postings) { iterators.add(posting.postings); } return ConjunctionDISI.intersectIterators(iterators); }
ConjunctionSpans(List<Spans> subSpans) { if (subSpans.size() < 2) { throw new IllegalArgumentException("Less than 2 subSpans.size():" + subSpans.size()); } this.subSpans = subSpans.toArray(new Spans[subSpans.size()]); this.conjunction = ConjunctionDISI.intersectSpans(subSpans); this.atFirstInCurrentDoc = true; // ensure for doc -1 that start/end positions are -1 }
private static DocIdSetIterator createConjunction( List<DocIdSetIterator> allIterators, List<TwoPhaseIterator> twoPhaseIterators) { long minCost = allIterators.stream().mapToLong(DocIdSetIterator::cost).min().getAsLong(); List<BitSetIterator> bitSetIterators = new ArrayList<>(); List<DocIdSetIterator> iterators = new ArrayList<>(); for (DocIdSetIterator iterator : allIterators) { if (iterator.cost() > minCost && iterator instanceof BitSetIterator) { // we put all bitset iterators into bitSetIterators // except if they have the minimum cost, since we need // them to lead the iteration in that case bitSetIterators.add((BitSetIterator) iterator); } else { iterators.add(iterator); } } DocIdSetIterator disi; if (iterators.size() == 1) { disi = iterators.get(0); } else { disi = new ConjunctionDISI(iterators); } if (bitSetIterators.size() > 0) { disi = new BitSetConjunctionDISI(disi, bitSetIterators); } if (twoPhaseIterators.isEmpty() == false) { disi = TwoPhaseIterator.asDocIdSetIterator(new ConjunctionTwoPhaseIterator(disi, twoPhaseIterators)); } return disi; }
/** Adds the Spans. */ private static void addSpans(Spans spans, List<DocIdSetIterator> allIterators, List<TwoPhaseIterator> twoPhaseIterators) { TwoPhaseIterator twoPhaseIter = spans.asTwoPhaseIterator(); if (twoPhaseIter != null) { addTwoPhaseIterator(twoPhaseIter, allIterators, twoPhaseIterators); } else { // no approximation support, use the iterator as-is addIterator(spans, allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Spans}. Note that the * returned {@link DocIdSetIterator} might leverage two-phase iteration in * which case it is possible to retrieve the {@link TwoPhaseIterator} using * {@link TwoPhaseIterator#unwrap}. */ public static DocIdSetIterator intersectSpans(List<Spans> spanList) { if (spanList.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Spans spans : spanList) { addSpans(spans, allIterators, twoPhaseIterators); } return createConjunction(allIterators, twoPhaseIterators); }
/** Create a conjunction over the provided {@link Scorer}s. Note that the * returned {@link DocIdSetIterator} might leverage two-phase iteration in * which case it is possible to retrieve the {@link TwoPhaseIterator} using * {@link TwoPhaseIterator#unwrap}. */ public static DocIdSetIterator intersectScorers(Collection<Scorer> scorers) { if (scorers.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Scorer scorer : scorers) { addScorer(scorer, allIterators, twoPhaseIterators); } return createConjunction(allIterators, twoPhaseIterators); }
@Override public int advance(int target) throws IOException { return doNext(lead1.advance(target)); }
/** Create a conjunction over the provided DocIdSetIterators. */ public static ConjunctionDISI intersectIterators(List<DocIdSetIterator> iterators) { if (iterators.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (DocIdSetIterator iterator : iterators) { addIterator(iterator, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Scorer}s, taking advantage * of {@link TwoPhaseIterator}. */ public static ConjunctionDISI intersectScorers(List<Scorer> scorers) { if (scorers.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Scorer scorer : scorers) { addScorer(scorer, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Scorer}s, taking advantage * of {@link TwoPhaseIterator}. */ public static ConjunctionDISI intersectSpans(List<Spans> spanList) { if (spanList.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Spans spans : spanList) { addSpans(spans, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided DocIdSetIterators. Note that the * returned {@link DocIdSetIterator} might leverage two-phase iteration in * which case it is possible to retrieve the {@link TwoPhaseIterator} using * {@link TwoPhaseIterator#unwrap}. */ public static DocIdSetIterator intersectIterators(List<DocIdSetIterator> iterators) { if (iterators.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (DocIdSetIterator iterator : iterators) { addIterator(iterator, allIterators, twoPhaseIterators); } return createConjunction(allIterators, twoPhaseIterators); }
/** Create a new {@link ConjunctionScorer}, note that {@code scorers} must be a subset of {@code required}. */ ConjunctionScorer(Weight weight, Collection<Scorer> required, Collection<Scorer> scorers) { super(weight); assert required.containsAll(scorers); this.disi = ConjunctionDISI.intersectScorers(required); this.scorers = scorers.toArray(new Scorer[scorers.size()]); this.required = required; }
private static void addTwoPhaseIterator(TwoPhaseIterator twoPhaseIter, List<DocIdSetIterator> allIterators, List<TwoPhaseIterator> twoPhaseIterators) { addIterator(twoPhaseIter.approximation(), allIterators, twoPhaseIterators); if (twoPhaseIter.getClass() == ConjunctionTwoPhaseIterator.class) { // Check for exactly this class for collapsing Collections.addAll(twoPhaseIterators, ((ConjunctionTwoPhaseIterator) twoPhaseIter).twoPhaseIterators); } else { twoPhaseIterators.add(twoPhaseIter); } }
private static void addIterator(DocIdSetIterator disi, List<DocIdSetIterator> allIterators, List<TwoPhaseIterator> twoPhaseIterators) { TwoPhaseIterator twoPhase = TwoPhaseIterator.unwrap(disi); if (twoPhase != null) { addTwoPhaseIterator(twoPhase, allIterators, twoPhaseIterators); } else if (disi.getClass() == ConjunctionDISI.class) { // Check for exactly this class for collapsing ConjunctionDISI conjunction = (ConjunctionDISI) disi; // subconjuctions have already split themselves into two phase iterators and others, so we can take those // iterators as they are and move them up to this conjunction allIterators.add(conjunction.lead1); allIterators.add(conjunction.lead2); Collections.addAll(allIterators, conjunction.others); } else if (disi.getClass() == BitSetConjunctionDISI.class) { BitSetConjunctionDISI conjunction = (BitSetConjunctionDISI) disi; allIterators.add(conjunction.lead); Collections.addAll(allIterators, conjunction.bitSetIterators); } else { allIterators.add(disi); } }
/** Adds the scorer, possibly splitting up into two phases or collapsing if it is another conjunction */ private static void addScorer(Scorer scorer, List<DocIdSetIterator> allIterators, List<TwoPhaseIterator> twoPhaseIterators) { TwoPhaseIterator twoPhaseIter = scorer.twoPhaseIterator(); if (twoPhaseIter != null) { addTwoPhaseIterator(twoPhaseIter, allIterators, twoPhaseIterators); } else { // no approximation support, use the iterator as-is addIterator(scorer.iterator(), allIterators, twoPhaseIterators); } }
@Override public int nextDoc() throws IOException { return doNext(lead1.nextDoc()); }
/** Create a conjunction over the provided DocIdSetIterators. */ public static ConjunctionDISI intersectIterators(List<DocIdSetIterator> iterators) { if (iterators.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (DocIdSetIterator iterator : iterators) { addIterator(iterator, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Scorer}s, taking advantage * of {@link TwoPhaseIterator}. */ public static ConjunctionDISI intersectScorers(List<Scorer> scorers) { if (scorers.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Scorer scorer : scorers) { addScorer(scorer, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Scorer}s, taking advantage * of {@link TwoPhaseIterator}. */ public static ConjunctionDISI intersectSpans(List<Spans> spanList) { if (spanList.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Spans spans : spanList) { addSpans(spans, allIterators, twoPhaseIterators); } if (twoPhaseIterators.isEmpty()) { return new ConjunctionDISI(allIterators); } else { return new TwoPhase(allIterators, twoPhaseIterators); } }
/** Create a conjunction over the provided {@link Spans}. Note that the * returned {@link DocIdSetIterator} might leverage two-phase iteration in * which case it is possible to retrieve the {@link TwoPhaseIterator} using * {@link TwoPhaseIterator#unwrap}. */ public static DocIdSetIterator intersectSpans(List<Spans> spanList) { if (spanList.size() < 2) { throw new IllegalArgumentException("Cannot make a ConjunctionDISI of less than 2 iterators"); } final List<DocIdSetIterator> allIterators = new ArrayList<>(); final List<TwoPhaseIterator> twoPhaseIterators = new ArrayList<>(); for (Spans spans : spanList) { addSpans(spans, allIterators, twoPhaseIterators); } return createConjunction(allIterators, twoPhaseIterators); }