@@ -57,7 +57,8 @@ impl From<&WeightingConfig> for WeightingMode {
57
57
fn get_weight ( bucket : u64 , alpha : u64 ) -> u64 {
58
58
debug_assert ! ( ( ALPHA_MIN ..=ALPHA_MIN + lpf:: SCALE . get( ) ) . contains( & alpha) ) ;
59
59
let b = bucket + 1 ;
60
- linearly_interpolate ( b, alpha)
60
+ let b_squared = b. saturating_mul ( b) ;
61
+ gossip_interpolate_weight ( b, b_squared, alpha)
61
62
}
62
63
63
64
/// Approximates `base^alpha` rounded to nearest integer using
@@ -66,11 +67,10 @@ fn get_weight(bucket: u64, alpha: u64) -> u64 {
66
67
/// Note: This function is most accurate when `base` is small e.g. < ~25.
67
68
#[ inline]
68
69
#[ allow( clippy:: arithmetic_side_effects) ]
69
- pub fn linearly_interpolate ( base : u64 , alpha : u64 ) -> u64 {
70
+ pub fn gossip_interpolate_weight ( base : u64 , base_squared : u64 , alpha : u64 ) -> u64 {
70
71
let scale = lpf:: SCALE . get ( ) ;
71
72
let t = alpha. saturating_sub ( ALPHA_MIN ) ;
72
73
debug_assert ! ( t <= scale, "interpolation t={} > SCALE={}" , t, scale) ;
73
- let base_squared = base. saturating_mul ( base) ;
74
74
// ((base * (scale - t) + base_squared * t) + scale / 2) / scale
75
75
( ( base. saturating_mul ( scale. saturating_sub ( t) ) ) . saturating_add ( base_squared. saturating_mul ( t) ) )
76
76
. saturating_add ( scale / 2 )
@@ -922,21 +922,24 @@ mod tests {
922
922
923
923
#[ test]
924
924
fn test_interpolate_t_zero ( ) {
925
- // When t=0, should return base
926
- assert_eq ! ( linearly_interpolate( 100 , 0 ) , 100 ) ;
927
- assert_eq ! ( linearly_interpolate( 0 , 0 ) , 0 ) ;
928
- assert_eq ! ( linearly_interpolate( 1000000 , 0 ) , 1000000 ) ;
925
+ // When alpha = ALPHA_MIN (t = 0), should return base
926
+ assert_eq ! ( gossip_interpolate_weight( 100 , 100 * 100 , ALPHA_MIN ) , 100 ) ;
927
+ assert_eq ! ( gossip_interpolate_weight( 0 , 0 , ALPHA_MIN ) , 0 ) ;
928
+ assert_eq ! (
929
+ gossip_interpolate_weight( 1_000_000 , 1_000_000 * 1_000_000 , ALPHA_MIN ) ,
930
+ 1_000_000
931
+ ) ;
929
932
}
930
933
931
934
#[ test]
932
935
fn test_interpolate_t_max ( ) {
933
- // When t= SCALE, should return base^2
936
+ // When alpha = ALPHA_MAX (t = SCALE) , should return base^2
934
937
let base = 100 ;
935
- let result = linearly_interpolate ( base, lpf :: SCALE . get ( ) ) ;
938
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MAX ) ;
936
939
assert_eq ! ( result, base * base) ;
937
940
938
941
let base2 = 1000 ;
939
- let result = linearly_interpolate ( base2, lpf :: SCALE . get ( ) ) ;
942
+ let result = gossip_interpolate_weight ( base2, base2 * base2 , ALPHA_MAX ) ;
940
943
assert_eq ! ( result, base2 * base2) ;
941
944
}
942
945
@@ -947,62 +950,68 @@ mod tests {
947
950
let t_75 = lpf:: SCALE . get ( ) * 3 / 4 ; // 75%
948
951
949
952
let base = 3 ;
950
- let result = linearly_interpolate ( base, t_10) ;
953
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_10) ;
951
954
assert_eq ! ( result, 4 ) ;
952
955
953
- let result = linearly_interpolate ( base, t_50) ;
956
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_50) ;
954
957
assert_eq ! ( result, 6 ) ;
955
958
956
- let result = linearly_interpolate ( base, t_75) ;
959
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_75) ;
957
960
assert_eq ! ( result, 8 ) ;
958
961
959
962
let base = 15 ;
960
- let result = linearly_interpolate ( base, t_10) ;
963
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_10) ;
961
964
assert_eq ! ( result, 36 ) ;
962
965
963
- let result = linearly_interpolate ( base, t_50) ;
966
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_50) ;
964
967
assert_eq ! ( result, 120 ) ;
965
968
966
- let result = linearly_interpolate ( base, t_75) ;
969
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_75) ;
967
970
assert_eq ! ( result, 173 ) ;
968
971
969
972
let base = 24 ;
970
- let result = linearly_interpolate ( base, t_10) ;
973
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_10) ;
971
974
assert_eq ! ( result, 79 ) ;
972
975
973
- let result = linearly_interpolate ( base, t_50) ;
976
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_50) ;
974
977
assert_eq ! ( result, 300 ) ;
975
978
976
- let result = linearly_interpolate ( base, t_75) ;
979
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t_75) ;
977
980
assert_eq ! ( result, 438 ) ;
978
981
}
979
982
980
983
#[ test]
981
984
fn test_interpolate_large_base ( ) {
982
- let base = 1000000000 ;
983
- let result = linearly_interpolate ( base, lpf:: SCALE . get ( ) / 2 ) ;
985
+ let base = 1_000_000_000u64 ;
986
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + lpf:: SCALE . get ( ) / 2 ) ;
984
987
assert ! ( result >= base) ;
985
988
assert ! ( result < base * base) ;
986
989
}
987
990
988
991
#[ test]
989
992
fn test_interpolate_edge_cases ( ) {
990
993
// Test with base = 1
991
- assert_eq ! ( linearly_interpolate( 1 , 0 ) , 1 ) ;
992
- assert_eq ! ( linearly_interpolate( 1 , lpf:: SCALE . get( ) ) , 1 ) ;
993
- assert_eq ! ( linearly_interpolate( 1 , lpf:: SCALE . get( ) / 2 ) , 1 ) ;
994
+ assert_eq ! ( gossip_interpolate_weight( 1 , 1 , ALPHA_MIN ) , 1 ) ;
995
+ assert_eq ! ( gossip_interpolate_weight( 1 , 1 , ALPHA_MAX ) , 1 ) ;
996
+ assert_eq ! (
997
+ gossip_interpolate_weight( 1 , 1 , ALPHA_MIN + ( lpf:: SCALE . get( ) / 2 ) ) ,
998
+ 1
999
+ ) ;
994
1000
995
1001
// Test with base = 0
996
- assert_eq ! ( linearly_interpolate( 0 , 0 ) , 0 ) ;
997
- assert_eq ! ( linearly_interpolate( 0 , lpf:: SCALE . get( ) ) , 0 ) ;
998
- assert_eq ! ( linearly_interpolate( 0 , lpf:: SCALE . get( ) / 2 ) , 0 ) ;
1002
+ assert_eq ! ( gossip_interpolate_weight( 0 , 0 , ALPHA_MIN ) , 0 ) ;
1003
+ assert_eq ! ( gossip_interpolate_weight( 0 , 0 , ALPHA_MAX ) , 0 ) ;
1004
+ assert_eq ! (
1005
+ gossip_interpolate_weight( 0 , 0 , ALPHA_MIN + ( lpf:: SCALE . get( ) / 2 ) ) ,
1006
+ 0
1007
+ ) ;
999
1008
}
1000
1009
1001
1010
#[ test]
1002
1011
fn test_interpolate_rounding ( ) {
1003
1012
let base = 3 ;
1004
1013
let t = lpf:: SCALE . get ( ) / 3 ;
1005
- let result = linearly_interpolate ( base, t) ;
1014
+ let result = gossip_interpolate_weight ( base, base * base , ALPHA_MIN + t) ;
1006
1015
1007
1016
assert ! ( result >= 3 ) ;
1008
1017
assert ! ( result <= 9 ) ;
@@ -1024,9 +1033,8 @@ mod tests {
1024
1033
let target_alpha = alpha_min + lpf:: SCALE . get ( ) / 2 ; // 1.5 * SCALE
1025
1034
let filtered_alpha = lpf:: filter_alpha ( prev_alpha, target_alpha, config) ;
1026
1035
1027
- let t = filtered_alpha. saturating_sub ( alpha_min) ;
1028
1036
let base = 2 ;
1029
- let result = linearly_interpolate ( base, t ) ;
1037
+ let result = gossip_interpolate_weight ( base, base * base , filtered_alpha ) ;
1030
1038
1031
1039
assert ! ( result >= base) ;
1032
1040
assert ! ( result <= base * base) ;
0 commit comments