diff --git a/hydroflow/tests/surface_lattice_bimorphism.rs b/hydroflow/tests/surface_lattice_bimorphism.rs index d3b6fd4211a..2332851bb10 100644 --- a/hydroflow/tests/surface_lattice_bimorphism.rs +++ b/hydroflow/tests/surface_lattice_bimorphism.rs @@ -8,7 +8,7 @@ use lattices::map_union::{KeyedBimorphism, MapUnionHashMap, MapUnionSingletonMap use lattices::set_union::{CartesianProductBimorphism, SetUnionHashSet, SetUnionSingletonSet}; use lattices::GhtType; use multiplatform_test::multiplatform_test; -use variadics::hash_set::VariadicHashSet; +use variadics::variadic_sets::VariadicHashSet; use variadics::{var_expr, CloneVariadic}; #[multiplatform_test] @@ -156,17 +156,6 @@ fn test_ght_join_bimorphism() { >>::DeepJoinLatticeBimorphism; type MyBim = GhtBimorphism; - // let mut hf = hydroflow_syntax! { - // lhs = source_iter_delta([ - // var_expr!(123, 2, 5, "hello"), - // var_expr!(50, 1, 1, "hi"), - // var_expr!(5, 1, 7, "hi"), - // var_expr!(5, 1, 7, "bye"), - // ]) - // -> map(|row| MyGhtATrie::new_from([row])) - // -> state::<'tick, MyGhtATrie>(); - // }; - let mut hf = hydroflow_syntax! { lhs = source_iter_delta([ var_expr!(123, 2, 5, "hello"), diff --git a/hydroflow/tests/surface_lattice_generalized_hash_trie.rs b/hydroflow/tests/surface_lattice_generalized_hash_trie.rs index d25bbbf502a..c2af0222f1a 100644 --- a/hydroflow/tests/surface_lattice_generalized_hash_trie.rs +++ b/hydroflow/tests/surface_lattice_generalized_hash_trie.rs @@ -4,7 +4,7 @@ use hydroflow::lattices::ght_lattice::{DeepJoinLatticeBimorphism, GhtBimorphism} use hydroflow::lattices::GhtType; use hydroflow::util::collect_ready; use hydroflow::variadics::{var_expr, var_type}; -use variadics::hash_set::VariadicHashSet; // Import the Insert trait +use variadics::variadic_sets::VariadicHashSet; // Import the Insert trait #[test] fn test_basic() { diff --git a/lattices/src/ght.rs b/lattices/src/ght.rs index dfb285031c2..4c23034dde0 100644 --- a/lattices/src/ght.rs +++ b/lattices/src/ght.rs @@ -4,7 +4,7 @@ use std::hash::Hash; use std::marker::PhantomData; use sealed::sealed; -use variadics::hash_set::VariadicHashSet; +use variadics::variadic_sets::VariadicSet; use variadics::{ var_args, var_type, PartialEqVariadic, RefVariadic, Split, SplitBySuffix, VariadicExt, }; @@ -24,7 +24,7 @@ pub trait GeneralizedHashTrieNode: Default { /// This type is the same in all nodes of the trie. type ValType: VariadicExt + Eq + Hash + Clone; /// The type that holds the data in the leaves - type Storage: TupleSet + Default + IntoIterator; + type Storage: VariadicSet + Default + IntoIterator; /// SuffixSchema variadic: the suffix of the schema *from this node of the trie /// downward*. The first entry in this variadic is of type Head. @@ -206,7 +206,7 @@ where impl FromIterator for GhtLeaf where Schema: Eq + Hash, - Storage: TupleSet + Default + FromIterator, + Storage: VariadicSet + Default + FromIterator, { fn from_iter>(iter: Iter) -> Self { let elements = iter.into_iter().collect(); @@ -218,72 +218,13 @@ where } } -/// Trait for a set of Tuples -pub trait TupleSet { - /// The Schema (aka Variadic type) associated with tuples in this set - type Schema: PartialEqVariadic; - - /// Insert an element into the set - fn insert(&mut self, element: Self::Schema) -> bool; - - /// Iterate over the elements of the set - fn iter(&self) -> impl Iterator::AsRefVar<'_>>; - - /// Return number of elements in the set - fn len(&self) -> usize; - - /// Return true if empty - fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// iterate and drain items from the set - fn drain(&mut self) -> impl Iterator; - - /// Check for containment - fn contains(&self, value: ::AsRefVar<'_>) -> bool; -} - -impl TupleSet for VariadicHashSet -where - Schema: 'static + Eq + Hash + PartialEqVariadic, - for<'a> ::AsRefVar<'a>: Hash, -{ - type Schema = Schema; - - fn insert(&mut self, element: Self::Schema) -> bool { - self.insert(element) - } - - fn iter(&self) -> impl Iterator::AsRefVar<'_>> { - self.iter() - } - - fn len(&self) -> usize { - self.len() - } - - /// Return true if empty - fn is_empty(&self) -> bool { - self.len() == 0 - } - - fn drain(&mut self) -> impl Iterator { - self.drain() - } - - fn contains(&self, value: ::AsRefVar<'_>) -> bool { - self.get(value).is_some() - } -} - /// leaf node of a HashTrie #[derive(Debug, PartialEq, Eq, Clone)] // #[repr(transparent)] pub struct GhtLeaf where Schema: Eq + Hash, - Storage: TupleSet, + Storage: VariadicSet, { pub(crate) elements: Storage, pub(crate) forced: bool, @@ -292,7 +233,7 @@ where impl Default for GhtLeaf where Schema: Eq + Hash, - Storage: TupleSet + Default, + Storage: VariadicSet + Default, { fn default() -> Self { let elements = Default::default(); @@ -319,7 +260,7 @@ where var_type!(ValHead, ...ValRest): Clone + Eq + Hash + PartialEqVariadic, >::Prefix: Eq + Hash + Clone, // for<'a> Schema::AsRefVar<'a>: PartialEq, - Storage: TupleSet + Default + IntoIterator, + Storage: VariadicSet + Default + IntoIterator, { type Schema = Schema; type SuffixSchema = var_type!(ValHead, ...ValRest); @@ -389,7 +330,7 @@ where + Clone // + SplitBySuffix + PartialEqVariadic, - Storage: TupleSet + Default + IntoIterator, + Storage: VariadicSet + Default + IntoIterator, // ValHead: Clone + Eq + Hash, // var_type!(ValHead, ...ValRest): Clone + Eq + Hash + PartialEqVariadic, // >::Prefix: Eq + Hash + Clone, @@ -510,7 +451,7 @@ where ValType: Eq + Hash + Clone + PartialEqVariadic, >::Prefix: Eq + Hash + Clone, GhtLeaf: GeneralizedHashTrieNode, - Storage: TupleSet, + Storage: VariadicSet, { /// Type returned by [`Self::get`]. type Get = GhtLeaf; @@ -621,7 +562,7 @@ where Head, as GeneralizedHashTrieNode>::SuffixSchema, )>, - Storage: 'static + TupleSet + Default, + Storage: 'static + VariadicSet + Default, { fn take_containing_leaf( &mut self, @@ -666,7 +607,7 @@ where Schema: 'static + Hash + Clone + Eq + PartialEqVariadic + SplitBySuffix, ValType: 'static + Hash + Clone + Eq + VariadicExt + PartialEqVariadic, GhtLeaf: GeneralizedHashTrieNode, - Storage: 'static + TupleSet, + Storage: 'static + VariadicSet, { fn take_containing_leaf( &mut self, @@ -752,7 +693,7 @@ where // for<'a> SuffixSchema::AsRefVar<'a>: Split, ValType: Split, KeyPrefixRef::UnRefVar: PartialEqVariadic, - Storage: 'static + TupleSet, + Storage: 'static + VariadicSet, { type Item = Schema; fn prefix_iter<'a>( @@ -787,17 +728,17 @@ macro_rules! GhtRowTypeWithSchema { // Empty key (Leaf) (() => $( $z:ty ),* => $schema:ty ) => ( - $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),* ), $crate::variadics::hash_set::VariadicHashSet<$schema> > + $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),* ), $crate::variadics::variadic_sets::VariadicHashSet<$schema> > ); // Singleton key & Empty val (Inner over Leaf) ($a:ty => () => $schema:ty ) => ( - $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, (), $crate::variadics::hash_set::VariadicHashSet<$schema> >> + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, (), $crate::variadics::variadic_sets::VariadicHashSet<$schema> >> ); // Singleton key (Inner over Leaf) ($a:ty => $( $z:ty ),* => $schema:ty ) => ( - $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::variadics::hash_set::VariadicHashSet<$schema> >> + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::variadics::variadic_sets::VariadicHashSet<$schema> >> ); // Recursive case with empty val @@ -823,17 +764,17 @@ macro_rules! GhtColumnTypeWithSchema { // Empty key (Leaf) (() => $( $z:ty ),* => $schema:ty ) => ( - $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),* ), $crate::ght_lazy::VariadicColumnarSet<$schema> > + $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),* ), $crate::variadics::variadic_sets::VariadicColumnarSet<$schema> > ); // Singleton key & Empty val (Inner over Leaf) ($a:ty => () => $schema:ty ) => ( - $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, (), $crate::ght_lazy::VariadicColumnarSet<$schema> >> + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, (), $crate::variadics::variadic_sets::VariadicColumnarSet<$schema> >> ); // Singleton key (Inner over Leaf) ($a:ty => $( $z:ty ),* => $schema:ty ) => ( - $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::ght_lazy::VariadicColumnarSet<$schema> >> + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::variadics::variadic_sets::VariadicColumnarSet<$schema> >> ); // Recursive case with empty val diff --git a/lattices/src/ght_lattice.rs b/lattices/src/ght_lattice.rs index c3e145b4dc4..eeb49b95816 100644 --- a/lattices/src/ght_lattice.rs +++ b/lattices/src/ght_lattice.rs @@ -3,9 +3,10 @@ use std::cmp::Ordering; use std::collections::HashMap; use std::hash::Hash; +use variadics::variadic_sets::VariadicSet; use variadics::{var_expr, var_type, CloneVariadic, PartialEqVariadic, SplitBySuffix, VariadicExt}; -use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf, TupleSet}; +use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf}; use crate::{IsBot, IsTop, LatticeBimorphism, LatticeOrd, Merge}; ////////////////////////// @@ -51,7 +52,7 @@ impl Merge> for GhtLeaf where Schema: Eq + Hash, - Storage: TupleSet + Extend + IntoIterator, + Storage: VariadicSet + Extend + IntoIterator, { fn merge(&mut self, other: GhtLeaf) -> bool { let old_len = self.elements.len(); @@ -170,7 +171,7 @@ impl PartialOrd + PartialEq, + Storage: VariadicSet + PartialEq, { fn partial_cmp(&self, other: &GhtLeaf) -> Option { match self.elements.len().cmp(&other.elements.len()) { @@ -228,7 +229,7 @@ impl LatticeOrd + PartialEq, + Storage: VariadicSet + PartialEq, { } @@ -257,7 +258,7 @@ impl IsBot for GhtLeaf, + Storage: VariadicSet, { fn is_bot(&self) -> bool { self.elements.is_empty() @@ -289,7 +290,7 @@ impl IsTop for GhtLeaf, + Storage: VariadicSet, { fn is_top(&self) -> bool { false @@ -484,7 +485,7 @@ where NodeA: 'static + GeneralizedHashTrieNode, NodeB: 'static + GeneralizedHashTrieNode, (NodeA, NodeB): DeepJoinLatticeBimorphism, - Storage: TupleSet, + Storage: VariadicSet, { type DeepJoinLatticeBimorphism = GhtNodeKeyedBimorphism< <(NodeA, NodeB) as DeepJoinLatticeBimorphism>::DeepJoinLatticeBimorphism, @@ -501,9 +502,9 @@ where ValTypeA: 'static + VariadicExt + Eq + Hash, // + AsRefVariadicPartialEq SchemaB: 'static + VariadicExt + Eq + Hash + SplitBySuffix, /* + AsRefVariadicPartialEq */ ValTypeB: 'static + VariadicExt + Eq + Hash, // + AsRefVariadicPartialEq - StorageA: TupleSet, - StorageB: TupleSet, - StorageOut: TupleSet, + StorageA: VariadicSet, + StorageB: VariadicSet, + StorageOut: VariadicSet, for<'x> SchemaA::AsRefVar<'x>: CloneVariadic, for<'x> SchemaB::AsRefVar<'x>: CloneVariadic, var_type!(...SchemaA, ...ValTypeB): Eq + Hash, diff --git a/lattices/src/ght_lazy.rs b/lattices/src/ght_lazy.rs index 7a6dc1f927b..b1af45d3d5b 100644 --- a/lattices/src/ght_lazy.rs +++ b/lattices/src/ght_lazy.rs @@ -2,11 +2,10 @@ use std::hash::Hash; use std::marker::PhantomData; use sealed::sealed; -use variadics::{ - var_expr, var_type, PartialEqVariadic, Split, SplitBySuffix, VariadicExt, VecVariadic, -}; +use variadics::variadic_sets::VariadicSet; +use variadics::{var_expr, var_type, PartialEqVariadic, Split, SplitBySuffix, VariadicExt}; -use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf, GhtTakeLeaf, TupleSet}; +use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf, GhtTakeLeaf}; // Strategies for Get on a ColtNode: // 1. ColtNode returns different type for var_type!(GhtInner>) (drops First). @@ -76,7 +75,7 @@ where Schema: SplitBySuffix, >::Prefix: Eq + Hash + Clone, >::Prefix: Eq + Hash + Clone, - Storage: TupleSet + Storage: VariadicSet + Default // + Iterator + IntoIterator, GhtLeaf: GeneralizedHashTrieNode, @@ -183,7 +182,7 @@ where GhtLeaf: ColumnLazyTrieNode, Schema: Clone + Hash + Eq + VariadicExt, SuffixSchema: Clone + Hash + Eq + VariadicExt, - Storage: TupleSet, + Storage: VariadicSet, { type Schema = Schema; type Head = Rest::Head; @@ -209,7 +208,7 @@ where GhtLeaf: ColumnLazyTrieNode, Schema: Clone + Hash + Eq + VariadicExt, SuffixSchema: Clone + Hash + Eq + VariadicExt, - Storage: TupleSet, + Storage: VariadicSet, { fn merge(&mut self, _inner_to_merge: T) { panic!(); @@ -269,7 +268,7 @@ where Head: Eq + Hash + Clone, Schema: Eq + Hash + Clone + PartialEqVariadic, ValType: Eq + Hash + Clone + PartialEqVariadic, - Storage: TupleSet, + Storage: VariadicSet, GhtLeaf: GeneralizedHashTrieNode, Schema: 'static + Eq + VariadicExt + Hash + Clone + SplitBySuffix + PartialEqVariadic, >::Prefix: Eq + Hash + Clone, @@ -306,7 +305,7 @@ where Head: Eq + Hash + Clone, Schema: Eq + Hash + Clone + PartialEqVariadic, ValType: Eq + Hash + Clone + PartialEqVariadic, - Storage: TupleSet, + Storage: VariadicSet, GhtLeaf: GeneralizedHashTrieNode, Schema: 'static + Eq + VariadicExt + Hash + Clone + SplitBySuffix + PartialEqVariadic, >::Prefix: Eq + Hash + Clone, @@ -350,7 +349,7 @@ where GhtLeaf: GeneralizedHashTrieNode, Head: Clone + Eq + Hash, Schema: Clone + Eq + Hash + VariadicExt, - Storage: TupleSet, + Storage: VariadicSet, { fn merge(&mut self, inner_to_merge: GhtInner>) { crate::Merge::merge(self.0, inner_to_merge); @@ -468,7 +467,7 @@ where pub trait ForestFindLeaf where Schema: Eq + Hash + VariadicExt + PartialEqVariadic, - Storage: TupleSet, + Storage: VariadicSet, { /// find a matching leaf in the forest fn find_containing_leaf( @@ -507,7 +506,7 @@ where impl ForestFindLeaf for var_type!() where Schema: Eq + Hash + VariadicExt + PartialEqVariadic, - Storage: TupleSet, + Storage: VariadicSet, { fn find_containing_leaf( &self, @@ -516,111 +515,3 @@ where None } } - -/// Column storage for Variadic tuples of type Schema -/// An alternative to VariadicHashSet -#[derive(Default)] -pub struct VariadicColumnarSet -where - Schema: VariadicExt, -{ - columns: Schema::AsVec, - last_offset: usize, -} - -impl TupleSet for VariadicColumnarSet -where - Schema: PartialEqVariadic, -{ - type Schema = Schema; - - fn insert(&mut self, element: Self::Schema) -> bool { - if self.last_offset == 0 { - self.columns = element.as_vec() - } else { - self.columns.push(element); - } - self.last_offset += 1; - true - } - - fn iter(&self) -> impl Iterator::AsRefVar<'_>> { - self.columns.zip_vecs() - } - - fn len(&self) -> usize { - self.last_offset - } - - fn drain(&mut self) -> impl Iterator { - self.last_offset = 0; - self.columns.drain(0..) - } - - fn contains(&self, value: ::AsRefVar<'_>) -> bool { - self.iter() - .any(|t| ::eq_ref(t, value)) - } -} - -impl IntoIterator for VariadicColumnarSet -where - Schema: PartialEqVariadic, -{ - type Item = Schema; - type IntoIter = ::IntoZip; - - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.columns.into_zip() - } -} - -impl std::fmt::Debug for VariadicColumnarSet -where - T: std::fmt::Debug + VariadicExt + PartialEqVariadic, - for<'a> T::AsRefVar<'a>: Hash + std::fmt::Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_set().entries(self.iter()).finish() - } -} - -// THIS CODE ADAPTED FROM hashbrown::HashMap -impl Extend for VariadicColumnarSet -where - K: Eq + Hash + PartialEqVariadic, - for<'a> K::AsRefVar<'a>: Hash, - // for<'a> S::Hasher: Fn(&'a K) -> u64, - // A: Allocator, -{ - // #[cfg_attr(feature = "inline-more", inline)] - fn extend>(&mut self, iter: T) { - let iter = iter.into_iter(); - // self.table.reserve(reserve, hasher); - iter.for_each(move |k| { - self.insert(k); - }); - } - - // #[inline] - // #[cfg(feature = "nightly")] - // fn extend_one(&mut self, (k, v): (K, V)) { - // self.insert(k, v); - // } - - // #[inline] - // #[cfg(feature = "nightly")] - // fn extend_reserve(&mut self, additional: usize) { - // // Keys may be already present or show multiple times in the iterator. - // // Reserve the entire hint lower bound if the map is empty. - // // Otherwise reserve half the hint (rounded up), so the map - // // will only resize twice in the worst case. - // let reserve = if self.is_empty() { - // additional - // } else { - // (additional + 1) / 2 - // }; - // self.reserve(reserve); - // } -} diff --git a/lattices/src/ght_test.rs b/lattices/src/ght_test.rs index ba1a8500a97..8b042af6a59 100644 --- a/lattices/src/ght_test.rs +++ b/lattices/src/ght_test.rs @@ -3,18 +3,16 @@ mod test { use std::collections::HashSet; use std::io::{self, Write}; - use variadics::hash_set::VariadicHashSet; + use variadics::variadic_sets::{VariadicColumnarSet, VariadicHashSet, VariadicSet}; use variadics::{var_expr, var_type, VariadicExt}; - use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtLeaf, GhtPrefixIter, TupleSet}; + use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtLeaf, GhtPrefixIter}; use crate::ght_lattice::{ // DeepJoinLatticeBimorphism, GhtBimorphism, GhtCartesianProductBimorphism, // GhtNodeKeyedBimorphism, GhtValTypeProductBimorphism, }; - use crate::ght_lazy::{ - ColtNode, ColumnLazyTrieNode, ForestFindLeaf, GhtForest, VariadicColumnarSet, - }; // GhtForestStruct}; + use crate::ght_lazy::{ColtNode, ColumnLazyTrieNode, ForestFindLeaf, GhtForest}; /* GhtForestStruct}; */ use crate::{GhtForestType, GhtType, LatticeBimorphism, Merge, NaiveLatticeOrd}; #[test] diff --git a/variadics/src/hash_set.rs b/variadics/src/hash_set.rs deleted file mode 100644 index db81e90d669..00000000000 --- a/variadics/src/hash_set.rs +++ /dev/null @@ -1,209 +0,0 @@ -use std::fmt; -use std::hash::{BuildHasher, Hash, RandomState}; - -use hashbrown::hash_table::{Entry, HashTable}; - -use crate::{PartialEqVariadic, VariadicExt}; - -/// HashSet that stores Variadics of owned values but allows -/// for lookups with RefVariadics as well -#[derive(Clone)] -pub struct VariadicHashSet { - table: HashTable, - hasher: S, -} - -impl VariadicHashSet { - /// Creates a new `VariadicHashSet` with a default hasher. - pub fn new() -> Self { - Self { - table: HashTable::new(), - hasher: RandomState::default(), - } - } -} - -impl Default for VariadicHashSet { - fn default() -> Self { - Self::new() - } -} - -impl fmt::Debug for VariadicHashSet -where - T: fmt::Debug + VariadicExt + PartialEqVariadic, - for<'a> T::AsRefVar<'a>: Hash + fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_set().entries(self.iter()).finish() - } -} - -impl VariadicHashSet -where - T: VariadicExt + PartialEqVariadic, - for<'a> T::AsRefVar<'a>: Hash, - S: BuildHasher, -{ - fn get_hash(hasher: &S, ref_var: T::AsRefVar<'_>) -> u64 { - hasher.hash_one(ref_var) - // let mut hasher = hasher.build_hasher(); - // ref_var.hash(&mut hasher); - // hasher.finish() - } - - /// given a RefVariadic lookup key, get a RefVariadic version of a tuple in the set - pub fn get<'a>(&'a self, ref_var: T::AsRefVar<'_>) -> Option<&'a T> { - let hash = Self::get_hash(&self.hasher, ref_var); - self.table.find(hash, |item| { - ::eq_ref(ref_var, item.as_ref_var()) - }) - } - - /// insert a tuple - pub fn insert(&mut self, element: T) -> bool { - let hash = Self::get_hash(&self.hasher, element.as_ref_var()); - let entry = self.table.entry( - hash, - |item| ::eq(&element, item), - |item| Self::get_hash(&self.hasher, item.as_ref_var()), - ); - match entry { - Entry::Occupied(_occupied_entry) => false, - Entry::Vacant(vacant_entry) => { - vacant_entry.insert(element); - true - } - } - } - - /// return the number of tuples in the set - pub fn len(&self) -> usize { - self.table.len() - } - - /// return the number of tuples in the set - pub fn is_empty(&self) -> bool { - self.table.len() == 0 - } - - /// drain the set: iterate and remove the tuples without deallocating - pub fn drain(&mut self) -> hashbrown::hash_table::Drain<'_, T> { - self.table.drain() - } - - /// iterate through the set - pub fn iter(&self) -> impl Iterator> { - self.table.iter().map(|item| item.as_ref_var()) - } -} - -impl IntoIterator for VariadicHashSet -where - T: VariadicExt + PartialEqVariadic, -{ - type Item = T; - type IntoIter = hashbrown::hash_table::IntoIter; - - #[inline] - fn into_iter(self) -> Self::IntoIter { - self.table.into_iter() - } -} - -impl VariadicHashSet { - /// allocate a new VariadicHashSet with a specific hasher - pub fn with_hasher(hasher: S) -> Self { - Self { - table: HashTable::new(), - hasher, - } - } - /// allocate a new VariadicHashSet with a specific hasher and capacity - pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self { - Self { - table: HashTable::with_capacity(capacity), - hasher, - } - } -} - -// THIS CODE ADAPTED FROM hashbrown::HashMap -impl Extend for VariadicHashSet -where - K: Eq + Hash + PartialEqVariadic, - S: BuildHasher, - for<'a> K::AsRefVar<'a>: Hash, - // for<'a> S::Hasher: Fn(&'a K) -> u64, - // A: Allocator, -{ - // #[cfg_attr(feature = "inline-more", inline)] - fn extend>(&mut self, iter: T) { - // Keys may be already present or show multiple times in the iterator. - // Reserve the entire hint lower bound if the map is empty. - // Otherwise reserve half the hint (rounded up), so the map - // will only resize twice in the worst case. - let iter = iter.into_iter(); - // let reserve = - if self.is_empty() { - iter.size_hint().0 - } else { - (iter.size_hint().0 + 1) / 2 - }; - // let hasher = self.hasher.build_hasher(); - // self.table.reserve(reserve, hasher); - iter.for_each(move |k| { - self.insert(k); - }); - } - - // #[inline] - // #[cfg(feature = "nightly")] - // fn extend_one(&mut self, (k, v): (K, V)) { - // self.insert(k, v); - // } - - // #[inline] - // #[cfg(feature = "nightly")] - // fn extend_reserve(&mut self, additional: usize) { - // // Keys may be already present or show multiple times in the iterator. - // // Reserve the entire hint lower bound if the map is empty. - // // Otherwise reserve half the hint (rounded up), so the map - // // will only resize twice in the worst case. - // let reserve = if self.is_empty() { - // additional - // } else { - // (additional + 1) / 2 - // }; - // self.reserve(reserve); - // } -} - -impl PartialEq for VariadicHashSet -where - T: Eq + Hash + PartialEqVariadic, - S: BuildHasher, - for<'a> T::AsRefVar<'a>: Hash, -{ - fn eq(&self, other: &Self) -> bool { - if self.len() != other.len() { - return false; - } - - self.iter().all(|key| other.get(key).is_some()) - } -} - -impl FromIterator for VariadicHashSet -where - T: Eq + Hash + PartialEqVariadic, - S: BuildHasher + Default, - for<'a> T::AsRefVar<'a>: Hash, - // A: Default + Allocator, -{ - fn from_iter>(iter: I) -> Self { - let mut set = Self::with_hasher(Default::default()); - set.extend(iter); - set - } -} diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index af30baeab31..d016d022c0e 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -12,7 +12,7 @@ #![doc = include_str!("../var_args.md")] /// VariadicHashSet module -pub mod hash_set; +pub mod variadic_sets; use std::any::Any; use std::ops::RangeBounds; diff --git a/variadics/src/variadic_sets.rs b/variadics/src/variadic_sets.rs index 4fff8f00d7f..8ace205f18c 100644 --- a/variadics/src/variadic_sets.rs +++ b/variadics/src/variadic_sets.rs @@ -5,6 +5,95 @@ use hashbrown::hash_table::{Entry, HashTable}; use crate::{PartialEqVariadic, VariadicExt, VecVariadic}; +/// Trait for a set of Tuples +pub trait VariadicSet { + /// The Schema (aka Variadic type) associated with tuples in this set + type Schema: PartialEqVariadic; + + /// Insert an element into the set + fn insert(&mut self, element: Self::Schema) -> bool; + + /// Iterate over the elements of the set + fn iter(&self) -> impl Iterator::AsRefVar<'_>>; + + /// Return number of elements in the set + fn len(&self) -> usize; + + /// Return true if empty + fn is_empty(&self) -> bool; + + /// iterate and drain items from the set + fn drain(&mut self) -> impl Iterator; + + /// Check for containment + fn contains(&self, value: ::AsRefVar<'_>) -> bool; +} + +// impl TupleSet for VariadicHashSet +// where +// Schema: 'static + Eq + Hash + PartialEqVariadic, +// for<'a> ::AsRefVar<'a>: Hash, +// { +// type Schema = Schema; + +// fn insert(&mut self, element: Self::Schema) -> bool { +// self.insert(element) +// } + +// fn iter(&self) -> impl Iterator::AsRefVar<'_>> { +// self.iter() +// } + +// fn len(&self) -> usize { +// self.len() +// } + +// /// Return true if empty +// fn is_empty(&self) -> bool { +// self.is_empty() +// } + +// fn drain(&mut self) -> impl Iterator { +// self.drain() +// } + +// fn contains(&self, value: ::AsRefVar<'_>) -> bool { +// self.get(value).is_some() +// } +// } + +// impl TupleSet for VariadicColumnarSet +// where +// Schema: 'static + Eq + Hash + PartialEqVariadic, +// { +// type Schema = Schema; + +// fn insert(&mut self, element: Self::Schema) -> bool { +// self.insert(element) +// } + +// fn iter(&self) -> impl Iterator::AsRefVar<'_>> { +// self.iter() +// } + +// fn len(&self) -> usize { +// self.len() +// } + +// fn is_empty(&self) -> bool { +// self.is_empty() +// } + +// fn drain(&mut self) -> impl Iterator { +// self.drain() +// } + +// fn contains(&self, value: ::AsRefVar<'_>) -> bool { +// self.iter() +// .any(|t| ::eq_ref(t, value)) +// } +// } + /// HashSet that stores Variadics of owned values but allows /// for lookups with RefVariadics as well #[derive(Clone)] @@ -41,32 +130,35 @@ where impl VariadicHashSet where - T: VariadicExt + PartialEqVariadic, + T: PartialEqVariadic, for<'a> T::AsRefVar<'a>: Hash, S: BuildHasher, { - fn get_hash(hasher: &S, ref_var: T::AsRefVar<'_>) -> u64 { - hasher.hash_one(ref_var) - // let mut hasher = hasher.build_hasher(); - // ref_var.hash(&mut hasher); - // hasher.finish() - } - /// given a RefVariadic lookup key, get a RefVariadic version of a tuple in the set pub fn get<'a>(&'a self, ref_var: T::AsRefVar<'_>) -> Option<&'a T> { - let hash = Self::get_hash(&self.hasher, ref_var); + // let hash = Self::get_hash(&self.hasher, ref_var); + let hash = self.hasher.hash_one(ref_var); self.table.find(hash, |item| { ::eq_ref(ref_var, item.as_ref_var()) }) } +} +impl VariadicSet for VariadicHashSet +where + T: VariadicExt + PartialEqVariadic, + for<'a> T::AsRefVar<'a>: Hash, + S: BuildHasher, +{ + type Schema = T; /// insert a tuple - pub fn insert(&mut self, element: T) -> bool { - let hash = Self::get_hash(&self.hasher, element.as_ref_var()); + fn insert(&mut self, element: T) -> bool { + // let hash = Self::get_hash(&self.hasher, element.as_ref_var()); + let hash = self.hasher.hash_one(element.as_ref_var()); let entry = self.table.entry( hash, |item| ::eq(&element, item), - |item| Self::get_hash(&self.hasher, item.as_ref_var()), + |item| self.hasher.hash_one(item.as_ref_var()), ); match entry { Entry::Occupied(_occupied_entry) => false, @@ -78,22 +170,27 @@ where } /// return the number of tuples in the set - pub fn len(&self) -> usize { + fn len(&self) -> usize { self.table.len() } /// return the number of tuples in the set - pub fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.table.len() == 0 } /// drain the set: iterate and remove the tuples without deallocating - pub fn drain(&mut self) -> hashbrown::hash_table::Drain<'_, T> { + // fn drain(&mut self) -> hashbrown::hash_table::Drain<'_, T> { + fn drain(&mut self) -> impl Iterator { self.table.drain() } + fn contains(&self, value: ::AsRefVar<'_>) -> bool { + self.get(value).is_some() + } + /// iterate through the set - pub fn iter(&self) -> impl Iterator> { + fn iter(&self) -> impl Iterator> { self.table.iter().map(|item| item.as_ref_var()) } } @@ -198,12 +295,14 @@ where last_offset: usize, } -impl VariadicColumnarSet +impl VariadicSet for VariadicColumnarSet where - Schema: VariadicExt, + Schema: PartialEqVariadic, { + type Schema = Schema; + /// Insert an element into the set - pub fn insert(&mut self, element: Schema) -> bool { + fn insert(&mut self, element: Schema) -> bool { if self.last_offset == 0 { self.columns = element.as_vec() } else { @@ -214,25 +313,30 @@ where } /// Iterate over the elements of the set - pub fn iter(&self) -> impl Iterator::AsRefVar<'_>> { + fn iter(&self) -> impl Iterator::AsRefVar<'_>> { self.columns.zip_vecs() } /// Return number of elements in the set - pub fn len(&self) -> usize { + fn len(&self) -> usize { self.last_offset } /// Return true if empty - pub fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.len() == 0 } /// iterate and drain items from the set - pub fn drain(&mut self) -> impl Iterator + '_ { + fn drain(&mut self) -> impl Iterator { self.last_offset = 0; self.columns.drain(0..) } + + fn contains(&self, value: ::AsRefVar<'_>) -> bool { + self.iter() + .any(|t| ::eq_ref(t, value)) + } } impl fmt::Debug for VariadicColumnarSet