1//! Timers, memory measurement and the hash function used by the tables.23use std::hash::{BuildHasherDefault, Hasher};45/// CPU time consumed by the calling thread (seconds), via CLOCK_THREAD_CPUTIME_ID.6pub fn thread_cpu_s() -> f64 {7 let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };8 unsafe {9 libc::clock_gettime(libc::CLOCK_THREAD_CPUTIME_ID, &mut ts);10 }11 ts.tv_sec as f64 + ts.tv_nsec as f64 * 1e-912}1314/// Process CPU time (user + system) via getrusage.15pub fn process_cpu_s() -> f64 {16 let mut ru: libc::rusage = unsafe { std::mem::zeroed() };17 unsafe {18 libc::getrusage(libc::RUSAGE_SELF, &mut ru);19 }20 let tv = |t: libc::timeval| t.tv_sec as f64 + t.tv_usec as f64 * 1e-6;21 tv(ru.ru_utime) + tv(ru.ru_stime)22}2324/// Peak resident set size in bytes (ru_maxrss is bytes on macOS, kilobytes on Linux).25pub fn peak_rss_bytes() -> u64 {26 let mut ru: libc::rusage = unsafe { std::mem::zeroed() };27 unsafe {28 libc::getrusage(libc::RUSAGE_SELF, &mut ru);29 }30 let v = ru.ru_maxrss as u64;31 if cfg!(target_os = "macos") {32 v33 } else {34 v * 102435 }36}3738/// Cheap multiplicative hasher for u64 keys that are already well-mixed field residues.39#[derive(Default, Clone, Copy)]40pub struct FxHasher {41 h: u64,42}4344impl Hasher for FxHasher {45 #[inline(always)]46 fn finish(&self) -> u64 {47 self.h48 }49 #[inline(always)]50 fn write(&mut self, bytes: &[u8]) {51 for b in bytes {52 self.h = (self.h.rotate_left(5) ^ (*b as u64)).wrapping_mul(0x517cc1b727220a95);53 }54 }55 #[inline(always)]56 fn write_u64(&mut self, i: u64) {57 let z = i.wrapping_mul(0x9E3779B97F4A7C15);58 self.h = z ^ (z >> 32);59 }60}6162pub type FxBuild = BuildHasherDefault<FxHasher>;63