| 185 | } |
| 186 | |
| 187 | NodeGroupScanResult NodeGroup::scan(const Transaction* transaction, TableScanState& state) const { |
| 188 | // TODO(Guodong): Move the locked part of figuring out the chunked group to initScan. |
| 189 | const auto lock = chunkedGroups.lock(); |
| 190 | auto& nodeGroupScanState = *state.nodeGroupScanState; |
| 191 | DASSERT(nodeGroupScanState.chunkedGroupIdx < chunkedGroups.getNumGroups(lock)); |
| 192 | const auto chunkedGroup = chunkedGroups.getGroup(lock, nodeGroupScanState.chunkedGroupIdx); |
| 193 | if (nodeGroupScanState.nextRowToScan >= |
| 194 | chunkedGroup->getNumRows() + chunkedGroup->getStartRowIdx()) { |
| 195 | nodeGroupScanState.chunkedGroupIdx++; |
| 196 | if (nodeGroupScanState.chunkedGroupIdx >= chunkedGroups.getNumGroups(lock)) { |
| 197 | return NODE_GROUP_SCAN_EMPTY_RESULT; |
| 198 | } |
| 199 | ChunkedNodeGroup* currentChunkedGroup = |
| 200 | chunkedGroups.getGroup(lock, nodeGroupScanState.chunkedGroupIdx); |
| 201 | initializeScanStateForChunkedGroup(state, currentChunkedGroup); |
| 202 | } |
| 203 | const auto& chunkedGroupToScan = |
| 204 | *chunkedGroups.getGroup(lock, nodeGroupScanState.chunkedGroupIdx); |
| 205 | DASSERT(nodeGroupScanState.nextRowToScan >= chunkedGroupToScan.getStartRowIdx()); |
| 206 | const auto rowIdxInChunkToScan = |
| 207 | nodeGroupScanState.nextRowToScan - chunkedGroupToScan.getStartRowIdx(); |
| 208 | const auto numRowsToScan = |
| 209 | std::min(chunkedGroupToScan.getNumRows() - rowIdxInChunkToScan, DEFAULT_VECTOR_CAPACITY); |
| 210 | bool enableSemiMask = |
| 211 | state.source == TableScanSource::COMMITTED && state.semiMask && state.semiMask->isEnabled(); |
| 212 | if (enableSemiMask) { |
| 213 | const auto startNodeOffset = nodeGroupScanState.nextRowToScan + |
| 214 | StorageUtils::getStartOffsetOfNodeGroup(state.nodeGroupIdx); |
| 215 | NodeTable::applySemiMaskFilter(state, startNodeOffset, numRowsToScan, |
| 216 | state.outState->getSelVectorUnsafe()); |
| 217 | if (state.outState->getSelVector().getSelSize() == 0) { |
| 218 | state.nodeGroupScanState->nextRowToScan += numRowsToScan; |
| 219 | return NodeGroupScanResult{nodeGroupScanState.nextRowToScan, 0}; |
| 220 | } |
| 221 | } |
| 222 | chunkedGroupToScan.scan(transaction, state, nodeGroupScanState, rowIdxInChunkToScan, |
| 223 | numRowsToScan); |
| 224 | const auto startRow = nodeGroupScanState.nextRowToScan; |
| 225 | nodeGroupScanState.nextRowToScan += numRowsToScan; |
| 226 | return NodeGroupScanResult{startRow, numRowsToScan}; |
| 227 | } |
| 228 | |
| 229 | NodeGroupScanResult NodeGroup::scan(Transaction* transaction, TableScanState& state, |
| 230 | offset_t startOffsetInGroup, offset_t numRowsToScan) const { |
no test coverage detected