Skip to content

Commit ab57ac7

Browse files
mykaulclaude
andcommitted
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 <noreply@anthropic.com>
1 parent 9b5b037 commit ab57ac7

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

cassandra/c_shard_info.pyx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414

1515
from libc.stdint cimport INT64_MIN, UINT32_MAX, uint64_t, int64_t
1616

17-
cdef extern from *:
18-
ctypedef unsigned int __uint128_t
19-
2017
cdef class ShardingInfo():
2118
cdef readonly int shards_count
2219
cdef readonly unicode partitioner
@@ -39,5 +36,15 @@ cdef class ShardingInfo():
3936
def shard_id_from_token(self, int64_t token_input):
4037
cdef uint64_t biased_token = token_input + (<uint64_t>1 << 63);
4138
biased_token <<= self.sharding_ignore_msb;
42-
cdef int shardId = (<__uint128_t>biased_token * self.shards_count) >> 64;
39+
# Compute (biased_token * shards_count) >> 64, i.e. the high 64 bits of the
40+
# 64x32-bit product, using only 64-bit arithmetic. This used to rely on the
41+
# GCC/Clang-only __uint128_t extension type, which MSVC does not support at
42+
# all (no 128-bit integer type), causing a compile error on Windows builds.
43+
# The split below is a standard, portable multiply-high decomposition and is
44+
# numerically identical to the previous 128-bit computation.
45+
cdef uint64_t shards_count = <uint64_t>self.shards_count
46+
cdef uint64_t low_product = (biased_token & <uint64_t>UINT32_MAX) * shards_count
47+
cdef uint64_t carry = low_product >> 32
48+
cdef uint64_t mid = (biased_token >> 32) * shards_count + carry
49+
cdef int shardId = <int>(mid >> 32);
4350
return shardId

0 commit comments

Comments
 (0)