File Coverage

tests/shared-primes-4
Criterion Covered Total %
statement 76 81 93.8
branch 15 22 68.1
condition 1 2 50.0
subroutine 9 10 90.0
pod n/a
total 101 115 87.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2              
3             # The script calculates primes using Arch::SharedCache package.
4             # It creates multiple processes that all modify the same cache.
5             # This version uses perl_data serialization and builds lists of divisors.
6              
7 10     10   8720 use FindBin qw($Bin);
  10         14160  
  10         1420  
8 10     10   8200 use lib "$Bin/../perllib";
  10         12970  
  10         70  
9              
10 10         40 my $auto_test = !@ARGV;
11 10   50     100 my $max_multiplier = shift || 10;
12 10         30 my $max_prime = $max_multiplier * $max_multiplier;
13              
14 10 50   10   14340 use Test::More tests => @ARGV? 2: 9;
  10         226240  
  10         170  
15 10     10   70 use_ok("Arch::SharedCache");
  10         10680  
  10         40  
  10         30  
  10         270  
16              
17 10         11670 my $dir_name = "/tmp/shared-primes-4-$$";
18              
19             sub create_shared_index () {
20 19     19   1361 return Arch::SharedCache->new(
21             max_size => $max_prime,
22             can_create => 1,
23             dir => $dir_name,
24             perl_data => 1,
25             );
26             }
27 10         70 my $shared_index = create_shared_index();
28 10         80 is(ref($shared_index), 'Arch::SharedCache', "create cache to calculate primes");
29              
30             # populate the index with all candidates (value [] means prime, no divisors)
31 10     990   9970 my @values = $shared_index->fetch_store(sub { [] }, 2 .. $max_prime);
  990         3210  
32 10 50       490 die "Internal error #1 in fetch_store\n" if grep { !$_ || @$_ != 0 } @values;
  990 50       3140  
33 10     0   150 @values = $shared_index->fetch_store(sub { [ 9 ] }, 2 .. $max_prime);
  0         0  
34 10 50       190 die "Internal error #2 in fetch_store\n" if grep { !$_ || @$_ != 0 } @values;
  990 50       3710  
35              
36 10         70 for (my $num = 2; $num <= $max_multiplier; $num++) {
37 54         176894 my $is_parent = fork();
38 54 100       3670 next if $is_parent;
39 9 50       2327 die "Can't fork: $!\n" unless defined $is_parent;
40              
41             # in child, dismiss all multiples of $num
42 9         1145 my %multiples = map { $_ * $num => 1 } 2 .. int($max_prime / $num);
  182         2918  
43 9         475 $shared_index = create_shared_index(); # recreate for testing only
44              
45             # delete all *5 numbers from the index
46 9 100       1170 if ($num == 5) {
47 1     50   79 $shared_index->filter(sub { $multiples{$_[0]} });
  50         219  
48 1         254 exit 0;
49             }
50             $shared_index->update(
51 8     192   900 sub { [ @{$_[1]}, $num ] }, sub { $multiples{$_[0]} });
  97         271  
  97         1184  
  489         4541  
52 8         7474 exit 0;
53             }
54              
55             # delete all even numbers from the index
56 1         129 $shared_index->delete(map { $_ * 2 } 2 .. int($max_prime / 2));
  49         222  
57              
58             # wait for children
59 1         2185808 while (wait() > 0) {}
60              
61 1         36 my @keys = $shared_index->keys;
62 1 100       20 my @values1 = map { @$_? 0: 1 } $shared_index->values;
  41         84  
63 1 100       21 my @values2 = map { @$_? 0: 1 } $shared_index->fetch(@keys);
  41         60  
64 1     41   33 my @primes = sort { $a <=> $b } $shared_index->grep(sub { @{$_[1]} == 0 });
  24         36  
  41         81  
  41         166  
65              
66 1         7 my $num_keys = @keys;
67 1         3 my $num_values1 = @values1;
68 1         4 my $num_values2 = @values2;
69 1         12 my $values1_str = join('', @values1);
70 1         11 my $values2_str = join('', @values2);
71 1         2 my $num_primes = @primes;
72 1         6 my $primes_str = join(', ', @primes);
73              
74 1 50       22 if ($auto_test) {
75 1         2 my $exp_num_keys = 41;
76 1         5 my $exp_values_str = "11110111101011010111001011010110101010010";
77 1         2 my $exp_num_primes = 25;
78 1         3 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";
79 1         16 is($num_keys, $exp_num_keys, "verify num_keys (odd non *5 numbers)");
80 1         1098 is($num_values1, $exp_num_keys, "verify number of values (1)");
81 1         472 is($values1_str, $exp_values_str, "verify values (1)");
82 1         514 is($num_values1, $exp_num_keys, "verify number of values (2)");
83 1         404 is($values2_str, $exp_values_str, "verify values (2)");
84 1         455 is($num_primes, $exp_num_primes, "verify number of primes");
85 1         406 is($primes_str, $exp_primes_str, "verify primes");
86             } else {
87 0         0 printf "Number of keys (odd non *5 numbers): %d\n", $num_keys;
88 0         0 printf "Values (1-st): %d - %s\n", $num_values1, $values1_str;
89 0         0 printf "Values (2-nd): %d - %s\n", $num_values2, $values2_str;
90 0         0 printf "Primes: %d - %s\n", $num_primes, $primes_str;
91             }
92              
93 1         16722 system("/bin/rm -rf '$dir_name'");