<?php require_once __DIR__ . '/BufferedReader.php'; class PackStreamManager { private array $readers = []; public function computeInt( string $path, callable $callback, int $default ): int { $result = $default; $reader = $this->acquire( $path ); if( $reader->isOpen() ) { try { $result = $callback( $reader ); } finally { $this->release( $path, $reader ); } } return $result; } public function computeIntDedicated( string $path, callable $callback, int $default ): int { $reader = new BufferedReader( $path ); return $reader->isOpen() ? $callback( $reader ) : $default; } public function computeStringDedicated( string $path, callable $callback, string $default ): string { $reader = new BufferedReader( $path ); return $reader->isOpen() ? $callback( $reader ) : $default; } public function computeArray( string $path, callable $callback, array $default ): array { $result = $default; $reader = $this->acquire( $path ); if( $reader->isOpen() ) { try { $result = $callback( $reader ); } finally { $this->release( $path, $reader ); } } return $result; } public function streamGenerator( string $path, callable $callback ): Generator { $reader = $this->acquire( $path ); if( $reader->isOpen() ) { try { yield from $callback( $reader ); } finally { $this->release( $path, $reader ); } } } public function streamGeneratorDedicated( string $path, callable $callback ): Generator { $reader = new BufferedReader( $path ); if( $reader->isOpen() ) { yield from $callback( $reader ); } } private function acquire( string $path ): BufferedReader { return !empty( $this->readers[$path] ) ? \array_pop( $this->readers[$path] ) : new BufferedReader( $path ); } private function release( string $path, BufferedReader $reader ): void { if( !isset( $this->readers[$path] ) ) { $this->readers[$path] = []; } $this->readers[$path][] = $reader; } }