| 340 | } |
| 341 | |
| 342 | void ListChunkData::finalize() { |
| 343 | // rewrite the column chunk for better scanning performance |
| 344 | auto newColumnChunk = ColumnChunkFactory::createColumnChunkData(getMemoryManager(), |
| 345 | dataType.copy(), enableCompression, capacity, ResidencyState::IN_MEMORY); |
| 346 | uint64_t totalListLen = dataColumnChunk->getNumValues(); |
| 347 | uint64_t resizeThreshold = dataColumnChunk->getCapacity() / 2; |
| 348 | // if the list is not very long, we do not need to rewrite |
| 349 | if (totalListLen < resizeThreshold) { |
| 350 | return; |
| 351 | } |
| 352 | // if we do not trigger random write, we do not need to rewrite |
| 353 | if (!checkOffsetSortedAsc) { |
| 354 | return; |
| 355 | } |
| 356 | // if the list is in ascending order, we do not need to rewrite |
| 357 | if (isOffsetsConsecutiveAndSortedAscending(0, numValues)) { |
| 358 | return; |
| 359 | } |
| 360 | auto& newListChunk = newColumnChunk->cast<ListChunkData>(); |
| 361 | newListChunk.resize(numValues); |
| 362 | newListChunk.getDataColumnChunk()->resize(totalListLen); |
| 363 | auto newDataColumnChunk = newListChunk.getDataColumnChunk(); |
| 364 | newDataColumnChunk->resize(totalListLen); |
| 365 | offset_t offsetInChunk = 0; |
| 366 | offset_t currentIndex = 0; |
| 367 | for (auto i = 0u; i < numValues; i++) { |
| 368 | if (nullData->isNull(i)) { |
| 369 | newListChunk.appendNullList(); |
| 370 | } else { |
| 371 | auto startOffset = getListStartOffset(i); |
| 372 | auto listSize = getListSize(i); |
| 373 | newDataColumnChunk->append(dataColumnChunk.get(), startOffset, listSize); |
| 374 | offsetInChunk += listSize; |
| 375 | newListChunk.nullData->setNull(currentIndex, false); |
| 376 | newListChunk.sizeColumnChunk->setValue<list_size_t>(listSize, currentIndex); |
| 377 | newListChunk.setOffsetChunkValue(offsetInChunk, currentIndex); |
| 378 | } |
| 379 | currentIndex++; |
| 380 | } |
| 381 | DASSERT(newListChunk.sanityCheck()); |
| 382 | // Move offsets, null, data from newListChunk to this column chunk. And release indices. |
| 383 | resetFromOtherChunk(&newListChunk); |
| 384 | } |
| 385 | |
| 386 | void ListChunkData::resetFromOtherChunk(ListChunkData* other) { |
| 387 | nullData = std::move(other->nullData); |
no test coverage detected