| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Math::Prime::Util::PrimeArray; |
|
2
|
2
|
|
|
2
|
|
48704
|
use strict; |
|
|
2
|
|
|
|
|
15
|
|
|
|
2
|
|
|
|
|
69
|
|
|
3
|
2
|
|
|
2
|
|
15
|
use warnings; |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
81
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
BEGIN { |
|
6
|
2
|
|
|
2
|
|
6
|
$Math::Prime::Util::PrimeArray::AUTHORITY = 'cpan:DANAJ'; |
|
7
|
2
|
|
|
|
|
31
|
$Math::Prime::Util::PrimeArray::VERSION = '0.68'; |
|
8
|
|
|
|
|
|
|
} |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# parent is cleaner, and in the Perl 5.10.1 / 5.12.0 core, but not earlier. |
|
11
|
|
|
|
|
|
|
# use parent qw( Exporter ); |
|
12
|
2
|
|
|
2
|
|
10
|
use base qw( Exporter ); |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
516
|
|
|
13
|
|
|
|
|
|
|
our @EXPORT_OK = qw(@primes @prime @pr @p $probj); |
|
14
|
|
|
|
|
|
|
our %EXPORT_TAGS = (all => [ @EXPORT_OK ]); |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
# It would be nice to do this dynamically. |
|
17
|
|
|
|
|
|
|
our(@primes, @prime, @pr, @p, $probj); |
|
18
|
|
|
|
|
|
|
sub import { |
|
19
|
2
|
50
|
|
2
|
|
13
|
tie @primes, __PACKAGE__ if grep { $_ eq '@primes' } @_; |
|
|
2
|
|
|
|
|
9
|
|
|
20
|
2
|
50
|
|
|
|
4
|
tie @prime , __PACKAGE__ if grep { $_ eq '@prime' } @_; |
|
|
2
|
|
|
|
|
5
|
|
|
21
|
2
|
50
|
|
|
|
3
|
tie @pr , __PACKAGE__ if grep { $_ eq '@pr' } @_; |
|
|
2
|
|
|
|
|
6
|
|
|
22
|
2
|
50
|
|
|
|
4
|
tie @p , __PACKAGE__ if grep { $_ eq '@p' } @_; |
|
|
2
|
|
|
|
|
4
|
|
|
23
|
2
|
50
|
|
|
|
4
|
$probj = __PACKAGE__->TIEARRAY if grep { $_ eq '$probj' } @_; |
|
|
2
|
|
|
|
|
4
|
|
|
24
|
2
|
|
|
|
|
1619
|
goto &Exporter::import; |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
|
|
27
|
2
|
|
|
2
|
|
783
|
use Math::Prime::Util qw/nth_prime nth_prime_upper nth_prime_lower primes prime_precalc next_prime prev_prime/; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
20
|
|
|
28
|
2
|
|
|
2
|
|
526
|
use Tie::Array; |
|
|
2
|
|
|
|
|
1804
|
|
|
|
2
|
|
|
|
|
52
|
|
|
29
|
2
|
|
|
2
|
|
12
|
use Carp qw/carp croak confess/; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
87
|
|
|
30
|
|
|
|
|
|
|
|
|
31
|
2
|
|
|
2
|
|
10
|
use constant SEGMENT_SIZE => 50_000; |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
92
|
|
|
32
|
2
|
|
|
2
|
|
9
|
use constant ALLOW_SKIP => 3_000; # Sieve if skipping up to this |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
1181
|
|
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub TIEARRAY { |
|
35
|
4
|
|
|
4
|
|
886
|
my $class = shift; |
|
36
|
4
|
50
|
|
|
|
13
|
if (@_) { |
|
37
|
0
|
|
|
|
|
0
|
croak "usage: tie ARRAY, '" . __PACKAGE__ . ""; |
|
38
|
|
|
|
|
|
|
} |
|
39
|
4
|
|
|
|
|
19
|
return bless { |
|
40
|
|
|
|
|
|
|
# used to keep track of shift |
|
41
|
|
|
|
|
|
|
SHIFTINDEX => 0, |
|
42
|
|
|
|
|
|
|
# Remove all extra prime memory when we go out of scope |
|
43
|
|
|
|
|
|
|
MEMFREE => Math::Prime::Util::MemFree->new, |
|
44
|
|
|
|
|
|
|
# A chunk of primes |
|
45
|
|
|
|
|
|
|
PRIMES => [2, 3, 5, 7, 11, 13, 17], |
|
46
|
|
|
|
|
|
|
# What's the index of the first one? |
|
47
|
|
|
|
|
|
|
BEG_INDEX => 0, |
|
48
|
|
|
|
|
|
|
# What's the index of the last one? |
|
49
|
|
|
|
|
|
|
END_INDEX => 6, |
|
50
|
|
|
|
|
|
|
# positive = forward, negative = backward, 0 = random |
|
51
|
|
|
|
|
|
|
ACCESS_TYPE => 0, |
|
52
|
|
|
|
|
|
|
}, $class; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
0
|
|
|
0
|
|
0
|
sub STORE { carp "You cannot write to the prime array"; } |
|
55
|
0
|
|
|
0
|
|
0
|
sub DELETE { carp "You cannot write to the prime array"; } |
|
56
|
0
|
|
|
0
|
|
0
|
sub STORESIZE { carp "You cannot write to the prime array"; } |
|
57
|
0
|
|
|
0
|
|
0
|
sub EXISTS { 1 } |
|
58
|
|
|
|
|
|
|
#sub EXTEND { my $self = shift; my $count = shift; prime_precalc($count); } |
|
59
|
0
|
|
|
0
|
|
0
|
sub EXTEND { 1 } |
|
60
|
2
|
|
|
2
|
|
6
|
sub FETCHSIZE { 0x7FFF_FFFF } # Even on 64-bit |
|
61
|
|
|
|
|
|
|
# Simple FETCH: |
|
62
|
|
|
|
|
|
|
# sub FETCH { return nth_prime($_[1]+1); } |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub FETCH { |
|
65
|
2067
|
|
|
2067
|
|
19916
|
my ($self, $index) = @_; |
|
66
|
2067
|
50
|
|
|
|
3031
|
$index = 0xFFFFFFFF + $index + 1 if $index < 0; |
|
67
|
2067
|
|
|
|
|
2523
|
$index += $self->{SHIFTINDEX}; # take into account any shifts |
|
68
|
2067
|
|
|
|
|
2437
|
my $begidx = $self->{BEG_INDEX}; |
|
69
|
2067
|
|
|
|
|
2344
|
my $endidx = $self->{END_INDEX}; |
|
70
|
|
|
|
|
|
|
|
|
71
|
2067
|
100
|
100
|
|
|
4787
|
if ( $index < $begidx || $index > $endidx ) { |
|
72
|
|
|
|
|
|
|
|
|
73
|
51
|
100
|
100
|
|
|
176
|
if ($index > $endidx && $index < $endidx + ALLOW_SKIP) { # Forward iteration |
|
|
|
100
|
100
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
|
75
|
22
|
|
|
|
|
30
|
$self->{ACCESS_TYPE}++; |
|
76
|
22
|
100
|
100
|
|
|
58
|
if ($self->{ACCESS_TYPE} > 2 || $index > $endidx+1) { |
|
77
|
16
|
|
|
|
|
371
|
my $end_prime = nth_prime_upper($index + SEGMENT_SIZE); |
|
78
|
16
|
|
|
|
|
56
|
$self->{PRIMES} = primes( $self->{PRIMES}->[-1]+1, $end_prime ); |
|
79
|
16
|
|
|
|
|
33
|
$begidx = $endidx+1; |
|
80
|
|
|
|
|
|
|
} else { |
|
81
|
6
|
|
|
|
|
9
|
push @{$self->{PRIMES}}, next_prime($self->{PRIMES}->[-1]); |
|
|
6
|
|
|
|
|
20
|
|
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
} elsif ($index < $begidx && $index > $begidx - ALLOW_SKIP) { # Bk iteration |
|
85
|
|
|
|
|
|
|
|
|
86
|
22
|
|
|
|
|
29
|
$self->{ACCESS_TYPE}--; |
|
87
|
22
|
100
|
100
|
|
|
52
|
if ($self->{ACCESS_TYPE} < -2 || $index < $begidx-1) { |
|
88
|
14
|
50
|
|
|
|
26
|
my $beg_prime = $index <= SEGMENT_SIZE |
|
89
|
|
|
|
|
|
|
? 2 : nth_prime_lower($index - SEGMENT_SIZE); |
|
90
|
14
|
|
|
|
|
37
|
$self->{PRIMES} = primes($beg_prime, $self->{PRIMES}->[0]-1); |
|
91
|
14
|
|
|
|
|
40
|
$begidx -= scalar @{ $self->{PRIMES} }; |
|
|
14
|
|
|
|
|
37
|
|
|
92
|
|
|
|
|
|
|
} else { |
|
93
|
8
|
|
|
|
|
11
|
$begidx--; |
|
94
|
8
|
|
|
|
|
10
|
unshift @{$self->{PRIMES}}, prev_prime($self->{PRIMES}->[0]); |
|
|
8
|
|
|
|
|
1423
|
|
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
} else { # Random access |
|
98
|
|
|
|
|
|
|
|
|
99
|
7
|
|
|
|
|
19
|
$self->{ACCESS_TYPE} = int($self->{ACCESS_TYPE} / 2); |
|
100
|
|
|
|
|
|
|
# Alternately we could get a small window, but that will be quite |
|
101
|
|
|
|
|
|
|
# a bit slower if true random access. |
|
102
|
7
|
|
|
|
|
10
|
$begidx = $index; |
|
103
|
7
|
|
|
|
|
760
|
$self->{PRIMES} = [nth_prime($begidx+1)]; |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
} |
|
106
|
51
|
|
|
|
|
87
|
$self->{BEG_INDEX} = $begidx; |
|
107
|
51
|
|
|
|
|
59
|
$self->{END_INDEX} = $begidx + scalar @{$self->{PRIMES}} - 1; |
|
|
51
|
|
|
|
|
99
|
|
|
108
|
|
|
|
|
|
|
} |
|
109
|
2067
|
|
|
|
|
4749
|
return $self->{PRIMES}->[ $index - $begidx ]; |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Fake out shift and unshift |
|
113
|
|
|
|
|
|
|
sub SHIFT { |
|
114
|
5
|
|
|
5
|
|
13
|
my $self = shift; |
|
115
|
5
|
|
|
|
|
9
|
my $head = $self->FETCH(0); |
|
116
|
5
|
|
|
|
|
9
|
$self->{SHIFTINDEX}++; |
|
117
|
5
|
|
|
|
|
20
|
$head; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
sub UNSHIFT { |
|
120
|
2
|
|
|
2
|
|
494
|
my ($self, $shiftamount) = @_; |
|
121
|
2
|
50
|
|
|
|
9
|
$shiftamount = 1 unless defined $shiftamount; |
|
122
|
|
|
|
|
|
|
$self->{SHIFTINDEX} = ($shiftamount >= $self->{SHIFTINDEX}) |
|
123
|
|
|
|
|
|
|
? 0 |
|
124
|
2
|
50
|
|
|
|
8
|
: $self->{SHIFTINDEX} - $shiftamount; |
|
125
|
2
|
|
|
|
|
8
|
$self->FETCHSIZE; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
# CLEAR this |
|
128
|
|
|
|
|
|
|
# PUSH this, LIST |
|
129
|
|
|
|
|
|
|
# POP this |
|
130
|
|
|
|
|
|
|
# SPLICE this, offset, len, LIST |
|
131
|
|
|
|
|
|
|
# DESTROY this |
|
132
|
|
|
|
|
|
|
# UNTIE this |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
1; |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
__END__ |