Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git
<?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;
  }
}