// only bits
assert shouldBits.size() >= 1;
if (shouldBits.size() == 1) {
requiredBits.add(shouldBits.get(0));
} else {
requiredBits.add(new OrBits(shouldBits.toArray(new Bits[shouldBits.size()])));
}
} else {
assert shouldBits.isEmpty();
// only iterators, we can add the merged iterator to the list of required iterators
requiredIterators.add(shouldBuilder.build().iterator());
}
}
} else {
assert shouldIterators.isEmpty();
assert shouldBits.isEmpty();
}
// From now on, we don't have to care about SHOULD clauses anymore since we upgraded
// them to required clauses (if necessary)
// cheap iterators first to make intersection faster
CollectionUtil.timSort(requiredIterators, COST_ASCENDING);
CollectionUtil.timSort(excludedIterators, COST_ASCENDING);
// Intersect iterators
BitDocIdSet.Builder res = null;
for (DocIdSetIterator iterator : requiredIterators) {
if (res == null) {
res = new BitDocIdSet.Builder(maxDoc);
res.or(iterator);
} else {
res.and(iterator);
}
}
for (DocIdSetIterator iterator : excludedIterators) {
if (res == null) {
res = new BitDocIdSet.Builder(maxDoc, true);
}
res.andNot(iterator);
}
// Transform the excluded bits into required bits
if (excludedBits.isEmpty() == false) {
Bits excluded;
if (excludedBits.size() == 1) {
excluded = excludedBits.get(0);
} else {
excluded = new OrBits(excludedBits.toArray(new Bits[excludedBits.size()]));
}
requiredBits.add(new NotDocIdSet.NotBits(excluded));
}
// The only thing left to do is to intersect 'res' with 'requiredBits'