| | +<?php |
| | +require_once __DIR__ . '/PackIndex.php'; |
| | +require_once __DIR__ . '/FileHandlePool.php'; |
| | + |
| | +class PackLocator { |
| | + private array $indexes; |
| | + |
| | + public function __construct( string $objectsPath ) { |
| | + $this->indexes = []; |
| | + $packFiles = glob( "{$objectsPath}/pack/*.idx" ) ?: []; |
| | + |
| | + foreach( $packFiles as $indexFile ) { |
| | + $this->indexes[] = new PackIndex( $indexFile ); |
| | + } |
| | + } |
| | + |
| | + public function locate( |
| | + FileHandlePool $pool, |
| | + string $sha, |
| | + callable $action |
| | + ): void { |
| | + if( strlen( $sha ) === 40 && ctype_xdigit( $sha ) ) { |
| | + $binarySha = hex2bin( $sha ); |
| | + $found = false; |
| | + $count = count( $this->indexes ); |
| | + $index = 0; |
| | + |
| | + while( !$found && $index < $count ) { |
| | + $this->indexes[$index]->search( |
| | + $pool, |
| | + $binarySha, |
| | + function( |
| | + string $packFile, |
| | + int $offset |
| | + ) use ( |
| | + &$found, |
| | + $index, |
| | + $action |
| | + ): void { |
| | + $found = true; |
| | + |
| | + if( $index > 0 ) { |
| | + $temp = $this->indexes[0]; |
| | + $this->indexes[0] = $this->indexes[$index]; |
| | + $this->indexes[$index] = $temp; |
| | + } |
| | + |
| | + $action( $packFile, $offset ); |
| | + } |
| | + ); |
| | + |
| | + $index++; |
| | + } |
| | + } |
| | + } |
| | +} |
| | |