Skip to content

fix: replace __uint128_t with portable 64-bit decomposition in c_shard_info.pyx (MSVC build failure) - #950

Open
mykaul wants to merge 1 commit into
scylladb:masterfrom
mykaul:fix/c-shard-info-msvc-uint128
Open

fix: replace __uint128_t with portable 64-bit decomposition in c_shard_info.pyx (MSVC build failure)#950
mykaul wants to merge 1 commit into
scylladb:masterfrom
mykaul:fix/c-shard-info-msvc-uint128

Conversation

@mykaul

@mykaul mykaul commented Jul 30, 2026

Copy link
Copy Markdown

Bug

cassandra/c_shard_info.pyx computes the shard id for a token by taking the
high 64 bits of a 64x32-bit product:

cdef int shardId = (<__uint128_t>biased_token * self.shards_count) >> 64;

__uint128_t is a GCC/Clang compiler-builtin extension type — it is not part
of the C or C++ standard, and it is not a type Cython itself understands
natively (the cdef extern from *: ctypedef unsigned int __uint128_t block
just tells Cython to trust that the C compiler has it). MSVC has no 128-bit
integer type at all, so on Windows the generated c_shard_info.c fails to
compile with error C2065: '__uint128_t': undeclared identifier, followed by
a cascade of C2146/C2059 syntax errors. This breaks Windows wheel builds for
any change that touches (or merely triggers a rebuild of) this extension.

Fix

Replace the 128-bit multiply with a portable multiply-high decomposition that
uses only 64-bit arithmetic (uint64_t), splitting the multiplication into
32-bit halves — the same technique already used by the pure-Python fallback
in cassandra/shard_info.py (_ShardingInfo.shard_id_from_token). This
compiles identically on GCC, Clang, and MSVC.

Verification

  • Built the extension locally with Cython + gcc and confirmed it compiles
    cleanly.
  • Directly compared the compiled extension's shard_id_from_token output
    against the pure-Python fallback (cassandra.shard_info._ShardingInfo)
    across 2,000,000 randomized (shards_count, sharding_ignore_msb, token)
    triples, covering the full int64 token range — 0 mismatches.
  • Ran the full tests/unit/ suite (770 passed, 38 skipped, 0 failed) plus
    the sharding-specific tests (tests/unit/test_shard_aware.py,
    tests/unit/test_connection.py::TestShardawarePortGenerator,
    tests/unit/test_host_connection_pool.py) — all passing, with the real
    compiled extension in place.

Context

This was originally found while investigating a Windows wheel-build CI
failure on an unrelated PR (#806, a ResponseFuture.__init__ cleanup). The
__uint128_t bug is pre-existing, independent of that PR's changes, and
would affect the Windows build of any PR that happens to trigger a rebuild
of this extension — so it's being fixed here as its own standalone, focused
PR rather than folded into #806.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@mykaul, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Pro Plus

Run ID: e506e955-729a-4cb3-88a1-a5b5629b699a

📥 Commits

Reviewing files that changed from the base of the PR and between 1d7e601 and 13728e7.

📒 Files selected for processing (1)
  • cassandra/c_shard_info.pyx

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Replaces a compiler-specific 128-bit multiplication with a portable 64-bit decomposition for shard calculation.

Changes:

  • Removes the unsupported __uint128_t declaration.
  • Computes the product’s high bits using portable 64-bit arithmetic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…d_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 scylladb#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>
@mykaul
mykaul force-pushed the fix/c-shard-info-msvc-uint128 branch from ab57ac7 to 13728e7 Compare August 9, 2026 16:15
@mykaul
mykaul marked this pull request as ready for review August 14, 2026 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants