line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBIx::CouchLike::IdGenerator; |
2
|
|
|
|
|
|
|
# original code from Data::YUID::Generator |
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
41
|
|
5
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
31
|
|
6
|
1
|
|
|
1
|
|
137244
|
use Math::BigInt try => 'GMP'; |
|
1
|
|
|
|
|
160593
|
|
|
1
|
|
|
|
|
7
|
|
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
650827
|
no warnings qw(deprecated); # for fields |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
60
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
6
|
use vars qw{$VERSION}; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
78
|
|
11
|
|
|
|
|
|
|
$VERSION = "0.02"; |
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
1137
|
use fields qw(host_id start_time current_time min_id max_id ids); |
|
1
|
|
|
|
|
1753
|
|
|
1
|
|
|
|
|
6
|
|
14
|
|
|
|
|
|
|
|
15
|
1
|
|
|
1
|
|
98
|
use constant EPOCH_OFFSET => 946684800; # Sat, Jan 1 2000 00:00 GMT |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
70
|
|
16
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
5
|
use constant HOST_ID_BITS => 16; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
47
|
|
18
|
1
|
|
|
1
|
|
6
|
use constant TIME_BITS => 36; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
66
|
|
19
|
1
|
|
|
1
|
|
6
|
use constant SERIAL_BITS => 64 - HOST_ID_BITS - TIME_BITS; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
69
|
|
20
|
|
|
|
|
|
|
|
21
|
1
|
|
|
1
|
|
5
|
use constant TIME_SHIFT => HOST_ID_BITS + SERIAL_BITS; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
71
|
|
22
|
1
|
|
|
1
|
|
5
|
use constant SERIAL_SHIFT => HOST_ID_BITS; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
61
|
|
23
|
|
|
|
|
|
|
|
24
|
1
|
|
|
1
|
|
5
|
use constant SERIAL_INCREMENT => Math::BigInt->new(1) << SERIAL_SHIFT; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
|
459
|
use constant HOST_ID_MAX => (Math::BigInt->new(1) << HOST_ID_BITS) - 1; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
4
|
|
27
|
1
|
|
|
1
|
|
507
|
use constant TIME_MAX => (Math::BigInt->new(1) << TIME_BITS) - 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
7
|
|
28
|
1
|
|
|
1
|
|
671
|
use constant TIME_MAX_SHIFTED => TIME_MAX << TIME_SHIFT; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
80
|
|
29
|
1
|
|
|
1
|
|
4
|
use constant SERIAL_MAX => (Math::BigInt->new(1) << SERIAL_BITS) - 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
30
|
1
|
|
|
1
|
|
563
|
use constant SERIAL_MAX_SHIFTED => SERIAL_MAX << SERIAL_SHIFT; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
553
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub new { |
34
|
1
|
|
|
1
|
0
|
12
|
my $self = shift; |
35
|
1
|
50
|
|
|
|
9
|
$self = fields::new( $self ) unless ref $self; |
36
|
|
|
|
|
|
|
|
37
|
1
|
|
|
|
|
3971
|
my $host_id = shift; |
38
|
1
|
50
|
0
|
|
|
5
|
if( !$host_id ) { |
|
|
0
|
|
|
|
|
|
39
|
1
|
|
|
|
|
113
|
$host_id = int( rand( HOST_ID_MAX ) ); |
40
|
|
|
|
|
|
|
} elsif( $host_id < 0 || $host_id > HOST_ID_MAX ) { |
41
|
0
|
|
|
|
|
0
|
warn __PACKAGE__ . ": host ID $host_id is not in range of [0," . HOST_ID_MAX . "]\n"; |
42
|
0
|
|
|
|
|
0
|
return; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
1
|
|
|
|
|
41
|
$self->{ host_id } = $host_id; |
46
|
1
|
|
|
|
|
10
|
$self->{ start_time } = time; |
47
|
1
|
|
|
|
|
2
|
$self->{ current_time } = 0; |
48
|
1
|
|
|
|
|
3
|
$self->{ ids } = {}; |
49
|
1
|
|
|
|
|
5
|
$self->_sync(); |
50
|
|
|
|
|
|
|
|
51
|
1
|
|
|
|
|
787
|
return $self; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub _sync { |
56
|
2001
|
|
|
2001
|
|
2686
|
my $self = shift; |
57
|
2001
|
|
|
|
|
4297
|
my $time = time; |
58
|
2001
|
100
|
|
|
|
6484
|
return if( $self->{ current_time } == $time ); # FIXME: check for clock skew |
59
|
9
|
|
|
|
|
25
|
$self->{ current_time } = $time; |
60
|
9
|
100
|
|
|
|
91
|
$self->{ min_id } = $self->_make_id( 0 ) unless( $self->{ min_id } ); |
61
|
9
|
|
|
|
|
1383
|
$self->{ max_id } = $self->_make_id( SERIAL_MAX ); |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub _make_id { |
66
|
10
|
|
|
10
|
|
30
|
my $self = shift; |
67
|
10
|
|
100
|
|
|
47
|
my $serial = shift || 0; |
68
|
|
|
|
|
|
|
return |
69
|
|
|
|
|
|
|
((Math::BigInt->new( $self->{ current_time } - EPOCH_OFFSET )) << TIME_SHIFT) |
70
|
10
|
|
|
|
|
372
|
| (Math::BigInt->new($serial) << SERIAL_SHIFT) | $self->{ host_id }; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub get_id { |
75
|
2000
|
|
|
2000
|
0
|
1920670
|
my $self = shift; |
76
|
2000
|
|
50
|
|
|
9683
|
my $key = shift || "_"; |
77
|
2000
|
|
|
|
|
4597
|
$self->_sync(); |
78
|
|
|
|
|
|
|
|
79
|
2000
|
100
|
|
|
|
21563
|
if( !exists $self->{ ids }->{ $key } ) { |
80
|
1
|
|
|
|
|
6
|
$self->{ ids }->{ $key } = $self->{ min_id }; |
81
|
1
|
|
|
|
|
14
|
return $self->{ ids }->{ $key }->bstr; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
1999
|
50
|
|
|
|
11490
|
return if( $self->{ ids }->{ $key } >= $self->{ max_id } ); |
85
|
|
|
|
|
|
|
|
86
|
1999
|
|
|
|
|
118732
|
$self->{ ids }->{ $key } += SERIAL_INCREMENT; |
87
|
1999
|
|
|
|
|
161722
|
return $self->{ ids }->{ $key }->bstr; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
1; |