Skip to main content

kora_core/
hash.rs

1//! Key hashing and shard routing.
2//!
3//! Provides the two functions that determine which shard owns a given key:
4//! `hash_key` computes a fast non-cryptographic hash (ahash), and
5//! `shard_for_key` maps that hash to a shard index via modular arithmetic.
6//!
7//! These functions sit on the hot path of every command dispatch, so they are
8//! `#[inline]` and allocation-free.
9
10use ahash::AHasher;
11use std::hash::{Hash, Hasher};
12
13/// Hash a key to a u64 using ahash (fast, non-cryptographic).
14#[inline]
15pub fn hash_key(key: &[u8]) -> u64 {
16    let mut hasher = AHasher::default();
17    key.hash(&mut hasher);
18    hasher.finish()
19}
20
21/// Determine which shard owns a given key.
22#[inline]
23pub fn shard_for_key(key: &[u8], shard_count: usize) -> u16 {
24    (hash_key(key) % shard_count as u64) as u16
25}
26
27#[cfg(test)]
28mod tests {
29    use super::*;
30
31    #[test]
32    fn test_deterministic_hashing() {
33        let h1 = hash_key(b"test-key");
34        let h2 = hash_key(b"test-key");
35        assert_eq!(h1, h2);
36    }
37
38    #[test]
39    fn test_different_keys_different_hashes() {
40        let h1 = hash_key(b"key-a");
41        let h2 = hash_key(b"key-b");
42        assert_ne!(h1, h2);
43    }
44
45    #[test]
46    fn test_shard_routing_in_range() {
47        for i in 0..1000u32 {
48            let key = format!("key:{}", i);
49            let shard = shard_for_key(key.as_bytes(), 8);
50            assert!(shard < 8);
51        }
52    }
53}