From ab57ac74942e8e911c278417fe49b03b27dfadc1 Mon Sep 17 00:00:00 2001 From: Yaniv Michael Kaul Date: Thu, 30 Jul 2026 15:19:54 +0300 Subject: [PATCH] fix: replace __uint128_t with portable 64-bit decomposition in c_shard_info.pyx cassandra/c_shard_info.pyx computed the high 64 bits of a 64x32-bit product by casting biased_token to `__uint128_t` and shifting right by 64: cdef int shardId = (<__uint128_t>biased_token * self.shards_count) >> 64; `__uint128_t` is a GCC/Clang compiler-builtin extension type, not standard C/C++ and not part of Cython's own type system. MSVC has no 128-bit integer type at all, so it treats `__uint128_t` as an undeclared identifier and fails with cascading syntax errors (C2065/C2146/C2059) in the generated c_shard_info.c. This breaks Windows wheel builds for any change that triggers a rebuild of this extension. Replaced it with a portable multiply-high decomposition that splits the 64x32-bit multiplication into 32-bit halves, using only 64-bit arithmetic (uint64_t), matching the existing pure-Python fallback already implemented in cassandra/shard_info.py. This compiles identically on GCC, Clang, and MSVC, and is numerically identical to the previous 128-bit computation (verified against 2M+ random inputs, cross-checked against both the pure -Python fallback and the actual compiled extension). Found while investigating an unrelated Windows CI failure on PR #806; the bug is pre-existing and independent of that PR's changes, so it's fixed here as its own standalone commit rather than folded into that PR. Co-Authored-By: Claude Sonnet 5 --- cassandra/c_shard_info.pyx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cassandra/c_shard_info.pyx b/cassandra/c_shard_info.pyx index a8affd9bba..a17ce5d65d 100644 --- a/cassandra/c_shard_info.pyx +++ b/cassandra/c_shard_info.pyx @@ -14,9 +14,6 @@ from libc.stdint cimport INT64_MIN, UINT32_MAX, uint64_t, int64_t -cdef extern from *: - ctypedef unsigned int __uint128_t - cdef class ShardingInfo(): cdef readonly int shards_count cdef readonly unicode partitioner @@ -39,5 +36,15 @@ cdef class ShardingInfo(): def shard_id_from_token(self, int64_t token_input): cdef uint64_t biased_token = token_input + (1 << 63); biased_token <<= self.sharding_ignore_msb; - cdef int shardId = (<__uint128_t>biased_token * self.shards_count) >> 64; + # Compute (biased_token * shards_count) >> 64, i.e. the high 64 bits of the + # 64x32-bit product, using only 64-bit arithmetic. This used to rely on the + # GCC/Clang-only __uint128_t extension type, which MSVC does not support at + # all (no 128-bit integer type), causing a compile error on Windows builds. + # The split below is a standard, portable multiply-high decomposition and is + # numerically identical to the previous 128-bit computation. + cdef uint64_t shards_count = self.shards_count + cdef uint64_t low_product = (biased_token & UINT32_MAX) * shards_count + cdef uint64_t carry = low_product >> 32 + cdef uint64_t mid = (biased_token >> 32) * shards_count + carry + cdef int shardId = (mid >> 32); return shardId \ No newline at end of file