| 33 | namespace bytedance::bolt::aggregate::prestosql { |
| 34 | |
| 35 | AddressableNonNullValueList::Entry AddressableNonNullValueList::append( |
| 36 | const DecodedVector& decoded, |
| 37 | vector_size_t index, |
| 38 | HashStringAllocator* allocator) { |
| 39 | ByteOutputStream stream(allocator); |
| 40 | if (!firstHeader_) { |
| 41 | // An array_agg or related begins with an allocation of 5 words and |
| 42 | // 4 bytes for header. This is compact for small arrays (up to 5 |
| 43 | // bigints) and efficient if needs to be extended (stores 4 bigints |
| 44 | // and a next pointer. This could be adaptive, with smaller initial |
| 45 | // sizes for lots of small arrays. |
| 46 | static constexpr int kInitialSize = 44; |
| 47 | |
| 48 | currentPosition_ = allocator->newWrite(stream, kInitialSize); |
| 49 | firstHeader_ = currentPosition_.header; |
| 50 | } else { |
| 51 | allocator->extendWrite(currentPosition_, stream); |
| 52 | } |
| 53 | |
| 54 | const auto hash = decoded.base()->hashValueAt(decoded.index(index)); |
| 55 | |
| 56 | const auto originalSize = stream.size(); |
| 57 | |
| 58 | // Write value. |
| 59 | exec::ContainerRowSerdeOptions options{}; |
| 60 | exec::ContainerRowSerde::serialize( |
| 61 | *decoded.base(), decoded.index(index), stream, options); |
| 62 | |
| 63 | ++size_; |
| 64 | |
| 65 | auto startAndFinish = allocator->finishWrite(stream, 1024); |
| 66 | currentPosition_ = startAndFinish.second; |
| 67 | |
| 68 | const auto writtenSize = stream.size() - originalSize; |
| 69 | |
| 70 | return {startAndFinish.first, writtenSize, hash}; |
| 71 | } |
| 72 | |
| 73 | namespace { |
| 74 |
nothing calls this directly
no test coverage detected