Path: blob/main/cranelift/codegen/src/constant_hash.rs
1693 views
//! Runtime support for precomputed constant hash tables.1//!2//! The shared module with the same name can generate constant hash tables using open addressing3//! and quadratic probing.4//!5//! The hash tables are arrays that are guaranteed to:6//!7//! - Have a power-of-two size.8//! - Contain at least one empty slot.9//!10//! This module provides runtime support for lookups in these tables.1112// Re-export entities from constant_hash for simplicity of use.13pub use cranelift_codegen_shared::constant_hash::*;1415/// Trait that must be implemented by the entries in a constant hash table.16pub trait Table<K: Copy + Eq> {17/// Get the number of entries in this table which must be a power of two.18fn len(&self) -> usize;1920/// Get the key corresponding to the entry at `idx`, or `None` if the entry is empty.21/// The `idx` must be in range.22fn key(&self, idx: usize) -> Option<K>;23}2425/// Look for `key` in `table`.26///27/// The provided `hash` value must have been computed from `key` using the same hash function that28/// was used to construct the table.29///30/// Returns `Ok(idx)` with the table index containing the found entry, or `Err(idx)` with the empty31/// sentinel entry if no entry could be found.32pub fn probe<K: Copy + Eq, T: Table<K> + ?Sized>(33table: &T,34key: K,35hash: usize,36) -> Result<usize, usize> {37debug_assert!(table.len().is_power_of_two());38let mask = table.len() - 1;3940let mut idx = hash;41let mut step = 0;4243loop {44idx &= mask;4546match table.key(idx) {47None => return Err(idx),48Some(k) if k == key => return Ok(idx),49_ => {}50}5152// Quadratic probing.53step += 1;5455// When `table.len()` is a power of two, it can be proven that `idx` will visit all56// entries. This means that this loop will always terminate if the hash table has even57// one unused entry.58debug_assert!(step < table.len());59idx += step;60}61}626364