This is an automated email from the ASF dual-hosted git repository.
paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git
The following commit(s) were added to refs/heads/main by this push:
new fb43002 fix bit counting for a single byte (#54)
fb43002 is described below
commit fb43002edecfeeb5cd536f64ec35d310d6715ee7
Author: Dewey Dunnington <[email protected]>
AuthorDate: Thu Sep 29 12:31:54 2022 -0300
fix bit counting for a single byte (#54)
---
src/nanoarrow/buffer_inline.h | 11 +++++++----
src/nanoarrow/buffer_test.cc | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/src/nanoarrow/buffer_inline.h b/src/nanoarrow/buffer_inline.h
index e4cb7a8..1d8c02c 100644
--- a/src/nanoarrow/buffer_inline.h
+++ b/src/nanoarrow/buffer_inline.h
@@ -291,17 +291,20 @@ static inline int64_t ArrowBitCountSet(const uint8_t*
bits, int64_t start_offset
const int64_t bytes_begin = i_begin / 8;
const int64_t bytes_end = i_end / 8 + 1;
- const uint8_t first_byte_mask = _ArrowkPrecedingBitmask[i_begin % 8];
- const uint8_t last_byte_mask = _ArrowkTrailingBitmask[i_end % 8];
-
if (bytes_end == bytes_begin + 1) {
// count bits within a single byte
+ const uint8_t first_byte_mask = _ArrowkPrecedingBitmask[i_end % 8];
+ const uint8_t last_byte_mask = _ArrowkTrailingBitmask[i_begin % 8];
+
const uint8_t only_byte_mask =
- i_end % 8 == 0 ? first_byte_mask : (uint8_t)(first_byte_mask |
last_byte_mask);
+ i_end % 8 == 0 ? first_byte_mask : (uint8_t)(first_byte_mask &
last_byte_mask);
+
const uint8_t byte_masked = bits[bytes_begin] & only_byte_mask;
return _ArrowkBytePopcount[byte_masked];
}
+ const uint8_t first_byte_mask = _ArrowkPrecedingBitmask[i_begin % 8];
+ const uint8_t last_byte_mask = _ArrowkTrailingBitmask[i_end % 8];
int64_t count = 0;
// first byte
diff --git a/src/nanoarrow/buffer_test.cc b/src/nanoarrow/buffer_test.cc
index 603e409..76c925d 100644
--- a/src/nanoarrow/buffer_test.cc
+++ b/src/nanoarrow/buffer_test.cc
@@ -307,6 +307,42 @@ TEST(BitmapTest, BitmapTestCountSet) {
EXPECT_EQ(ArrowBitCountSet(bitmap, 23, 1), 1);
}
+TEST(BitmapTest, BitmapTestCountSetSingleByte) {
+ uint8_t bitmap = 0xff;
+
+ // Check starting on a byte boundary
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 0), 0);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 2), 2);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 3), 3);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 4), 4);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 5), 5);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 6), 6);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 7), 7);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 8), 8);
+
+ // Check bits in the middle
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 1, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 2, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 3, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 4, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 5, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 6, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 7, 1), 1);
+
+ // Check ending on a byte boundary
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 0, 8), 8);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 1, 7), 7);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 2, 6), 6);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 3, 5), 5);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 4, 4), 4);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 5, 3), 3);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 6, 2), 2);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 7, 1), 1);
+ EXPECT_EQ(ArrowBitCountSet(&bitmap, 8, 0), 0);
+}
+
TEST(BitmapTest, BitmapTestAppend) {
int8_t test_values[65];
memset(test_values, 0, sizeof(test_values));