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));

Reply via email to