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

Function RunGetSpaced

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

Source from the content-addressed store, hash-verified

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