Skip to content

Commit bb80b30

Browse files
committed
add test, assert JumpHash is close enough to ideally consistent
1 parent dd4876b commit bb80b30

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

t/02_rebucket.t

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use strict;
2+
use warnings;
3+
use Test::More tests => 12;
4+
use Algorithm::ConsistentHash::JumpHash;
5+
6+
my $DEFAULT_NUM_KEYS = 100_000;
7+
8+
# default threshold could be scaled to the number of keys
9+
my $DEFAULT_THRESHOLD = 0.001;
10+
11+
my $is_consistent = sub {
12+
my ( $from_buckets, $to_buckets, $num_keys, $first_key, $threshold ) = @_;
13+
14+
$from_buckets ||= 4;
15+
$to_buckets ||= $from_buckets + 1;
16+
$num_keys ||= $DEFAULT_NUM_KEYS;
17+
$threshold ||= $DEFAULT_THRESHOLD;
18+
$first_key ||= 0;
19+
20+
my $key_limit = ( $first_key + $num_keys );
21+
22+
my $ideal;
23+
if ( $from_buckets < $to_buckets ) {
24+
$ideal = ( $from_buckets * 1.0 ) / ( $to_buckets * 1.0 );
25+
}
26+
else {
27+
$ideal = ( $to_buckets * 1.0 ) / ( $from_buckets * 1.0 );
28+
}
29+
my $stayed = 0;
30+
my $moved = 0;
31+
my ( $key, $first, $next );
32+
for ( $key = $first_key ; $key < $key_limit ; ++$key ) {
33+
$first = Algorithm::ConsistentHash::JumpHash::jumphash_numeric( $key,
34+
$from_buckets );
35+
$next = Algorithm::ConsistentHash::JumpHash::jumphash_numeric( $key,
36+
$to_buckets );
37+
if ( $first == $next ) {
38+
++$stayed;
39+
}
40+
else {
41+
++$moved;
42+
}
43+
}
44+
my $ratio = ( $stayed * 1.0 ) / ( ( $moved + $stayed ) * 1.0 );
45+
my $diff = ( $ratio >= $ideal ) ? $ratio - $ideal : $ideal - $ratio;
46+
my $fail = ( $diff < $threshold ) ? 0 : 1;
47+
48+
my $msg = <<"EOL";
49+
50+
tested $num_keys keys ($first_key <= $key_limit)
51+
with $from_buckets buckets and $to_buckets buckets
52+
$stayed stayed in the same bucket
53+
$moved moved buckets
54+
for a ratio of $ratio, ideal would be $ideal
55+
ratio diff from ideal: $diff, threshold: $threshold
56+
57+
EOL
58+
59+
is( $fail, 0, "FAIL: diff == $diff, expected < $threshold\n$msg" );
60+
};
61+
62+
# $is_consistent->(
63+
# $from_buckets, $to_buckets, $num_keys, $first_key, $threshold
64+
# );
65+
$is_consistent->( 1, 2 );
66+
$is_consistent->( 2, 3 );
67+
$is_consistent->( 3, 7 );
68+
$is_consistent->( 4, 8 );
69+
$is_consistent->( 5, 11 );
70+
$is_consistent->( 6, 12 );
71+
$is_consistent->( 7, 13 );
72+
$is_consistent->( 8, 16 );
73+
74+
# going to fewer buckets
75+
$is_consistent->( 16, 8 );
76+
$is_consistent->( 5, 4 );
77+
$is_consistent->( 3, 2 );
78+
79+
# lager number of keys, a higher threshold, over keys in a range above 2^32
80+
$is_consistent->( 4, 5, 10_000_000, 2**34, 0.00001 );

0 commit comments

Comments
 (0)