| 271 | } |
| 272 | |
| 273 | bool BitmapEquals(const uint8_t* left, int64_t left_offset, const uint8_t* right, |
| 274 | int64_t right_offset, int64_t length) { |
| 275 | if (left_offset % 8 == 0 && right_offset % 8 == 0) { |
| 276 | // byte aligned, can use memcmp |
| 277 | bool bytes_equal = |
| 278 | std::memcmp(left + left_offset / 8, right + right_offset / 8, length / 8) == 0; |
| 279 | if (!bytes_equal) { |
| 280 | return false; |
| 281 | } |
| 282 | for (int64_t i = (length / 8) * 8; i < length; ++i) { |
| 283 | if (bit_util::GetBit(left, left_offset + i) != |
| 284 | bit_util::GetBit(right, right_offset + i)) { |
| 285 | return false; |
| 286 | } |
| 287 | } |
| 288 | return true; |
| 289 | } |
| 290 | |
| 291 | // Unaligned slow case |
| 292 | auto left_reader = internal::BitmapWordReader<uint64_t>(left, left_offset, length); |
| 293 | auto right_reader = internal::BitmapWordReader<uint64_t>(right, right_offset, length); |
| 294 | |
| 295 | auto nwords = left_reader.words(); |
| 296 | while (nwords--) { |
| 297 | if (left_reader.NextWord() != right_reader.NextWord()) { |
| 298 | return false; |
| 299 | } |
| 300 | } |
| 301 | auto nbytes = left_reader.trailing_bytes(); |
| 302 | while (nbytes--) { |
| 303 | int valid_bits; |
| 304 | if (left_reader.NextTrailingByte(valid_bits) != |
| 305 | right_reader.NextTrailingByte(valid_bits)) { |
| 306 | return false; |
| 307 | } |
| 308 | } |
| 309 | return true; |
| 310 | } |
| 311 | |
| 312 | bool OptionalBitmapEquals(const uint8_t* left, int64_t left_offset, const uint8_t* right, |
| 313 | int64_t right_offset, int64_t length) { |