Use the faster bit interleave for encode_quadkey itself

encode_vertex() computed exactly the same thing as encode_quadkey(),
so there is no reason to have both. Give encode_quadkey() the branch-free
implementation, which also speeds up the default encode_index, and have
the shared node code call it directly. The unit test now compares it
against the old bit-at-a-time loop and checks that decode_quadkey()
reverses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2nBqZisxNQfmEmon3vE9v
This commit is contained in:
Claude
2026-09-23 20:02:49 +00:00
parent e1795ebe32
commit 58ad6e3008
6 changed files with 39 additions and 36 deletions
+23 -3
View File
@@ -129,11 +129,31 @@ TEST_CASE("Bit reversal", "bit reversal") {
REQUIRE(bit_reverse(0xF3D912481E6A2C48) == 0x1234567812489BCF);
}
TEST_CASE("Vertex encoding matches quadkey encoding", "[projection]") {
// The bit-at-a-time quadkey encoding that encode_quadkey() used to use
static unsigned long long reference_quadkey(unsigned int wx, unsigned int wy) {
unsigned long long out = 0;
for (int i = 0; i < 32; i++) {
unsigned long long v = ((wx >> (32 - (i + 1))) & 1) << 1;
v |= (wy >> (32 - (i + 1))) & 1;
v = v << (64 - 2 * (i + 1));
out |= v;
}
return out;
}
TEST_CASE("Quadkey encoding", "[projection]") {
unsigned int values[] = {0, 1, 2, 0x7FFFFFFF, 0x80000000, 0xFFFFFFFF, 0x12345678, 0xDEADBEEF};
for (unsigned int x : values) {
for (unsigned int y : values) {
REQUIRE(encode_vertex(x, y) == encode_quadkey(x, y));
REQUIRE(encode_quadkey(x, y) == reference_quadkey(x, y));
unsigned wx, wy;
decode_quadkey(encode_quadkey(x, y), &wx, &wy);
REQUIRE(wx == x);
REQUIRE(wy == y);
}
}
@@ -142,7 +162,7 @@ TEST_CASE("Vertex encoding matches quadkey encoding", "[projection]") {
seed = seed * 6364136223846793005ULL + 1442695040888963407ULL;
unsigned int x = seed >> 32;
unsigned int y = seed;
REQUIRE(encode_vertex(x, y) == encode_quadkey(x, y));
REQUIRE(encode_quadkey(x, y) == reference_quadkey(x, y));
}
}