@@ -360,10 +360,18 @@ impl Histogram {
360360
361361 fn equal_count ( & self , value : & DataValue , sketch : & CountMinSketch < DataValue > ) -> usize {
362362 let average_count = self . average_count ( ) ;
363- if sketch. error_bound ( self . meta . values_len ) >= average_count {
364- average_count
363+ if average_count == 0 {
364+ return 0 ;
365+ }
366+
367+ let estimated_count = sketch. estimate ( value) ;
368+ let error_bound = sketch. error_bound ( self . meta . values_len ) ;
369+ if error_bound < average_count
370+ || estimated_count. saturating_sub ( error_bound) > average_count
371+ {
372+ estimated_count
365373 } else {
366- sketch . estimate ( value )
374+ average_count
367375 }
368376 }
369377
@@ -1123,19 +1131,20 @@ mod tests {
11231131 }
11241132
11251133 #[ test]
1126- fn test_eq_count_falls_back_to_hll_when_cm_error_is_large ( ) -> Result < ( ) , DatabaseError > {
1134+ fn test_eq_count_falls_back_to_average_when_cm_error_is_large ( ) -> Result < ( ) , DatabaseError > {
11271135 let mut builder = HistogramBuilder :: new ( & index_meta ( ) , ANALYZE_STATISTICS_RELATIVE_ERROR ) ?;
11281136
11291137 for value in 0 ..10_000 {
11301138 builder. append ( DataValue :: Int32 ( value) ) ?;
11311139 }
11321140
1133- let ( histogram, mut sketch, _) = builder. build ( 100 ) ?;
1141+ let ( histogram, sketch, _) = builder. build ( 100 ) ?;
11341142 let top_n = ColumnTopN :: default ( ) ;
11351143 let average_count = histogram. average_count ( ) ;
1136- assert ! ( sketch. error_bound( histogram. values_len( ) ) >= average_count) ;
1137-
1138- sketch. add ( & DataValue :: Int32 ( 7 ) , 1000 ) ;
1144+ let error_bound = sketch. error_bound ( histogram. values_len ( ) ) ;
1145+ let estimated_count = sketch. estimate ( & DataValue :: Int32 ( 7 ) ) ;
1146+ assert ! ( error_bound >= average_count) ;
1147+ assert ! ( estimated_count. saturating_sub( error_bound) <= average_count) ;
11391148
11401149 assert_eq ! (
11411150 histogram. collect_count( & [ Range :: Eq ( DataValue :: Int32 ( 7 ) ) ] , & sketch, & top_n) ?,
@@ -1145,6 +1154,33 @@ mod tests {
11451154 Ok ( ( ) )
11461155 }
11471156
1157+ #[ test]
1158+ fn test_eq_count_uses_cm_sketch_for_clear_heavy_hitter ( ) -> Result < ( ) , DatabaseError > {
1159+ let mut builder = HistogramBuilder :: new ( & index_meta ( ) , ANALYZE_STATISTICS_RELATIVE_ERROR ) ?;
1160+
1161+ for _ in 0 ..1_000 {
1162+ builder. append ( DataValue :: Int32 ( 7 ) ) ?;
1163+ }
1164+ for value in 0 ..9_000 {
1165+ builder. append ( DataValue :: Int32 ( 10_000 + value) ) ?;
1166+ }
1167+
1168+ let ( histogram, sketch, _) = builder. build ( 100 ) ?;
1169+ let top_n = ColumnTopN :: default ( ) ;
1170+ let average_count = histogram. average_count ( ) ;
1171+ let error_bound = sketch. error_bound ( histogram. values_len ( ) ) ;
1172+ let estimated_count = sketch. estimate ( & DataValue :: Int32 ( 7 ) ) ;
1173+ assert ! ( error_bound >= average_count) ;
1174+ assert ! ( estimated_count. saturating_sub( error_bound) > average_count) ;
1175+
1176+ assert_eq ! (
1177+ histogram. collect_count( & [ Range :: Eq ( DataValue :: Int32 ( 7 ) ) ] , & sketch, & top_n) ?,
1178+ estimated_count
1179+ ) ;
1180+
1181+ Ok ( ( ) )
1182+ }
1183+
11481184 #[ test]
11491185 fn test_eq_count_falls_back_when_top_n_error_is_large ( ) -> Result < ( ) , DatabaseError > {
11501186 let mut builder = HistogramBuilder :: new ( & index_meta ( ) , ANALYZE_STATISTICS_RELATIVE_ERROR ) ?;
0 commit comments