| 55 | } |
| 56 | |
| 57 | void IndexBuilderGlobalQueues::maybeConsumeIndex(size_t index, |
| 58 | NodeBatchInsertErrorHandler& errorHandler) { |
| 59 | auto& pkIndex = nodeTable->getPKIndex()->cast<PrimaryKeyIndex>(); |
| 60 | if (!pkIndex.tryLockTypedIndex(index)) { |
| 61 | return; |
| 62 | } |
| 63 | |
| 64 | std::visit( |
| 65 | [&](auto&& queues) { |
| 66 | using T = std::decay_t<decltype(queues.type)>; |
| 67 | auto lck = pkIndex.adoptLockOfTypedIndex(index); |
| 68 | IndexBufferWithWarningData<T> bufferWithWarningData; |
| 69 | while (queues.array[index].pop(bufferWithWarningData)) { |
| 70 | auto& buffer = bufferWithWarningData.indexBuffer; |
| 71 | auto& warningDataBuffer = bufferWithWarningData.warningDataBuffer; |
| 72 | uint64_t insertBufferOffset = 0; |
| 73 | while (insertBufferOffset < buffer.size()) { |
| 74 | auto numValuesInserted = pkIndex.appendWithIndexPosNoLock(transaction, buffer, |
| 75 | insertBufferOffset, index, |
| 76 | [&](offset_t offset) { return nodeTable->isVisible(transaction, offset); }); |
| 77 | if (numValuesInserted < buffer.size() - insertBufferOffset) { |
| 78 | const auto& erroneousEntry = buffer[insertBufferOffset + numValuesInserted]; |
| 79 | OptionalWarningSourceData erroneousEntryWarningData; |
| 80 | if (warningDataBuffer != nullptr) { |
| 81 | erroneousEntryWarningData = |
| 82 | (*warningDataBuffer)[insertBufferOffset + numValuesInserted]; |
| 83 | } |
| 84 | errorHandler.handleError( |
| 85 | IndexBuilderError<T>{.message = ExceptionMessage::duplicatePKException( |
| 86 | TypeUtils::toString(erroneousEntry.first)), |
| 87 | .key = erroneousEntry.first, |
| 88 | .nodeID = |
| 89 | nodeID_t{ |
| 90 | erroneousEntry.second, |
| 91 | nodeTable->getTableID(), |
| 92 | }, |
| 93 | .kind = NodeCopyErrorKind::DUPLICATE_PK, |
| 94 | .warningData = erroneousEntryWarningData}); |
| 95 | insertBufferOffset += 1; // skip the erroneous index then continue |
| 96 | } |
| 97 | insertBufferOffset += numValuesInserted; |
| 98 | } |
| 99 | } |
| 100 | return; |
| 101 | }, |
| 102 | std::move(queues)); |
| 103 | } |
| 104 | |
| 105 | IndexBuilderLocalBuffers::IndexBuilderLocalBuffers(IndexBuilderGlobalQueues& globalQueues) |
| 106 | : globalQueues(&globalQueues) { |
nothing calls this directly
no test coverage detected