Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Git / PurePerl / PackIndex / Version2.pm
1 package Git::PurePerl::PackIndex::Version2;
2 use Moose;
3 use MooseX::StrictConstructor;
4 use namespace::autoclean;
5
6 extends 'Git::PurePerl::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     return 8;
20 }
21
22 sub all_sha1s {
23     my ( $self, $want_sha1 ) = @_;
24     my $fh = $self->fh;
25     my @sha1s;
26     my @data;
27
28     my $pos = $OffsetStart;
29     $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
30     foreach my $i ( 0 .. $self->size - 1 ) {
31         $fh->read( my $sha1, $SHA1Size ) || die $!;
32         $data[$i] = [ unpack( 'H*', $sha1 ), 0, 0 ];
33         $pos += $SHA1Size;
34     }
35     $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
36     foreach my $i ( 0 .. $self->size - 1 ) {
37         $fh->read( my $crc, $CrcSize ) || die $!;
38         $data[$i]->[1] = unpack( 'H*', $crc );
39         $pos += $CrcSize;
40     }
41     $fh->seek( $pos + $self->global_offset, 0 ) || die $!;
42     foreach my $i ( 0 .. $self->size - 1 ) {
43         $fh->read( my $offset, $OffsetSize ) || die $!;
44         $data[$i]->[2] = unpack( 'N', $offset );
45         $pos += $OffsetSize;
46     }
47     foreach my $data (@data) {
48         my ( $sha1, $crc, $offset ) = @$data;
49         push @sha1s, $sha1;
50     }
51
52     return @sha1s;
53 }
54
55 sub get_object_offset {
56     my ( $self, $want_sha1 ) = @_;
57     my @offsets = $self->offsets;
58     my $fh      = $self->fh;
59
60     my $slot = unpack( 'C', pack( 'H*', $want_sha1 ) );
61     return unless defined $slot;
62
63     my ( $first, $last ) = @offsets[ $slot, $slot + 1 ];
64
65     while ( $first < $last ) {
66         my $mid = int( ( $first + $last ) / 2 );
67
68         $fh->seek( $self->global_offset + $OffsetStart + ( $mid * $SHA1Size ),
69             0 )
70             || die $!;
71         $fh->read( my $data, $SHA1Size ) || die $!;
72         my $midsha1 = unpack( 'H*', $data );
73         if ( $midsha1 lt $want_sha1 ) {
74             $first = $mid + 1;
75         } elsif ( $midsha1 gt $want_sha1 ) {
76             $last = $mid;
77         } else {
78             my $pos
79                 = $self->global_offset 
80                 + $OffsetStart
81                 + ( $self->size * ( $SHA1Size + $CrcSize ) )
82                 + ( $mid * $OffsetSize );
83             $fh->seek( $pos, 0 ) || die $!;
84             $fh->read( my $data, $OffsetSize ) || die $!;
85             my $offset = unpack( 'N', $data );
86             return $offset;
87         }
88     }
89     return;
90 }
91
92 __PACKAGE__->meta->make_immutable;
93