| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Archive::BagIt::Fast; | 
| 2 | 2 |  |  | 2 |  | 8123 | use strict; | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 50 |  | 
| 3 | 2 |  |  | 2 |  | 7 | use warnings; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 59 |  | 
| 4 | 2 |  |  | 2 |  | 8 | use Carp qw( carp croak ); | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 102 |  | 
| 5 | 2 |  |  | 2 |  | 905 | use Time::HiRes qw( time ); | 
|  | 2 |  |  |  |  | 2376 |  | 
|  | 2 |  |  |  |  | 6 |  | 
| 6 | 2 |  |  | 2 |  | 1274 | use Moo; | 
|  | 2 |  |  |  |  | 20883 |  | 
|  | 2 |  |  |  |  | 14 |  | 
| 7 | 2 |  |  | 2 |  | 3397 | use IO::AIO (); | 
|  | 2 |  |  |  |  | 6487 |  | 
|  | 2 |  |  |  |  | 37 |  | 
| 8 | 2 |  |  | 2 |  | 1011 | use Net::SSLeay (); | 
|  | 2 |  |  |  |  | 20641 |  | 
|  | 2 |  |  |  |  | 184 |  | 
| 9 |  |  |  |  |  |  | extends "Archive::BagIt"; | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | our $VERSION = '0.090'; # VERSION | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | # ABSTRACT: A module to use L to get better performance | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | sub BEGIN { | 
| 18 | 2 |  |  | 2 |  | 1221 | Net::SSLeay::OpenSSL_add_all_digests(); | 
| 19 |  |  |  |  |  |  | } | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | sub _XXX_digest { | 
| 22 | 138 |  |  | 138 |  | 163 | my $digestobj = shift; | 
| 23 | 138 |  |  |  |  | 120 | my $data_ref = shift; | 
| 24 | 138 |  |  |  |  | 123 | my $data = ${ $data_ref }; | 
|  | 138 |  |  |  |  | 220 |  | 
| 25 | 138 |  |  |  |  | 639 | my $md  = Net::SSLeay::EVP_get_digestbyname($digestobj->name); | 
| 26 | 138 |  |  |  |  | 279 | my $internal_digest = Net::SSLeay::EVP_MD_CTX_create(); | 
| 27 | 138 |  |  |  |  | 383 | Net::SSLeay::EVP_DigestInit($internal_digest, $md); | 
| 28 | 138 |  |  |  |  | 395 | Net::SSLeay::EVP_DigestUpdate($internal_digest, $data); | 
| 29 | 138 |  |  |  |  | 533 | my $result = Net::SSLeay::EVP_DigestFinal($internal_digest); | 
| 30 | 138 |  |  |  |  | 399 | Net::SSLeay::EVP_MD_CTX_destroy($internal_digest); | 
| 31 | 138 |  |  |  |  | 352 | my $digest = unpack('H*', $result); | 
| 32 | 138 |  |  |  |  | 1791 | return $digest; | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | } | 
| 35 |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  | sub sysread_based_digest { | 
| 37 | 134 |  |  | 134 | 1 | 4990 | my $digestobj = shift; | 
| 38 | 134 |  |  |  |  | 127 | my $fh = shift; | 
| 39 | 134 |  |  |  |  | 131 | my $filesize = shift; | 
| 40 | 134 |  |  |  |  | 126 | my $data; | 
| 41 | 134 |  |  |  |  | 1159 | sysread $fh, $data, $filesize; | 
| 42 | 134 |  |  |  |  | 404 | return _XXX_digest( $digestobj, \$data); | 
| 43 |  |  |  |  |  |  | } | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | sub mmap_based_digest { | 
| 46 | 4 |  |  | 4 | 1 | 5 | my $digestobj = shift; | 
| 47 | 4 |  |  |  |  | 5 | my $fh = shift; | 
| 48 | 4 |  |  |  |  | 4 | my $filesize = shift; | 
| 49 | 4 |  |  |  |  | 5 | my $data=''; | 
| 50 | 4 | 100 |  |  |  | 10 | if ($filesize > 0) { | 
| 51 | 2 | 50 |  |  |  | 59 | if (! IO::AIO::mmap $data, $filesize, IO::AIO::PROT_READ, IO::AIO::MAP_SHARED, $fh) { | 
| 52 | 0 |  |  |  |  | 0 | carp "mmap fails, fall back to sysread"; | 
| 53 | 0 |  |  |  |  | 0 | sysread $fh, $data, $filesize; | 
| 54 |  |  |  |  |  |  | }; | 
| 55 |  |  |  |  |  |  | } | 
| 56 | 4 |  |  |  |  | 11 | return _XXX_digest($digestobj, \$data); | 
| 57 |  |  |  |  |  |  | } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | has 'digest_callback' => ( | 
| 60 |  |  |  |  |  |  | is      => 'ro', | 
| 61 |  |  |  |  |  |  | lazy    => 1, | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | builder => sub { | 
| 64 | 11 |  |  | 11 |  | 336679 | my ($self) = shift; | 
| 65 |  |  |  |  |  |  | #my $sub = sub { | 
| 66 |  |  |  |  |  |  | #    my ($digestobj, $filename) = @_; | 
| 67 |  |  |  |  |  |  | #    open(my $fh, "<:raw", "$filename") or croak ("Cannot open $filename, $!"); | 
| 68 |  |  |  |  |  |  | #    binmode($fh); | 
| 69 |  |  |  |  |  |  | #    my $digest = $digestobj->get_hash_string($fh); | 
| 70 |  |  |  |  |  |  | #    close $fh || croak("could not close file '$filename', $!"); | 
| 71 |  |  |  |  |  |  | #    return $digest; | 
| 72 |  |  |  |  |  |  | #}; | 
| 73 |  |  |  |  |  |  | my $sub = sub { | 
| 74 | 130 |  |  | 130 |  | 34389 | my $digestobj = shift; | 
| 75 | 130 |  |  |  |  | 152 | my $filename =shift; | 
| 76 | 130 |  |  |  |  | 123 | my $opts = shift; | 
| 77 | 130 |  | 50 |  |  | 464 | my $MMAP_MIN = $opts->{mmap_min} || 8000000; | 
| 78 | 130 |  |  |  |  | 1581 | my $filesize = -s $filename; | 
| 79 | 130 | 50 |  |  |  | 4074 | open(my $fh, "<:raw", "$filename") or croak ("Cannot open $filename, $!"); | 
| 80 | 130 |  |  |  |  | 610 | $self->{stats}->{files}->{"$filename"}->{size}= $filesize; | 
| 81 | 130 |  |  |  |  | 182 | $self->{stats}->{size} += $filesize; | 
| 82 | 130 |  |  |  |  | 327 | my $start_time = time(); | 
| 83 | 130 |  |  |  |  | 119 | my $digest; | 
| 84 | 130 | 50 |  |  |  | 213 | if ($filesize < $MMAP_MIN ) { | 
|  |  | 0 |  |  |  |  |  | 
| 85 | 130 |  |  |  |  | 230 | return sysread_based_digest($digestobj, $fh, $filesize); | 
| 86 |  |  |  |  |  |  | } | 
| 87 |  |  |  |  |  |  | elsif ( $filesize < 1500000000) { | 
| 88 | 0 |  |  |  |  | 0 | return mmap_based_digest($digestobj, $fh, $filesize); | 
| 89 |  |  |  |  |  |  | } | 
| 90 |  |  |  |  |  |  | else { | 
| 91 | 0 |  |  |  |  | 0 | $digest = $digestobj->get_hash_string($fh); | 
| 92 |  |  |  |  |  |  | } | 
| 93 | 0 |  |  |  |  | 0 | my $finish_time = time(); | 
| 94 | 0 |  |  |  |  | 0 | $self->{stats}->{files}->{"$filename"}->{verify_time}= ($finish_time - $start_time); | 
| 95 | 0 |  |  |  |  | 0 | $self->{stats}->{verify_time} += ($finish_time-$start_time); | 
| 96 | 0 |  |  |  |  | 0 | close($fh); | 
| 97 | 0 |  |  |  |  | 0 | return $digest; | 
| 98 | 11 |  |  |  |  | 95 | }; | 
| 99 | 11 |  |  |  |  | 48 | return $sub; | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  | ); | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | 1; | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | __END__ |