| 62 | namespace { |
| 63 | template<std::floating_point T> |
| 64 | std::pair<std::unique_ptr<uint8_t[]>, uint64_t> flushCompressedFloats(const CompressionAlg& alg, |
| 65 | PhysicalTypeID dataType, std::span<const uint8_t> buffer, FileHandle* dataFH, |
| 66 | const PageRange& entry, const ColumnChunkMetadata& metadata) { |
| 67 | const auto& castedAlg = dynamic_cast_checked<const FloatCompression<T>&>(alg); |
| 68 | |
| 69 | const auto* floatMetadata = metadata.compMeta.floatMetadata(); |
| 70 | DASSERT(floatMetadata->exceptionCapacity >= floatMetadata->exceptionCount); |
| 71 | |
| 72 | auto valuesRemaining = metadata.numValues; |
| 73 | DASSERT(valuesRemaining <= buffer.size_bytes() / sizeof(T)); |
| 74 | |
| 75 | const size_t exceptionBufferSize = |
| 76 | EncodeException<T>::numPagesFromExceptions(floatMetadata->exceptionCapacity) * |
| 77 | LBUG_PAGE_SIZE; |
| 78 | auto exceptionBuffer = std::make_unique<uint8_t[]>(exceptionBufferSize); |
| 79 | std::byte* exceptionBufferCursor = reinterpret_cast<std::byte*>(exceptionBuffer.get()); |
| 80 | |
| 81 | const auto numValuesPerPage = metadata.compMeta.numValues(LBUG_PAGE_SIZE, dataType); |
| 82 | DASSERT(numValuesPerPage * metadata.getNumDataPages(dataType) >= metadata.numValues); |
| 83 | |
| 84 | const auto compressedBuffer = std::make_unique<uint8_t[]>(LBUG_PAGE_SIZE); |
| 85 | const uint8_t* bufferCursor = buffer.data(); |
| 86 | auto numPages = 0u; |
| 87 | size_t remainingExceptionBufferSize = exceptionBufferSize; |
| 88 | RUNTIME_CHECK(size_t totalExceptionCount = 0); |
| 89 | |
| 90 | while (valuesRemaining > 0) { |
| 91 | uint64_t pageExceptionCount = 0; |
| 92 | (void)castedAlg.compressNextPageWithExceptions(bufferCursor, |
| 93 | metadata.numValues - valuesRemaining, valuesRemaining, compressedBuffer.get(), |
| 94 | LBUG_PAGE_SIZE, EncodeExceptionView<T>{exceptionBufferCursor}, |
| 95 | remainingExceptionBufferSize, pageExceptionCount, metadata.compMeta); |
| 96 | |
| 97 | exceptionBufferCursor += pageExceptionCount * EncodeException<T>::sizeInBytes(); |
| 98 | remainingExceptionBufferSize -= pageExceptionCount * EncodeException<T>::sizeInBytes(); |
| 99 | RUNTIME_CHECK(totalExceptionCount += pageExceptionCount); |
| 100 | |
| 101 | // Avoid underflows (when data is compressed to nothing, numValuesPerPage may be |
| 102 | // UINT64_MAX) |
| 103 | if (numValuesPerPage > valuesRemaining) { |
| 104 | valuesRemaining = 0; |
| 105 | } else { |
| 106 | valuesRemaining -= numValuesPerPage; |
| 107 | } |
| 108 | DASSERT(numPages < entry.numPages); |
| 109 | DASSERT(dataFH->getNumPages() >= entry.startPageIdx + numPages); |
| 110 | dataFH->writePageToFile(compressedBuffer.get(), entry.startPageIdx + numPages); |
| 111 | numPages++; |
| 112 | } |
| 113 | |
| 114 | DASSERT(totalExceptionCount == floatMetadata->exceptionCount); |
| 115 | |
| 116 | return {std::move(exceptionBuffer), exceptionBufferSize}; |
| 117 | } |
| 118 | |
| 119 | template<std::floating_point T> |
| 120 | void flushALPExceptions(std::span<const uint8_t> exceptionBuffer, FileHandle* dataFH, |
nothing calls this directly
no test coverage detected