X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FGitalist.git;a=blobdiff_plain;f=local-lib5%2Flib%2Fperl5%2FGit%2FPurePerl%2FPackIndex%2FVersion1.pm;fp=local-lib5%2Flib%2Fperl5%2FGit%2FPurePerl%2FPackIndex%2FVersion1.pm;h=302ef71509c0e4e57499f0322e555aa76fea2dac;hp=0000000000000000000000000000000000000000;hb=3fea05b9fbf95091f4522528b9980a33e0235603;hpb=af746827daa7a8feccee889e1d12ebc74cc9201e diff --git a/local-lib5/lib/perl5/Git/PurePerl/PackIndex/Version1.pm b/local-lib5/lib/perl5/Git/PurePerl/PackIndex/Version1.pm new file mode 100644 index 0000000..302ef71 --- /dev/null +++ b/local-lib5/lib/perl5/Git/PurePerl/PackIndex/Version1.pm @@ -0,0 +1,72 @@ +package Git::PurePerl::PackIndex::Version1; +use Moose; +use MooseX::StrictConstructor; +use namespace::autoclean; + +extends 'Git::PurePerl::PackIndex'; + +my $FanOutCount = 256; +my $SHA1Size = 20; +my $IdxOffsetSize = 4; +my $OffsetSize = 4; +my $CrcSize = 4; +my $OffsetStart = $FanOutCount * $IdxOffsetSize; +my $SHA1Start = $OffsetStart + $OffsetSize; +my $EntrySize = $OffsetSize + $SHA1Size; +my $EntrySizeV2 = $SHA1Size + $CrcSize + $OffsetSize; + +sub global_offset { + return 0; +} + +sub all_sha1s { + my ( $self, $want_sha1 ) = @_; + my $fh = $self->fh; + my @sha1s; + + my $pos = $OffsetStart; + $fh->seek( $pos, 0 ) || die $!; + foreach my $i ( 1 .. $self->size ) { + $fh->read( my $data, $OffsetSize ) || die $!; + my $offset = unpack( 'N', $data ); + $fh->read( $data, $SHA1Size ) || die $!; + my $sha1 = unpack( 'H*', $data ); + push @sha1s, $sha1; + $pos += $EntrySize; + } + return @sha1s; +} + +sub get_object_offset { + my ( $self, $want_sha1 ) = @_; + my @offsets = $self->offsets; + my $fh = $self->fh; + + my $slot = unpack( 'C', pack( 'H*', $want_sha1 ) ); + return unless defined $slot; + + my ( $first, $last ) = @offsets[ $slot, $slot + 1 ]; + + while ( $first < $last ) { + my $mid = int( ( $first + $last ) / 2 ); + $fh->seek( $SHA1Start + $mid * $EntrySize, 0 ) || die $!; + $fh->read( my $data, $SHA1Size ) || die $!; + my $midsha1 = unpack( 'H*', $data ); + if ( $midsha1 lt $want_sha1 ) { + $first = $mid + 1; + } elsif ( $midsha1 gt $want_sha1 ) { + $last = $mid; + } else { + my $pos = $OffsetStart + $mid * $EntrySize; + $fh->seek( $pos, 0 ) || die $!; + $fh->read( my $data, $OffsetSize ) || die $!; + my $offset = unpack( 'N', $data ); + return $offset; + } + } + + return; +} + +__PACKAGE__->meta->make_immutable; +