| | |
| | private function processTree( string $data, callable $callback ): void { |
| | + $entries = []; |
| | $position = 0; |
| | |
 |
| | $isDir = ($mode === self::MODE_TREE || $mode === self::MODE_TREE_A); |
| | |
| | - // Fast size calculation due to caching + binary search |
| | - $size = $isDir ? 0 : $this->getObjectSize( $entrySha ); |
| | + $entries[] = [ |
| | + 'name' => $name, |
| | + 'sha' => $entrySha, |
| | + 'mode' => $mode, |
| | + 'isDir' => $isDir, |
| | + 'size' => 0 |
| | + ]; |
| | |
| | - $callback( new File( $name, $entrySha, $mode, 0, $size ) ); |
| | $position = $nullPos + 21; |
| | + } |
| | + |
| | + $lookupOrder = $entries; |
| | + usort( $lookupOrder, fn($a, $b) => strcmp( $a['sha'], $b['sha'] ) ); |
| | + |
| | + $sizeCache = []; |
| | + |
| | + foreach( $lookupOrder as $item ) { |
| | + if( !$item['isDir'] ) { |
| | + $sizeCache[$item['sha']] = $this->getObjectSize( $item['sha'] ); |
| | + } |
| | + } |
| | + |
| | + foreach( $entries as $e ) { |
| | + $finalSize = $e['isDir'] ? 0 : ($sizeCache[$e['sha']] ?? 0); |
| | + $callback( new File( $e['name'], $e['sha'], $e['mode'], 0, $finalSize ) ); |
| | } |
| | } |