File Coverage

tests/shared-primes-3
Criterion Covered Total %
statement 71 75 94.6
branch 11 14 78.5
condition 1 2 50.0
subroutine 8 8 100.0
pod n/a
total 91 99 91.9


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             # The script calculates primes using Arch::SharedIndex package.
4             # It creates multiple processes that all modify the same index.
5             # This version uses perl_data serialization and builds lists of divisors.
6              
7 10     10   7940 use FindBin qw($Bin);
  10         13420  
  10         1540  
8 10     10   8990 use lib "$Bin/../perllib";
  10         8930  
  10         90  
9              
10 10         50 my $auto_test = !@ARGV;
11 10   50     120 my $max_multiplier = shift || 10;
12 10         30 my $max_prime = $max_multiplier * $max_multiplier;
13              
14 10 50   10   15200 use Test::More tests => @ARGV? 2: 9;
  10         272770  
  10         160  
15 10     10   90 use_ok("Arch::SharedIndex");
  10         11250  
  10         40  
  10         30  
  10         330  
16              
17 10         10970 my $file_name = "/tmp/shared-primes-3-$$";
18              
19             sub create_shared_index () {
20 19     19   2988 return Arch::SharedIndex->new(
21             max_size => $max_prime,
22             can_create => 1,
23             file => $file_name,
24             perl_data => 1,
25             );
26             }
27 10         70 my $shared_index = create_shared_index();
28 10         70 is(ref($shared_index), 'Arch::SharedIndex', "create index to calculate primes");
29              
30             # populate the index with all candidates (value [] means prime, no divisors)
31 10         5680 $shared_index->store(map { $_ => [] } 2 .. $max_prime);
  990         1510  
32              
33 10         190 for (my $num = 2; $num <= $max_multiplier; $num++) {
34 54         109610 my $is_parent = fork();
35 54 100       3275 next if $is_parent;
36 9 50       4670 die "Can't fork: $!\n" unless defined $is_parent;
37              
38             # in child, dismiss all multiples of $num
39 9         1687 my %multiples = map { $_ * $num => 1 } 2 .. int($max_prime / $num);
  182         4530  
40 9         992 $shared_index = create_shared_index(); # recreate for testing only
41              
42             # delete all *5 numbers from the index
43 9 100       1189 if ($num == 5) {
44 1     50   186 $shared_index->filter(sub { $multiples{$_[0]} });
  50         157  
45 1         251 exit 0;
46             }
47             $shared_index->update(
48 8     202   1556 sub { [ @{$_[1]}, $num ] }, sub { $multiples{$_[0]} });
  116         236  
  116         728  
  560         1864  
49 8         2151 exit 0;
50             }
51              
52             # delete all even numbers from the index
53 1         130 $shared_index->delete(map { $_ * 2 } 2 .. int($max_prime / 2));
  49         140  
54              
55             # wait for children
56 1         1292994 while (wait() > 0) {}
57              
58 1         35 my @keys = $shared_index->keys;
59 1 100       10 my @values1 = map { @$_? 0: 1 } $shared_index->values;
  41         75  
60 1 100       17 my @values2 = map { @$_? 0: 1 } $shared_index->fetch(@keys);
  41         301  
61 1     41   112 my @primes = sort { $a <=> $b } $shared_index->grep(sub { @{$_[1]} == 0 });
  24         51  
  41         44  
  41         140  
62              
63 1         9 my $num_keys = @keys;
64 1         437 my $num_values1 = @values1;
65 1         5 my $num_values2 = @values2;
66 1         15 my $values1_str = join('', @values1);
67 1         14 my $values2_str = join('', @values2);
68 1         3 my $num_primes = @primes;
69 1         7 my $primes_str = join(', ', @primes);
70              
71 1 50       5 if ($auto_test) {
72 1         2 my $exp_num_keys = 41;
73 1         3 my $exp_values_str = "11110111101011010111001011010110101010010";
74 1         2 my $exp_num_primes = 25;
75 1         8 my $exp_primes_str = "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97";
76 1         16 is($num_keys, $exp_num_keys, "verify num_keys (odd non *5 numbers)");
77 1         1832 is($num_values1, $exp_num_keys, "verify number of values (1)");
78 1         1029 is($values1_str, $exp_values_str, "verify values (1)");
79 1         941 is($num_values1, $exp_num_keys, "verify number of values (2)");
80 1         1288 is($values2_str, $exp_values_str, "verify values (2)");
81 1         1226 is($num_primes, $exp_num_primes, "verify number of primes");
82 1         1198 is($primes_str, $exp_primes_str, "verify primes");
83             } else {
84 0         0 printf "Number of keys (odd non *5 numbers): %d\n", $num_keys;
85 0         0 printf "Values (1-st): %d - %s\n", $num_values1, $values1_str;
86 0         0 printf "Values (2-nd): %d - %s\n", $num_values2, $values2_str;
87 0         0 printf "Primes: %d - %s\n", $num_primes, $primes_str;
88             }
89              
90 1         2483 unlink($file_name);