@@ -127,6 +127,72 @@ simpleColumnBytes(const TypePtr& colType, int64_t numRows, int64_t numNulls) {
127127 (numRows - numNulls) * fixedTypeWidth (colType->kind ()); // values
128128}
129129
130+ int64_t variableWidthColumnBytes (
131+ int64_t numRows,
132+ int64_t numNulls,
133+ int64_t valueBytes) {
134+ return 4 + static_cast <int64_t >(kVariableWidth .size ()) + // header
135+ 4 + // rowCount
136+ 4 * numRows + // offsets
137+ 1 + // nullFlag
138+ (numNulls > 0 ? bits::nbytes (numRows) : 0 ) + // null bitmap
139+ 4 + // valueBytes
140+ valueBytes; // values
141+ }
142+
143+ std::vector<int64_t > computeVariableWidthDataSizes (
144+ const std::vector<PartitionedVectorPtr>& partitionedVectors,
145+ uint32_t numPartitions) {
146+ std::vector<int64_t > dataSizes (numPartitions, 0 );
147+ for (const auto & partitionedVector : partitionedVectors) {
148+ auto encoding = partitionedVector->baseVector ()->encoding ();
149+ switch (encoding) {
150+ case VectorEncoding::Simple::FLAT : {
151+ auto * flatVector =
152+ partitionedVector->as <PartitionedFlatVector<StringView>>();
153+ VELOX_DCHECK_NOT_NULL (flatVector);
154+
155+ const auto * rawValues =
156+ flatVector->baseVector ()->asFlatVector <StringView>()->rawValues ();
157+ const auto * rawNulls =
158+ flatVector->baseVector ()->asFlatVector <StringView>()->rawNulls ();
159+ const auto * rawPartitionOffsets =
160+ partitionedVector->rawPartitionOffsets ();
161+
162+ vector_size_t lastOffset = 0 ;
163+ for (uint32_t p = 0 ; p < numPartitions; ++p) {
164+ const auto offset = rawPartitionOffsets[p];
165+ if (!rawNulls) {
166+ for (auto i = lastOffset; i < offset; ++i) {
167+ dataSizes[p] += rawValues[i].size ();
168+ }
169+ } else {
170+ for (auto i = lastOffset; i < offset; ++i) {
171+ if (!bits::isBitNull (rawNulls, i)) {
172+ dataSizes[p] += rawValues[i].size ();
173+ }
174+ }
175+ }
176+ lastOffset = offset;
177+ }
178+ break ;
179+ }
180+ case VectorEncoding::Simple::BIASED :
181+ case VectorEncoding::Simple::CONSTANT :
182+ case VectorEncoding::Simple::DICTIONARY :
183+ case VectorEncoding::Simple::SEQUENCE :
184+ VELOX_NYI (
185+ " Unsupported vector encoding for PrestoIterativePartitioningSerializer: " ,
186+ encoding);
187+ default :
188+ VELOX_UNSUPPORTED (
189+ " Invalid vector encoding for PrestoIterativePartitioningSerializer: " ,
190+ encoding);
191+ }
192+ }
193+ return dataSizes;
194+ }
195+
130196// / Returns per-partition exact byte counts for one column (all partitions).
131197// / Recurses into nested ROW columns.
132198// /
@@ -167,9 +233,17 @@ std::vector<int64_t> computeColumnFlushSizes(
167233 }
168234 break ;
169235
170- case TypeKind::TIMESTAMP :
171236 case TypeKind::VARCHAR :
172- case TypeKind::VARBINARY :
237+ case TypeKind::VARBINARY : {
238+ const auto dataSizes =
239+ computeVariableWidthDataSizes (columnVectors, numPartitions);
240+ for (uint32_t p : nonEmptyPartitions) {
241+ sizes[p] = variableWidthColumnBytes (
242+ rowsPerPartition[p], nullCounts[p], dataSizes[p]);
243+ }
244+ break ;
245+ }
246+ case TypeKind::TIMESTAMP :
173247 case TypeKind::ARRAY :
174248 case TypeKind::MAP :
175249 VELOX_NYI (
@@ -478,9 +552,12 @@ void PrestoIterativePartitioningSerializer::flushColumn(
478552 partitionedVectors, colType, nonEmptyPartitions, outputStreams);
479553 break ;
480554
481- case TypeKind::TIMESTAMP :
482555 case TypeKind::VARCHAR :
483556 case TypeKind::VARBINARY :
557+ flushVariableWidthColumn (
558+ partitionedVectors, colType, nonEmptyPartitions, outputStreams);
559+ break ;
560+ case TypeKind::TIMESTAMP :
484561 case TypeKind::ROW :
485562 case TypeKind::ARRAY :
486563 case TypeKind::MAP :
@@ -507,6 +584,25 @@ void PrestoIterativePartitioningSerializer::flushSimpleColumn(
507584 }
508585}
509586
587+ void PrestoIterativePartitioningSerializer::flushVariableWidthColumn (
588+ const std::vector<PartitionedVectorPtr>& partitionedVectors,
589+ const TypePtr& colType,
590+ const std::vector<uint32_t >& nonEmptyPartitions,
591+ const std::vector<IOBufOutputStream*>& outputStreams) const {
592+ flushHeader (typeToEncodingName (colType), nonEmptyPartitions, outputStreams);
593+ flushRowCounts (nonEmptyPartitions, outputStreams);
594+ const auto dataSizes = flushOffsets (partitionedVectors, outputStreams);
595+ flushNulls (partitionedVectors, nonEmptyPartitions, outputStreams);
596+
597+ for (uint32_t p : nonEmptyPartitions) {
598+ writeInt32 (outputStreams[p], dataSizes[p]);
599+ }
600+
601+ for (size_t i = 0 ; i < partitionedVectors.size (); i++) {
602+ flushSingleVariableWidthVector (partitionedVectors[i], outputStreams);
603+ }
604+ }
605+
510606template <TypeKind kind>
511607void PrestoIterativePartitioningSerializer::flushSingleFlatVector (
512608 const PartitionedVectorPtr& partitionedVector,
@@ -590,6 +686,60 @@ void PrestoIterativePartitioningSerializer::flushSingleSimpleVector(
590686 }
591687}
592688
689+ void PrestoIterativePartitioningSerializer::flushSingleVariableWidthFlatVector (
690+ const PartitionedVectorPtr& partitionedVector,
691+ const std::vector<IOBufOutputStream*>& outputStreams) const {
692+ auto * flatVector = partitionedVector->as <PartitionedFlatVector<StringView>>();
693+ VELOX_DCHECK_NOT_NULL (flatVector);
694+ const auto * rawValues =
695+ flatVector->baseVector ()->as <FlatVector<StringView>>()->rawValues ();
696+ const auto * rawNulls = flatVector->baseVector ()->rawNulls ();
697+ const auto * partitionOffsets = flatVector->rawPartitionOffsets ();
698+
699+ vector_size_t lastOffset = 0 ;
700+ for (uint32_t p = 0 ; p < numPartitions_; ++p) {
701+ const auto offset = partitionOffsets[p];
702+ if (outputStreams[p] != nullptr ) {
703+ if (!rawNulls) {
704+ for (auto i = lastOffset; i < offset; ++i) {
705+ const auto & value = rawValues[i];
706+ outputStreams[p]->write (value.data (), value.size ());
707+ }
708+ } else {
709+ for (auto i = lastOffset; i < offset; ++i) {
710+ if (!bits::isBitNull (rawNulls, i)) {
711+ const auto & value = rawValues[i];
712+ outputStreams[p]->write (value.data (), value.size ());
713+ }
714+ }
715+ }
716+ lastOffset = offset;
717+ }
718+ }
719+ }
720+
721+ void PrestoIterativePartitioningSerializer::flushSingleVariableWidthVector (
722+ const PartitionedVectorPtr& partitionedVector,
723+ const std::vector<IOBufOutputStream*>& outputStreams) const {
724+ auto encoding = partitionedVector->baseVector ()->encoding ();
725+ switch (encoding) {
726+ case VectorEncoding::Simple::FLAT :
727+ flushSingleVariableWidthFlatVector (partitionedVector, outputStreams);
728+ break ;
729+ case VectorEncoding::Simple::BIASED :
730+ case VectorEncoding::Simple::CONSTANT :
731+ case VectorEncoding::Simple::DICTIONARY :
732+ case VectorEncoding::Simple::SEQUENCE :
733+ VELOX_NYI (
734+ " Unsupported vector encoding for PrestoIterativePartitioningSerializer: " ,
735+ encoding);
736+ default :
737+ VELOX_UNSUPPORTED (
738+ " Invalid vector encoding for PrestoIterativePartitioningSerializer: " ,
739+ encoding);
740+ }
741+ }
742+
593743// ---------------------------------------------------------------------------
594744// Column building blocks
595745// ---------------------------------------------------------------------------
@@ -729,4 +879,55 @@ void PrestoIterativePartitioningSerializer::flushSequentialOffsets(
729879 }
730880}
731881
882+ std::vector<int32_t > PrestoIterativePartitioningSerializer::flushOffsets (
883+ const std::vector<PartitionedVectorPtr>& partitionedVectors,
884+ const std::vector<IOBufOutputStream*>& outputStreams) const {
885+ std::vector<int32_t > offsets (numPartitions_, 0 );
886+ for (const auto & partitionedVector : partitionedVectors) {
887+ auto encoding = partitionedVector->baseVector ()->encoding ();
888+ switch (encoding) {
889+ case VectorEncoding::Simple::FLAT : {
890+ auto * flatVector =
891+ partitionedVector->as <PartitionedFlatVector<StringView>>();
892+ VELOX_DCHECK_NOT_NULL (flatVector);
893+ const auto * rawValues =
894+ flatVector->baseVector ()->as <FlatVector<StringView>>()->rawValues ();
895+ const auto * rawNulls = flatVector->baseVector ()->rawNulls ();
896+ const auto * partitionOffsets = flatVector->rawPartitionOffsets ();
897+ vector_size_t lastOffset = 0 ;
898+ for (uint32_t p = 0 ; p < numPartitions_; ++p) {
899+ const auto offset = partitionOffsets[p];
900+ if (outputStreams[p] != nullptr ) {
901+ if (!rawNulls) {
902+ for (auto i = lastOffset; i < offset; ++i) {
903+ offsets[p] += rawValues[i].size ();
904+ writeInt32 (outputStreams[p], offsets[p]);
905+ }
906+ } else {
907+ for (auto i = lastOffset; i < offset; ++i) {
908+ if (!bits::isBitNull (rawNulls, i)) {
909+ offsets[p] += rawValues[i].size ();
910+ }
911+ writeInt32 (outputStreams[p], offsets[p]);
912+ }
913+ }
914+ }
915+ lastOffset = offset;
916+ }
917+ } break ;
918+ case VectorEncoding::Simple::BIASED :
919+ case VectorEncoding::Simple::CONSTANT :
920+ case VectorEncoding::Simple::DICTIONARY :
921+ case VectorEncoding::Simple::SEQUENCE :
922+ VELOX_NYI (
923+ " Unsupported vector encoding for PrestoIterativePartitioningSerializer: " ,
924+ encoding);
925+ default :
926+ VELOX_UNSUPPORTED (
927+ " Invalid vector encoding for PrestoIterativePartitioningSerializer: " ,
928+ encoding);
929+ }
930+ }
931+ return offsets;
932+ }
732933} // namespace facebook::velox::serializer::presto
0 commit comments