File Coverage

blib/lib/Cogit/PackIndex/Version2.pm
Criterion Covered Total %
statement 48 51 94.1
branch 13 26 50.0
condition n/a
subroutine 5 5 100.0
pod 0 3 0.0
total 66 85 77.6


line stmt bran cond sub pod time code
1             package Cogit::PackIndex::Version2;
2             $Cogit::PackIndex::Version2::VERSION = '0.001001';
3 4     4   17 use Moo;
  4         3  
  4         22  
4 4     4   7731 use namespace::clean;
  4         8  
  4         29  
5              
6             extends 'Cogit::PackIndex';
7              
8             my $FanOutCount = 256;
9             my $SHA1Size = 20;
10             my $IdxOffsetSize = 4;
11             my $OffsetSize = 4;
12             my $CrcSize = 4;
13             my $OffsetStart = $FanOutCount * $IdxOffsetSize;
14             my $SHA1Start = $OffsetStart + $OffsetSize;
15             my $EntrySize = $OffsetSize + $SHA1Size;
16             my $EntrySizeV2 = $SHA1Size + $CrcSize + $OffsetSize;
17              
18             sub global_offset {
19 53     53 0 516 return 8;
20             }
21              
22             sub all_sha1s {
23 2     2 0 12 my ( $self, $want_sha1 ) = @_;
24 2         29 my $fh = $self->fh;
25 2         7 my @sha1s;
26             my @data;
27              
28 2         3 my $pos = $OffsetStart;
29 2 50       4 $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
30 2         40 for my $i ( 0 .. $self->size - 1 ) {
31 18 50       33 $fh->read( my $sha1, $SHA1Size ) || die $!;
32 18         87 $data[$i] = [ unpack( 'H*', $sha1 ), 0, 0 ];
33 18         16 $pos += $SHA1Size;
34             }
35 2 50       3 $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
36 2         42 for my $i ( 0 .. $self->size - 1 ) {
37 18 50       31 $fh->read( my $crc, $CrcSize ) || die $!;
38 18         76 $data[$i]->[1] = unpack( 'H*', $crc );
39 18         15 $pos += $CrcSize;
40             }
41 2 50       6 $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
42 2         50 for my $i ( 0 .. $self->size - 1 ) {
43 18 50       41 $fh->read( my $offset, $OffsetSize ) || die $!;
44 18         78 $data[$i]->[2] = unpack( 'N', $offset );
45 18         294 $pos += $OffsetSize;
46             }
47 2         6 for my $data (@data) {
48 18         23 my ( $sha1, $crc, $offset ) = @$data;
49 18         25 push @sha1s, $sha1;
50             }
51              
52 2         112 return @sha1s;
53             }
54              
55             sub get_object_offset {
56 23     23 0 109 my ( $self, $want_sha1 ) = @_;
57 23         21 my @offsets = @{$self->offsets};
  23         311  
58 23         631 my $fh = $self->fh;
59              
60 23         171 my $slot = unpack( 'C', pack( 'H*', $want_sha1 ) );
61 23 50       47 return unless defined $slot;
62              
63 23         40 my ( $first, $last ) = @offsets[ $slot, $slot + 1 ];
64              
65 23         38 while ( $first < $last ) {
66 23         50 my $mid = int( ( $first + $last ) / 2 );
67              
68 23 50       44 $fh->seek( $self->global_offset + $OffsetStart + ( $mid * $SHA1Size ),
69             0 )
70             || die $!;
71 23 50       223 $fh->read( my $data, $SHA1Size ) || die $!;
72 23         241 my $midsha1 = unpack( 'H*', $data );
73 23 50       64 if ( $midsha1 lt $want_sha1 ) {
    50          
74 0         0 $first = $mid + 1;
75             } elsif ( $midsha1 gt $want_sha1 ) {
76 0         0 $last = $mid;
77             } else {
78 23         36 my $pos
79             = $self->global_offset
80             + $OffsetStart
81             + ( $self->size * ( $SHA1Size + $CrcSize ) )
82             + ( $mid * $OffsetSize );
83 23 50       126 $fh->seek( $pos, 0 ) || die $!;
84 23 50       141 $fh->read( my $data, $OffsetSize ) || die $!;
85 23         178 my $offset = unpack( 'N', $data );
86 23         159 return $offset;
87             }
88             }
89 0           return;
90             }
91              
92             1;
93              
94             __END__
95              
96             =pod
97              
98             =encoding UTF-8
99              
100             =head1 NAME
101              
102             Cogit::PackIndex::Version2
103              
104             =head1 VERSION
105              
106             version 0.001001
107              
108             =head1 AUTHOR
109              
110             Arthur Axel "fREW" Schmidt <cogit@afoolishmanifesto.com>
111              
112             =head1 COPYRIGHT AND LICENSE
113              
114             This software is copyright (c) 2017 by Arthur Axel "fREW" Schmidt.
115              
116             This is free software; you can redistribute it and/or modify it under
117             the same terms as the Perl 5 programming language system itself.
118              
119             =cut