From cf94433011792145740e7b4abed18ba93e21a5e2 Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Sat, 5 Sep 2026 10:37:28 -0400 Subject: [PATCH] feat: add ArrowResolveChunk16 --- src/nanoarrow/common/inline_buffer.h | 21 +++++++++++++++++++++ src/nanoarrow/common/utils_test.cc | 12 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/nanoarrow/common/inline_buffer.h b/src/nanoarrow/common/inline_buffer.h index c9a78602b..e3d485475 100644 --- a/src/nanoarrow/common/inline_buffer.h +++ b/src/nanoarrow/common/inline_buffer.h @@ -71,6 +71,27 @@ static inline int64_t ArrowResolveChunk32(int32_t index, const int32_t* offsets, return lo; } +static inline int64_t ArrowResolveChunk16(int16_t index, const int16_t* offsets, + int16_t lo, int16_t hi) { + // Similar to std::upper_bound(), but slightly different as our offsets + // array always starts with 0. + int16_t n = hi - lo; + // First iteration does not need to check for n > 1 + // (lo < hi is guaranteed by the precondition). + NANOARROW_DCHECK(n > 1); + do { + const int16_t m = n >> 1; + const int16_t mid = lo + m; + if (index >= offsets[mid]) { + lo = mid; + n -= m; + } else { + n = m; + } + } while (n > 1); + return lo; +} + static inline int64_t _ArrowGrowByFactor(int64_t current_capacity, int64_t new_capacity) { int64_t doubled_capacity = current_capacity * 2; if (doubled_capacity > new_capacity) { diff --git a/src/nanoarrow/common/utils_test.cc b/src/nanoarrow/common/utils_test.cc index 0f8b0218e..d4e43ad57 100644 --- a/src/nanoarrow/common/utils_test.cc +++ b/src/nanoarrow/common/utils_test.cc @@ -783,6 +783,18 @@ TEST(UtilsTest, ArrowResolveChunk32Test) { EXPECT_EQ(ArrowResolveChunk32(5, offsets, 0, n_offsets), 2); } +TEST(UtilsTest, ArrowResolveChunk16Test) { + int16_t offsets[] = {0, 2, 3, 6}; + int16_t n_offsets = 4; + + EXPECT_EQ(ArrowResolveChunk16(0, offsets, 0, n_offsets), 0); + EXPECT_EQ(ArrowResolveChunk16(1, offsets, 0, n_offsets), 0); + EXPECT_EQ(ArrowResolveChunk16(2, offsets, 0, n_offsets), 1); + EXPECT_EQ(ArrowResolveChunk16(3, offsets, 0, n_offsets), 2); + EXPECT_EQ(ArrowResolveChunk16(4, offsets, 0, n_offsets), 2); + EXPECT_EQ(ArrowResolveChunk16(5, offsets, 0, n_offsets), 2); +} + TEST(MaybeTest, ConstructionAndConversion) { using nanoarrow::NA; using nanoarrow::internal::Maybe;