1818use std:: hash:: Hash ;
1919use std:: num:: NonZeroU64 ;
2020
21- use crate :: theta:: raw_hash_table:: RawHashTable ;
22- use crate :: theta:: raw_hash_table:: RawHashTableEntry ;
23- #[ cfg( test) ]
24- pub ( crate ) use crate :: theta:: raw_hash_table:: starting_sub_multiple;
25- #[ cfg( test) ]
26- pub ( crate ) use crate :: theta:: raw_hash_table:: starting_theta_from_sampling_probability;
21+ use crate :: thetacommon:: RawHashTableEntry ;
22+ use crate :: thetacommon:: hash_table:: RawHashTable ;
2723
2824/// Specific hash table for theta sketch
2925///
@@ -34,16 +30,22 @@ pub(crate) use crate::theta::raw_hash_table::starting_theta_from_sampling_probab
3430/// update the theta to the k-th smallest entry.
3531pub ( super ) type ThetaHashTable = RawHashTable < ThetaEntry > ;
3632
33+ /// A retained entry in a Theta sketch.
3734#[ derive( Debug , Clone , Copy ) ]
38- pub ( crate ) struct ThetaEntry {
35+ pub struct ThetaEntry {
3936 hash : NonZeroU64 ,
4037}
4138
4239impl ThetaEntry {
43- fn new ( hash : u64 ) -> Self {
40+ pub ( crate ) fn new ( hash : u64 ) -> Self {
4441 let hash = NonZeroU64 :: new ( hash) . expect ( "hash must be non-zero" ) ;
4542 Self { hash }
4643 }
44+
45+ /// Return the hash used as this entry's key.
46+ pub fn hash ( & self ) -> u64 {
47+ self . hash . get ( )
48+ }
4749}
4850
4951impl RawHashTableEntry for ThetaEntry {
@@ -90,18 +92,20 @@ mod tests {
9092 use super :: * ;
9193 use crate :: common:: ResizeFactor ;
9294 use crate :: hash:: DEFAULT_UPDATE_SEED ;
93- use crate :: theta:: MAX_THETA ;
94- use crate :: theta:: MIN_LG_K ;
95+ use crate :: thetacommon:: constants:: MAX_THETA ;
96+ use crate :: thetacommon:: constants:: MIN_LG_K ;
97+ use crate :: thetacommon:: hash_table:: starting_sub_multiple;
98+ use crate :: thetacommon:: hash_table:: starting_theta_from_sampling_probability;
9599
96100 #[ test]
97101 fn test_new_hash_table ( ) {
98102 let table = ThetaHashTable :: new ( 8 , ResizeFactor :: X8 , 1.0 , DEFAULT_UPDATE_SEED ) ;
99103
100104 assert_eq ! (
101- table. lg_cur_size,
105+ table. lg_cur_size( ) ,
102106 starting_sub_multiple( 8 + 1 , MIN_LG_K , ResizeFactor :: X8 . lg_value( ) )
103107 ) ;
104- assert_eq ! ( table. theta, starting_theta_from_sampling_probability( 1.0 ) ) ;
108+ assert_eq ! ( table. theta( ) , starting_theta_from_sampling_probability( 1.0 ) ) ;
105109 assert_eq ! ( table. num_retained( ) , 0 ) ;
106110 assert ! ( table. is_empty( ) ) ;
107111 assert_eq ! ( table. iter( ) . count( ) , 0 ) ;
@@ -119,7 +123,7 @@ mod tests {
119123 assert_ne ! ( hash1, hash2) ;
120124
121125 // With low theta, update should be screened out.
122- table. theta = 1 ;
126+ table. set_theta ( 1 ) ;
123127 assert ! ( !table. try_insert( "test3" ) ) ;
124128 }
125129
@@ -136,7 +140,7 @@ mod tests {
136140 assert_eq ! ( table. num_retained( ) , 1 ) ;
137141
138142 // Force screening and verify insertion fails
139- table. theta = 0 ;
143+ table. set_theta ( 1 ) ; // Set theta to a low value to screen out new entries
140144 assert ! ( !table. try_insert( "screened" ) ) ;
141145 assert_eq ! ( table. num_retained( ) , 1 ) ;
142146 assert ! ( !table. is_empty( ) ) ;
@@ -174,7 +178,7 @@ mod tests {
174178 {
175179 let mut table = ThetaHashTable :: new ( 8 , ResizeFactor :: X2 , 1.0 , DEFAULT_UPDATE_SEED ) ;
176180
177- assert_eq ! ( table. entries . len ( ) , 32 ) ;
181+ assert_eq ! ( table. num_entries ( ) , 32 ) ;
178182
179183 // Insert enough values to trigger resize (50% threshold)
180184 // Capacity = 32 * 0.5 = 16
@@ -183,14 +187,14 @@ mod tests {
183187 // Table should have resized and all values should be inserted
184188 assert ! ( table. num_retained( ) > 0 ) ;
185189 assert_eq ! ( table. num_retained( ) , inserted) ;
186- assert_eq ! ( table. entries . len ( ) , 64 ) ;
190+ assert_eq ! ( table. num_entries ( ) , 64 ) ;
187191 }
188192
189193 // Test different resize factors
190194 {
191195 let mut table = ThetaHashTable :: new ( 8 , ResizeFactor :: X4 , 1.0 , DEFAULT_UPDATE_SEED ) ;
192196
193- assert_eq ! ( table. entries . len ( ) , 32 ) ;
197+ assert_eq ! ( table. num_entries ( ) , 32 ) ;
194198
195199 // Insert enough values to trigger resize (50% threshold)
196200 // Capacity = 32 * 0.5 = 16
@@ -199,17 +203,17 @@ mod tests {
199203 // Table should have resized and all values should be inserted
200204 assert ! ( table. num_retained( ) > 0 ) ;
201205 assert_eq ! ( table. num_retained( ) , inserted) ;
202- assert_eq ! ( table. entries . len ( ) , 128 ) ;
206+ assert_eq ! ( table. num_entries ( ) , 128 ) ;
203207 }
204208 }
205209
206210 #[ test]
207211 fn test_rebuild ( ) {
208212 let mut table = ThetaHashTable :: new ( 5 , ResizeFactor :: X8 , 1.0 , DEFAULT_UPDATE_SEED ) ;
209213
210- assert_eq ! ( table. lg_cur_size, 6 ) ;
211- assert_eq ! ( table. entries . len ( ) , 64 ) ;
212- assert_eq ! ( table. theta, MAX_THETA ) ;
214+ assert_eq ! ( table. lg_cur_size( ) , 6 ) ;
215+ assert_eq ! ( table. num_entries ( ) , 64 ) ;
216+ assert_eq ! ( table. theta( ) , MAX_THETA ) ;
213217
214218 // Insert many values to trigger rebuild
215219 for i in 0 ..100 {
@@ -228,9 +232,9 @@ mod tests {
228232 let _ = table. try_insert ( format ! ( "value_{}" , i) ) ;
229233 }
230234
231- assert_eq ! ( table. lg_cur_size, 6 ) ;
232- assert ! ( table. entries . len ( ) >= 64 ) ;
233- assert ! ( table. theta < new_theta) ;
235+ assert_eq ! ( table. lg_cur_size( ) , 6 ) ;
236+ assert ! ( table. num_entries ( ) >= 64 ) ;
237+ assert ! ( table. theta( ) < new_theta) ;
234238 }
235239
236240 #[ test]
@@ -274,8 +278,8 @@ mod tests {
274278 fn test_reset ( ) {
275279 let mut table = ThetaHashTable :: new ( 8 , ResizeFactor :: X8 , 1.0 , DEFAULT_UPDATE_SEED ) ;
276280 let init_theta = table. theta ( ) ;
277- let init_lg_cur = table. lg_cur_size ;
278- let init_entries = table. entries . len ( ) ;
281+ let init_lg_cur = table. lg_cur_size ( ) ;
282+ let init_entries = table. num_entries ( ) ;
279283
280284 // Insert some values
281285 for i in 0 ..10 {
@@ -291,8 +295,8 @@ mod tests {
291295 assert ! ( table. is_empty( ) ) ;
292296 assert_eq ! ( table. num_retained( ) , 0 ) ;
293297 assert_eq ! ( table. theta( ) , init_theta) ;
294- assert_eq ! ( table. lg_cur_size, init_lg_cur) ;
295- assert_eq ! ( table. entries . len ( ) , init_entries) ;
298+ assert_eq ! ( table. lg_cur_size( ) , init_lg_cur) ;
299+ assert_eq ! ( table. num_entries ( ) , init_entries) ;
296300 assert_eq ! ( table. iter( ) . count( ) , 0 ) ;
297301 }
298302
0 commit comments