private void findMatchingConjunctions(int k, List<ConjunctionIdIterator> iterators, List<ConjunctionHit> matchingIds, byte[] iteratorsPerConjunction) {
            if (k == 0) {
                k = 1;
            }
            int nextId = getNextId(0, k, iteratorsPerConjunction);
            if (nextId == -1) {
                return; // no hits
            }

            int nIterators = iterators.size();
            if (nIterators < k) {
                return; // No hits
            }
            short[] sortedIndexes = new short[nIterators];
            short[] sortedIndexesMergeBuffer = new short[nIterators];
            for (short i = 0; i < nIterators; ++i) {
                sortedIndexes[i] = i;
            }

            int[] currentIds = new int[nIterators];
            int nCompleted = initializeIterators(iterators, sortedIndexes, currentIds, nextId);
            nIterators -= nCompleted;

            while (nIterators >= k) {
                int id0 = currentIds[sortedIndexes[0]];
                int idK = currentIds[sortedIndexes[k - 1]];

                // There should be at least k iterators for conjunction.
                if (ConjunctionId.equals(id0, idK)) {
                    long matchingSubqueries = SubqueryBitmap.ALL_SUBQUERIES;
                    // Find first positive conjunction
                    int firstPositive = 0;
                    while (firstPositive < nIterators && !ConjunctionId.isPositive(currentIds[sortedIndexes[firstPositive]])) {
                        // AND in the complement of the bitmap for negative conjunctions.
                        matchingSubqueries &= ~iterators.get(sortedIndexes[firstPositive]).getSubqueryBitmap();
                        ++firstPositive;
                    }
                    if (firstPositive + k <= nIterators) {
                        // Verify that at there are k positive iterators for the current conjunction.
                        id0 = currentIds[sortedIndexes[firstPositive]];
                        idK = currentIds[sortedIndexes[firstPositive + k - 1]];
                        if (id0 == idK) { // We know that id0 is positive conjunction
                            for (int i = firstPositive; i < firstPositive + k; i++) {
                                matchingSubqueries &= iterators.get(sortedIndexes[i]).getSubqueryBitmap();
                            }
                            if (matchingSubqueries != 0) {
                                matchingIds.add(new ConjunctionHit(toExternalId(id0), matchingSubqueries));
                            }
                        }
                    }
                }

                // Advance iterators to next conjunction.
                nextId = getNextId(ConjunctionId.nextId(id0), k, iteratorsPerConjunction);
                if (nextId == -1) {
                    return;
                }
                int completed = 0;
                int i;
                for (i = 0; i < nIterators; ++i) {
                    short index = sortedIndexes[i];
                    if (ConjunctionId.compare(currentIds[index], nextId) < 0) {
                        ConjunctionIdIterator iterator = iterators.get(index);
                        if (iterator.next(nextId)) {
                            currentIds[index] = iterator.getConjunctionId();
                        } else {
                            currentIds[index] = Integer.MAX_VALUE;
                            ++completed;
                        }
                    } else {
                        break;
                    }
                }
                if (i > 0 && nIterators - completed >= k) {
                    boolean swapMergeBuffer =
                            PrimitiveArraySorter.sortAndMerge(sortedIndexes, sortedIndexesMergeBuffer, i, nIterators,
                                    (a, b) -> Integer.compare(currentIds[a], currentIds[b]));
                    if (swapMergeBuffer) {
                        short[] temp = sortedIndexes;
                        sortedIndexes = sortedIndexesMergeBuffer;
                        sortedIndexesMergeBuffer = temp;
                    }
                }
                nIterators -= completed;
            }
        }
Retrieves a list of hits for the given query.

@param query Specifies the boolean variables that are true.
@return List of hits
predicate-search/src/main/java/com/yahoo/search/predicate/index/conjunction/ConjunctionIndex.java