File Coverage

blib/lib/SimpleFlake.pm
Criterion Covered Total %
statement 46 46 100.0
branch 2 2 100.0
condition n/a
subroutine 12 12 100.0
pod 0 6 0.0
total 60 66 90.9


line stmt bran cond sub pod time code
1             package SimpleFlake;
2 5     5   186098 use 5.008001;
  5         64  
3 5     5   30 use strict;
  5         10  
  5         114  
4 5     5   26 use warnings;
  5         9  
  5         162  
5              
6 5     5   1863 use Time::HiRes qw(time);
  5         6071  
  5         22  
7 5     5   5088 use Math::BigInt lib => 'GMP';
  5         139356  
  5         37  
8 5         2348 use Bytes::Random::Secure qw(
9             random_bytes random_bytes_base64 random_bytes_hex
10 5     5   130603 );
  5         46865  
11              
12             our $VERSION = "0.11";
13              
14             our $random;
15             our @map = ( 0 .. 9, "A" .. "Z", "a" .. "z" );
16              
17             sub random {
18              
19 10002     10002 0 21507 my ($class) = @_;
20              
21 10002 100       33539 unless ($random) {
22              
23 3         35 $random = Bytes::Random::Secure->new(
24             Bits => 64,
25             NonBlocking => 1,
26             );
27             }
28              
29 10002         55799 return $random;
30             }
31              
32             sub get_random_bits {
33              
34 10002     10002 0 25064 my ( $class ) = @_;
35              
36 10002         40834 my $return = Math::BigInt->from_bin( unpack( 'B*', $class->random->bytes(8) ) );
37              
38 10002         3498033 return $return;
39             }
40              
41             sub get_millisecond_timestamp {
42              
43 10002     10002 0 20515 my $epoch = 946702800;
44              
45 10002         72187 my $time = Math::BigInt->new( int( ( time - $epoch ) * 100_000_000 ) );
46 10002         598444 return $time;
47             }
48              
49             sub get_pid {
50              
51 10001     10001 0 37152 return Math::BigInt->new($$);
52             }
53              
54             sub get_flake {
55              
56 10001     10001 0 131807 my $self = shift;
57              
58 10001         36815 my $timestamp = $self->get_millisecond_timestamp;
59 10001         35758 my $random = $self->get_random_bits;
60 10001         36751 my $pid = $self->get_pid;
61              
62 10001         429792 my $t = $timestamp->blsft(4) ;
63 10001         2489126 my $r = $t->bior($pid);
64 10001         2440788 my $p = $t->blsft(32);
65 10001         2984788 my $y = $p->bior($random);
66 10001         5892014 my $a = base36encode($y->as_int);
67              
68             # Limit length to 16 chars
69 10001         102083 return substr($a,0, 16)
70             }
71              
72             sub base36encode {
73              
74 10001     10001 0 243117 my $number = shift;
75              
76 10001         20084 my $output = "";
77 10001         21583 my ( $q, $r );
78              
79 10001         16521 do {
80 160016         7281023 ( $q, $r ) = ( int( $number / 62 ), $number % 62 );
81 160016         73292476 $number /= 62;
82 160016         34812216 $output = $map[$r] . $output;
83             } while ($q);
84              
85 10001         512509 return $output;
86             }
87              
88             1;
89             __END__