MCPcopy Create free account
hub / github.com/apache/arrow / RunGetSpaced

Function RunGetSpaced

cpp/src/arrow/util/rle_encoding_internal.h:886–944  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

884/// Overload for GetSpaced for a single run in a RleDecoder
885template <typename Converter, typename BitRunReader, typename BitRun, typename value_type>
886auto RunGetSpaced(Converter* converter, typename Converter::out_type* out,
887 rle_size_t batch_size, rle_size_t null_count,
888 rle_size_t value_bit_width, BitRunReader* validity_reader,
889 BitRun* validity_run,
890 RleRunDecoder<value_type>* decoder) -> GetSpacedResult<rle_size_t> {
891 ARROW_DCHECK_GT(batch_size, 0);
892 // The equality case is handled in the main loop in GetSpaced
893 ARROW_DCHECK_LT(null_count, batch_size);
894
895 auto batch = BatchCounter::FromBatchSizeAndNulls(batch_size, null_count);
896
897 const rle_size_t values_available = decoder->remaining();
898 ARROW_DCHECK_GT(values_available, 0);
899 auto values_remaining_run = [&]() {
900 auto out = values_available - batch.values_read();
901 ARROW_DCHECK_GE(out, 0);
902 return out;
903 };
904
905 // Consume as much as possible from the repeated run.
906 // We only need to count the number of nulls and non-nulls because we can fill in the
907 // same value for nulls and non-nulls.
908 // This proves to be a big efficiency win.
909 while (values_remaining_run() > 0 && !batch.is_done()) {
910 ARROW_DCHECK_GE(validity_run->length, 0);
911 ARROW_DCHECK_LT(validity_run->length, max_size_for_v<rle_size_t>);
912 ARROW_DCHECK_LE(validity_run->length, batch.total_remaining());
913 const auto& validity_run_size = static_cast<rle_size_t>(validity_run->length);
914
915 if (validity_run->set) {
916 // We may end the current RLE run in the middle of the validity run
917 auto update_size = std::min(validity_run_size, values_remaining_run());
918 batch.AccrueReadValues(update_size);
919 validity_run->length -= update_size;
920 } else {
921 // We can consume all nulls here because it does not matter if we consume on this
922 // RLE run, or an a next encoded run. The value filled does not matter.
923 auto update_size = std::min(validity_run_size, batch.null_remaining());
924 batch.AccrueReadNulls(update_size);
925 validity_run->length -= update_size;
926 }
927
928 if (ARROW_PREDICT_TRUE(validity_run->length == 0)) {
929 *validity_run = validity_reader->NextRun();
930 }
931 }
932
933 const value_type value = decoder->value();
934 if (ARROW_PREDICT_FALSE(!converter->InputIsValid(value))) {
935 return {0, 0};
936 }
937 converter->WriteRepeated(out, out + batch.total_read(), value);
938 const auto actual_values_read = decoder->Advance(batch.values_read());
939 // We always cropped the number of values_read by the remaining values in the run.
940 // What's more the RLE decoder should not encounter any errors.
941 ARROW_DCHECK_EQ(actual_values_read, batch.values_read());
942
943 return {/* .values_read= */ batch.values_read(), /* .null_read= */ batch.null_read()};

Callers 2

GetSpacedMethod · 0.85
GetBatchWithDictMethod · 0.85

Calls 15

values_readMethod · 0.80
is_doneMethod · 0.80
total_remainingMethod · 0.80
AccrueReadValuesMethod · 0.80
null_remainingMethod · 0.80
AccrueReadNullsMethod · 0.80
total_readMethod · 0.80
null_readMethod · 0.80
values_remainingMethod · 0.80
buffer_sizeFunction · 0.50
remainingMethod · 0.45
NextRunMethod · 0.45

Tested by

no test coverage detected