@@ -23,10 +23,9 @@ use arrow::buffer::{BooleanBuffer, NullBuffer};
2323use arrow:: compute:: { SortOptions , take} ;
2424use arrow:: datatypes:: DataType ;
2525use arrow:: util:: bit_iterator:: BitIndexIterator ;
26- use datafusion_common:: HashMap ;
2726use datafusion_common:: Result ;
2827use datafusion_common:: hash_utils:: { RandomState , with_hashes} ;
29- use hashbrown:: hash_map :: RawEntryMut ;
28+ use hashbrown:: HashTable ;
3029
3130use super :: result:: build_in_list_result;
3231use super :: static_filter:: StaticFilter ;
@@ -36,11 +35,8 @@ use super::static_filter::StaticFilter;
3635pub ( super ) struct ArrayStaticFilter {
3736 in_array : ArrayRef ,
3837 state : RandomState ,
39- /// Used to provide a lookup from value to in list index
40- ///
41- /// Note: usize::hash is not used, instead the raw entry
42- /// API is used to store entries w.r.t their value
43- map : HashMap < usize , ( ) , ( ) > ,
38+ /// Stores indices into `in_array` for O(1) lookups.
39+ table : HashTable < usize > ,
4440}
4541
4642impl ArrayStaticFilter {
@@ -56,36 +52,34 @@ impl ArrayStaticFilter {
5652 return Ok ( ArrayStaticFilter {
5753 in_array,
5854 state : RandomState :: default ( ) ,
59- map : HashMap :: with_hasher ( ( ) ) ,
55+ table : HashTable :: new ( ) ,
6056 } ) ;
6157 }
6258
6359 let state = RandomState :: default ( ) ;
64- let map = Self :: build_haystack_map ( & in_array, & state) ?;
60+ let table = Self :: build_haystack_table ( & in_array, & state) ?;
6561
6662 Ok ( Self {
6763 in_array,
6864 state,
69- map ,
65+ table ,
7066 } )
7167 }
7268
73- fn build_haystack_map (
69+ fn build_haystack_table (
7470 haystack : & ArrayRef ,
7571 state : & RandomState ,
76- ) -> Result < HashMap < usize , ( ) , ( ) > > {
77- let mut map : HashMap < usize , ( ) , ( ) > = HashMap :: with_hasher ( ( ) ) ;
72+ ) -> Result < HashTable < usize > > {
73+ let mut table = HashTable :: new ( ) ;
7874
7975 with_hashes ( [ haystack. as_ref ( ) ] , state, |hashes| -> Result < ( ) > {
8076 let cmp = make_comparator ( haystack, haystack, SortOptions :: default ( ) ) ?;
8177
8278 let insert_value = |idx| {
8379 let hash = hashes[ idx] ;
84- if let RawEntryMut :: Vacant ( v) = map
85- . raw_entry_mut ( )
86- . from_hash ( hash, |x| cmp ( * x, idx) . is_eq ( ) )
87- {
88- v. insert_with_hasher ( hash, idx, ( ) , |x| hashes[ * x] ) ;
80+ // Only insert if not already present (deduplication)
81+ if table. find ( hash, |& x| cmp ( x, idx) . is_eq ( ) ) . is_none ( ) {
82+ table. insert_unique ( hash, idx, |& x| hashes[ x] ) ;
8983 }
9084 } ;
9185
@@ -100,7 +94,7 @@ impl ArrayStaticFilter {
10094 Ok ( ( ) )
10195 } ) ?;
10296
103- Ok ( map )
97+ Ok ( table )
10498 }
10599
106100 fn find_needles_in_haystack (
@@ -122,10 +116,7 @@ impl ArrayStaticFilter {
122116 #[ inline( always) ]
123117 |i| {
124118 let hash = needle_hashes[ i] ;
125- self . map
126- . raw_entry ( )
127- . from_hash ( hash, |idx| cmp ( i, * idx) . is_eq ( ) )
128- . is_some ( )
119+ self . table . find ( hash, |& idx| cmp ( i, idx) . is_eq ( ) ) . is_some ( )
129120 } ,
130121 ) )
131122 } )
0 commit comments