| | private string $packFile; |
| | private array $fanoutCache; |
| | + private string $buffer; |
| | + private int $bufferOffset; |
| | |
| | public function __construct( string $indexFile ) { |
| | - $this->indexFile = $indexFile; |
| | - $this->packFile = str_replace( '.idx', '.pack', $indexFile ); |
| | - $this->fanoutCache = []; |
| | + $this->indexFile = $indexFile; |
| | + $this->packFile = str_replace( '.idx', '.pack', $indexFile ); |
| | + $this->fanoutCache = []; |
| | + $this->buffer = ''; |
| | + $this->bufferOffset = -1; |
| | } |
| | |
 |
| | while( $result === 0 && $low <= $high ) { |
| | $mid = ($low + $high) >> 1; |
| | - |
| | - fseek( $handle, 1032 + $mid * 20 ); |
| | - |
| | - $cmp = fread( $handle, 20 ); |
| | + $pos = 1032 + $mid * 20; |
| | + $cmp = $this->readShaBytes( $handle, $pos ); |
| | |
| | if( $cmp < $sha ) { |
 |
| | $onFound( $this->packFile, $result ); |
| | } |
| | + } |
| | + } |
| | + |
| | + private function readShaBytes( mixed $handle, int $pos ): string { |
| | + $result = ''; |
| | + |
| | + if( |
| | + $this->bufferOffset === -1 || |
| | + $pos < $this->bufferOffset || |
| | + $pos + 20 > $this->bufferOffset + 8192 |
| | + ) { |
| | + fseek( $handle, $pos ); |
| | + |
| | + $this->bufferOffset = $pos; |
| | + $this->buffer = fread( $handle, 8192 ); |
| | } |
| | + |
| | + $offset = $pos - $this->bufferOffset; |
| | + return substr( $this->buffer, $offset, 20 ); |
| | } |
| | |
 |
| | $offset = unpack( 'J', fread( $handle, 8 ) )[1]; |
| | } |
| | - |
| | - $result = (int)$offset; |
| | |
| | - return $result; |
| | + return (int)$offset; |
| | } |
| | } |