| 1874 | } |
| 1875 | |
| 1876 | int DecodeArrow(int num_values, int null_count, const uint8_t* valid_bits, |
| 1877 | int64_t valid_bits_offset, |
| 1878 | typename EncodingTraits<BooleanType>::Accumulator* out) override { |
| 1879 | if (null_count == num_values) { |
| 1880 | PARQUET_THROW_NOT_OK(out->AppendNulls(null_count)); |
| 1881 | return 0; |
| 1882 | } |
| 1883 | constexpr int kBatchSize = 1024; |
| 1884 | std::array<bool, kBatchSize> values; |
| 1885 | const int num_non_null_values = num_values - null_count; |
| 1886 | // Remaining non-null boolean values to read from decoder. |
| 1887 | // We decode from `decoder_` with maximum 1024 size batches. |
| 1888 | int num_remain_non_null_values = num_non_null_values; |
| 1889 | int current_index_in_batch = 0; |
| 1890 | int current_batch_size = 0; |
| 1891 | auto next_boolean_batch = [&]() { |
| 1892 | DCHECK_GT(num_remain_non_null_values, 0); |
| 1893 | DCHECK_EQ(current_index_in_batch, current_batch_size); |
| 1894 | current_batch_size = std::min(num_remain_non_null_values, kBatchSize); |
| 1895 | int decoded_count = decoder_->GetBatch(values.data(), current_batch_size); |
| 1896 | if (ARROW_PREDICT_FALSE(decoded_count != current_batch_size)) { |
| 1897 | // required values is more than values in decoder. |
| 1898 | ParquetException::EofException(); |
| 1899 | } |
| 1900 | num_remain_non_null_values -= current_batch_size; |
| 1901 | current_index_in_batch = 0; |
| 1902 | }; |
| 1903 | |
| 1904 | // Reserve all values including nulls first |
| 1905 | PARQUET_THROW_NOT_OK(out->Reserve(num_values)); |
| 1906 | if (null_count == 0) { |
| 1907 | // Fast-path for not having nulls. |
| 1908 | do { |
| 1909 | next_boolean_batch(); |
| 1910 | PARQUET_THROW_NOT_OK( |
| 1911 | out->AppendValues(values.begin(), values.begin() + current_batch_size)); |
| 1912 | num_values -= current_batch_size; |
| 1913 | // set current_index_in_batch to current_batch_size means |
| 1914 | // the whole batch is totally consumed. |
| 1915 | current_index_in_batch = current_batch_size; |
| 1916 | } while (num_values > 0); |
| 1917 | return num_non_null_values; |
| 1918 | } |
| 1919 | auto next_value = [&]() -> bool { |
| 1920 | if (current_index_in_batch == current_batch_size) { |
| 1921 | next_boolean_batch(); |
| 1922 | DCHECK_GT(current_batch_size, 0); |
| 1923 | } |
| 1924 | DCHECK_LT(current_index_in_batch, current_batch_size); |
| 1925 | bool value = values[current_index_in_batch]; |
| 1926 | ++current_index_in_batch; |
| 1927 | return value; |
| 1928 | }; |
| 1929 | VisitNullBitmapInline( |
| 1930 | valid_bits, valid_bits_offset, num_values, null_count, |
| 1931 | [&]() { out->UnsafeAppend(next_value()); }, [&]() { out->UnsafeAppendNull(); }); |
| 1932 | return num_non_null_values; |
| 1933 | } |
nothing calls this directly
no test coverage detected