diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2025-02-13 15:28:09 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2025-02-13 15:28:09 -0500 |
commit | 3515a4b00013d71863eb4d5769c640f12bec6ebe (patch) | |
tree | fe58e040369855f75dbc44255e7907f8da3a5aa1 | |
parent | baa45ab5393b780939de6721a88962fd2293b121 (diff) | |
download | bfs-3515a4b00013d71863eb4d5769c640f12bec6ebe.tar.xz |
-rw-r--r-- | src/trie.c | 52 |
1 files changed, 23 insertions, 29 deletions
@@ -391,12 +391,6 @@ static void trie_node_free(struct trie *trie, struct trie_node *node, size_t siz varena_free(&trie->nodes, node, size); } -#if ENDIAN_NATIVE == ENDIAN_LITTLE -# define TRIE_BSWAP(n) bswap(n) -#elif ENDIAN_NATIVE == ENDIAN_BIG -# define TRIE_BSWAP(n) (n) -#endif - /** Find the offset of the first nibble that differs between two keys. */ static size_t trie_mismatch(const struct trie_leaf *rep, const void *key, size_t length) { if (!rep) { @@ -410,32 +404,32 @@ static size_t trie_mismatch(const struct trie_leaf *rep, const void *key, size_t const char *rep_bytes = rep->key; const char *key_bytes = key; - size_t i = 0; - for (size_t chunk = sizeof(chunk); i + chunk <= length; i += chunk) { - size_t rep_chunk, key_chunk; - memcpy(&rep_chunk, rep_bytes + i, sizeof(rep_chunk)); - memcpy(&key_chunk, key_bytes + i, sizeof(key_chunk)); - - if (rep_chunk != key_chunk) { -#ifdef TRIE_BSWAP - size_t diff = TRIE_BSWAP(rep_chunk ^ key_chunk); - i *= 2; - i += leading_zeros(diff) / 4; - return i; -#else - break; -#endif - } - } + size_t ret = 0, i = 0; - for (; i < length; ++i) { - unsigned char diff = rep_bytes[i] ^ key_bytes[i]; - if (diff) { - return 2 * i + !(diff >> 4); - } +#define CHUNK(n) CHUNK_(uint##n##_t, load8_beu##n) +#define CHUNK_(type, load8) \ + while (length - i >= sizeof(type)) { \ + type rep_chunk = load8(rep_bytes + i); \ + type key_chunk = load8(key_bytes + i); \ + type diff = rep_chunk ^ key_chunk; \ + ret += leading_zeros(diff) / 4; \ + if (diff) { \ + return ret; \ + } \ + i += sizeof(type); \ } - return 2 * i; +#if SIZE_WIDTH >= 64 + CHUNK(64); +#endif + CHUNK(32); + CHUNK(16); + CHUNK(8); + +#undef CHUNK_ +#undef CHUNK + + return ret; } /** |