const HitList & SameElementQueryNode::evaluateHits(HitList & hl) const { hl.clear(); if ( !AndQueryNode::evaluate()) return hl; HitList tmpHL; unsigned int numFields = size(); unsigned int currMatchCount = 0; std::vector<unsigned int> indexVector(numFields, 0); auto curr = static_cast<const QueryTerm *> ((*this)[currMatchCount].get()); bool exhausted( curr->evaluateHits(tmpHL).empty()); for (; !exhausted; ) { auto next = static_cast<const QueryTerm *>((*this)[currMatchCount+1].get()); unsigned int & currIndex = indexVector[currMatchCount]; unsigned int & nextIndex = indexVector[currMatchCount+1]; const auto & currHit = curr->evaluateHits(tmpHL)[currIndex]; uint32_t currElemId = currHit.elemId(); const HitList & nextHL = next->evaluateHits(tmpHL); size_t nextIndexMax = nextHL.size(); while ((nextIndex < nextIndexMax) && (nextHL[nextIndex].elemId() < currElemId)) { nextIndex++; } if (nextHL[nextIndex].elemId() == currElemId) { currMatchCount++; if ((currMatchCount+1) == numFields) { Hit h = nextHL[indexVector[currMatchCount]]; hl.emplace_back(0, h.context(), h.elemId(), h.weight()); currMatchCount = 0; indexVector[0]++; } } else { currMatchCount = 0; indexVector[currMatchCount]++; } curr = static_cast<const QueryTerm *>((*this)[currMatchCount].get()); exhausted = (nextIndex >= nextIndexMax) || (indexVector[currMatchCount] >= curr->evaluateHits(tmpHL).size()); } return hl; }