@@ -100,6 +100,27 @@ pub fn absolute_from_relative_position(field_id: FieldId, relative: RelativePosi
100100 ( field_id as u32 ) << 16 | ( relative as u32 )
101101}
102102
103+ /// Compute the "bucketed" absolute position from the field id and relative position in the field.
104+ ///
105+ /// In a bucketed position, the accuracy of the relative position is reduced exponentially as it gets larger.
106+ pub fn bucketed_absolute_from_relative_position (
107+ field_id : FieldId ,
108+ relative : RelativePosition ,
109+ ) -> Position {
110+ // The first few relative positions are kept intact.
111+ if relative < 16 {
112+ absolute_from_relative_position ( field_id, relative)
113+ } else if relative < 24 {
114+ // Relative positions between 16 and 24 all become equal to 24
115+ absolute_from_relative_position ( field_id, 24 )
116+ } else {
117+ // Then, groups of positions that have the same base-2 logarithm are reduced to
118+ // the same relative position: the smallest power of 2 that is greater than them
119+ let relative = ( relative as f64 ) . log2 ( ) . ceil ( ) . exp2 ( ) as u16 ;
120+ absolute_from_relative_position ( field_id, relative)
121+ }
122+ }
123+
103124/// Transform a raw obkv store into a JSON Object.
104125pub fn obkv_to_json (
105126 displayed_fields : & [ FieldId ] ,
@@ -329,4 +350,51 @@ mod tests {
329350
330351 assert_eq ! ( & actual, expected) ;
331352 }
353+
354+ #[ test]
355+ fn bucketed_position ( ) {
356+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 0 ) , @"0" ) ;
357+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 1 ) , @"1" ) ;
358+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 2 ) , @"2" ) ;
359+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 15 ) , @"15" ) ;
360+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 16 ) , @"24" ) ;
361+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 19 ) , @"24" ) ;
362+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 20 ) , @"24" ) ;
363+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 21 ) , @"24" ) ;
364+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 22 ) , @"24" ) ;
365+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 23 ) , @"24" ) ;
366+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 24 ) , @"32" ) ;
367+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 25 ) , @"32" ) ;
368+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 30 ) , @"32" ) ;
369+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 40 ) , @"64" ) ;
370+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 50 ) , @"64" ) ;
371+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 60 ) , @"64" ) ;
372+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 70 ) , @"128" ) ;
373+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 80 ) , @"128" ) ;
374+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 90 ) , @"128" ) ;
375+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 100 ) , @"128" ) ;
376+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 110 ) , @"128" ) ;
377+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 120 ) , @"128" ) ;
378+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 130 ) , @"256" ) ;
379+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 1000 ) , @"1024" ) ;
380+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 2000 ) , @"2048" ) ;
381+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 4000 ) , @"4096" ) ;
382+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 8000 ) , @"8192" ) ;
383+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 9000 ) , @"16384" ) ;
384+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 10_000 ) , @"16384" ) ;
385+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 65_500 ) , @"65535" ) ;
386+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 0 , 65_535 ) , @"65535" ) ;
387+
388+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 1 , 0 ) , @"65536" ) ;
389+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 1 , 1 ) , @"65537" ) ;
390+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 1 , 20 ) , @"65560" ) ;
391+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 1 , 1000 ) , @"66560" ) ;
392+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 1 , 65_535 ) , @"131071" ) ;
393+
394+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 2 , 0 ) , @"131072" ) ;
395+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 2 , 65_535 ) , @"196607" ) ;
396+
397+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 65_535 , 0 ) , @"4294901760" ) ;
398+ insta:: assert_debug_snapshot!( bucketed_absolute_from_relative_position( 65_535 , 65_535 ) , @"4294967295" ) ;
399+ }
332400}
0 commit comments