@@ -100,6 +100,27 @@ pub fn absolute_from_relative_position(field_id: FieldId, relative: RelativePosi
100
100
( field_id as u32 ) << 16 | ( relative as u32 )
101
101
}
102
102
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
+
103
124
/// Transform a raw obkv store into a JSON Object.
104
125
pub fn obkv_to_json (
105
126
displayed_fields : & [ FieldId ] ,
@@ -329,4 +350,51 @@ mod tests {
329
350
330
351
assert_eq ! ( & actual, expected) ;
331
352
}
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
+ }
332
400
}
0 commit comments