From 334f9115589cd231227863657e493fcd8304d2f0 Mon Sep 17 00:00:00 2001 From: oflatt Date: Fri, 25 Oct 2024 14:36:06 -0700 Subject: [PATCH 1/2] switch to deterministic hasher --- src/util.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/util.rs b/src/util.rs index 47191c23..8f39ba20 100644 --- a/src/util.rs +++ b/src/util.rs @@ -2,15 +2,21 @@ use std::fmt::Display; +use symbol_table::DeterministicHashBuilder; + use crate::core::SpecializedPrimitive; #[allow(unused_imports)] use crate::*; pub(crate) type BuildHasher = std::hash::BuildHasherDefault; -pub(crate) type HashMap = hashbrown::HashMap; -pub(crate) type HashSet = hashbrown::HashSet; +/// Use deterministic hasher to make egglog deterministic +/// when rule application order matters. +pub(crate) type HashMap = hashbrown::HashMap; +pub(crate) type HashSet = hashbrown::HashSet; +/// Index maps don't need deterministic hashing, +/// since iteration order is guaranteed to be insertion order. pub type IndexMap = indexmap::IndexMap; pub type IndexSet = indexmap::IndexSet; From c9727fc816cf81b9974ac5128983abaf05f7611b Mon Sep 17 00:00:00 2001 From: oflatt Date: Fri, 25 Oct 2024 14:41:03 -0700 Subject: [PATCH 2/2] our own build hasher that implements clone --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/function/table.rs | 2 +- src/util.rs | 20 ++++++++++++++------ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcfa1b29..4029cdde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -449,6 +449,7 @@ dependencies = [ "codspeed-criterion-compat", "egraph-serialize", "env_logger", + "foldhash", "generic_symbolic_expressions", "getrandom", "glob", @@ -543,6 +544,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "generic-array" version = "0.14.7" diff --git a/Cargo.toml b/Cargo.toml index c1664496..4ed63d39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ num-integer = "0.1.45" num-rational = "0.4.1" num-traits = "0.2.15" smallvec = "1.11" +foldhash = "0.1.3" generic_symbolic_expressions = "5.0.4" diff --git a/src/function/table.rs b/src/function/table.rs index 300cd851..178f03a5 100644 --- a/src/function/table.rs +++ b/src/function/table.rs @@ -35,7 +35,7 @@ use std::{ use hashbrown::raw::RawTable; use super::binary_search::binary_search_table_by_key; -use crate::{util::BuildHasher as BH, TupleOutput, Value, ValueVec}; +use crate::{util::BuildFxHasher as BH, TupleOutput, Value, ValueVec}; type Offset = usize; diff --git a/src/util.rs b/src/util.rs index 8f39ba20..db74b186 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,14 +1,22 @@ #![allow(unused)] -use std::fmt::Display; - -use symbol_table::DeterministicHashBuilder; +use std::{fmt::Display, hash::BuildHasher}; use crate::core::SpecializedPrimitive; #[allow(unused_imports)] use crate::*; -pub(crate) type BuildHasher = std::hash::BuildHasherDefault; +pub(crate) type BuildFxHasher = std::hash::BuildHasherDefault; + +#[derive(Debug, Clone, Default)] +pub struct DeterministicHashBuilder; + +impl BuildHasher for DeterministicHashBuilder { + type Hasher = foldhash::fast::FoldHasher; + fn build_hasher(&self) -> Self::Hasher { + foldhash::fast::FixedState::with_seed(0).build_hasher() + } +} /// Use deterministic hasher to make egglog deterministic /// when rule application order matters. @@ -17,8 +25,8 @@ pub(crate) type HashSet = hashbrown::HashSet; /// Index maps don't need deterministic hashing, /// since iteration order is guaranteed to be insertion order. -pub type IndexMap = indexmap::IndexMap; -pub type IndexSet = indexmap::IndexSet; +pub type IndexMap = indexmap::IndexMap; +pub type IndexSet = indexmap::IndexSet; pub(crate) fn concat_vecs(to: &mut Vec, mut from: Vec) { if to.len() < from.len() {