| 21 | } |
| 22 | |
| 23 | bool UnwindDedup::getNextTuplesInternal(ExecutionContext* context) { |
| 24 | while (true) { |
| 25 | if (!children[0]->getNextTuple(context)) { |
| 26 | return false; |
| 27 | } |
| 28 | |
| 29 | // Compute hash for the key vector |
| 30 | DASSERT(!keyVectors.empty()); |
| 31 | const auto& selVector = keyVectors[0]->state->getSelVector(); |
| 32 | if (selVector.getSelSize() == 0) { |
| 33 | continue; |
| 34 | } |
| 35 | |
| 36 | auto hashVector = std::make_unique<ValueVector>(LogicalType::HASH(), |
| 37 | MemoryManager::Get(*context->clientContext)); |
| 38 | hashVector->state = keyVectors[0]->state; |
| 39 | VectorHashFunction::computeHash(*keyVectors[0], selVector, *hashVector, selVector); |
| 40 | if (keyVectors.size() > 1) { |
| 41 | auto tmpHashVector = std::make_unique<ValueVector>(LogicalType::HASH(), |
| 42 | MemoryManager::Get(*context->clientContext)); |
| 43 | tmpHashVector->state = keyVectors[0]->state; |
| 44 | for (auto i = 1u; i < keyVectors.size(); ++i) { |
| 45 | DASSERT(keyVectors[i]->state == keyVectors[0]->state); |
| 46 | VectorHashFunction::computeHash(*keyVectors[i], selVector, *tmpHashVector, |
| 47 | selVector); |
| 48 | VectorHashFunction::combineHash(*hashVector, selVector, *tmpHashVector, selVector, |
| 49 | *hashVector, selVector); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | // Filter out duplicate values by modifying the selection vector |
| 54 | auto hashData = reinterpret_cast<hash_t*>(hashVector->getData()); |
| 55 | sel_t newSelectedPositions[DEFAULT_VECTOR_CAPACITY]; |
| 56 | auto newSelSize = 0u; |
| 57 | |
| 58 | for (auto i = 0u; i < selVector.getSelSize(); i++) { |
| 59 | auto pos = selVector[i]; |
| 60 | auto hash = hashData[pos]; |
| 61 | |
| 62 | if (seenHashes.find(hash) == seenHashes.end()) { |
| 63 | seenHashes.insert(hash); |
| 64 | newSelectedPositions[newSelSize++] = pos; |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | if (newSelSize > 0) { |
| 69 | // Update the selection vector to only include non-duplicate values |
| 70 | auto& selVectorUnsafe = keyVectors[0]->state->getSelVectorUnsafe(); |
| 71 | selVectorUnsafe.setToFiltered(newSelSize); |
| 72 | auto buffer = selVectorUnsafe.getMutableBuffer(); |
| 73 | for (auto i = 0u; i < newSelSize; i++) { |
| 74 | buffer[i] = newSelectedPositions[i]; |
| 75 | } |
| 76 | return true; |
| 77 | } |
| 78 | // If all values were duplicates, continue to next batch |
| 79 | } |
| 80 | } |
nothing calls this directly
no test coverage detected