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

Class FirstTimeBitmapWriter

cpp/src/arrow/util/bitmap_writer.h:82–183  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

80};
81
82class FirstTimeBitmapWriter {
83 // Like BitmapWriter, but any bit values *following* the bits written
84 // might be clobbered. It is hence faster than BitmapWriter, and can
85 // also avoid false positives with Valgrind.
86
87 public:
88 FirstTimeBitmapWriter(uint8_t* bitmap, int64_t start_offset, int64_t length)
89 : bitmap_(bitmap), position_(0), length_(length) {
90 current_byte_ = 0;
91 byte_offset_ = start_offset / 8;
92 bit_mask_ = bit_util::kBitmask[start_offset % 8];
93 if (length > 0) {
94 current_byte_ =
95 bitmap[byte_offset_] & bit_util::kPrecedingBitmask[start_offset % 8];
96 } else {
97 current_byte_ = 0;
98 }
99 }
100
101 /// Appends number_of_bits from word to valid_bits and valid_bits_offset.
102 ///
103 /// \param[in] word The LSB bitmap to append. Any bits past number_of_bits are assumed
104 /// to be unset (i.e. 0).
105 /// \param[in] number_of_bits The number of bits to append from word.
106 void AppendWord(uint64_t word, int64_t number_of_bits) {
107 if (ARROW_PREDICT_FALSE(number_of_bits == 0)) {
108 return;
109 }
110
111 // Location that the first byte needs to be written to.
112 uint8_t* append_position = bitmap_ + byte_offset_;
113
114 // Update state variables except for current_byte_ here.
115 position_ += number_of_bits;
116 int64_t bit_offset = std::countr_zero(static_cast<uint32_t>(bit_mask_));
117 bit_mask_ = bit_util::kBitmask[(bit_offset + number_of_bits) % 8];
118 byte_offset_ += (bit_offset + number_of_bits) / 8;
119
120 if (bit_offset != 0) {
121 // We are in the middle of the byte. This code updates the byte and shifts
122 // bits appropriately within word so it can be memcpy'd below.
123 int64_t bits_to_carry = 8 - bit_offset;
124 // Carry over bits from word to current_byte_. We assume any extra bits in word
125 // unset so no additional accounting is needed for when number_of_bits <
126 // bits_to_carry.
127 current_byte_ |= (word & bit_util::kPrecedingBitmask[bits_to_carry]) << bit_offset;
128 // Check if everything is transferred into current_byte_.
129 if (ARROW_PREDICT_FALSE(number_of_bits < bits_to_carry)) {
130 return;
131 }
132 *append_position = current_byte_;
133 append_position++;
134 // Move the carry bits off of word.
135 word = word >> bits_to_carry;
136 number_of_bits -= bits_to_carry;
137 }
138 word = bit_util::ToLittleEndian(word);
139 int64_t bytes_for_word = ::arrow::bit_util::BytesForBits(number_of_bits);

Callers 1

TESTFunction · 0.70

Calls

no outgoing calls

Tested by 1

TESTFunction · 0.56