Last active
April 8, 2022 19:21
-
-
Save SEUH/39e7ceef6a52dd14405c470713880157 to your computer and use it in GitHub Desktop.
[WIP] Reverse SplFileObject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class ReverseSplFileObject | |
{ | |
private SplFileObject $file; | |
private int $readPointer; | |
/** | |
* @var int|mixed | |
*/ | |
private int $cacheSize; | |
private int $lineCount; | |
private array $buffer; | |
private int $bufferSize; | |
private int $bufferPointer; | |
private bool $reachedStartOfFile = false; | |
public function __construct($filePath, $cacheSize = 100) | |
{ | |
$this->file = new SplFileObject($filePath); | |
$this->cacheSize = $cacheSize; | |
// Broken | |
// $spl->fseek(0, SEEK_END); | |
$this->file->seek($this->file->getSize()); | |
// SplFileObject has always 1 line | |
$this->lineCount = $this->file->key() + 1; | |
$this->readPointer = $this->lineCount; | |
} | |
public function current() | |
{ | |
if (empty($this->buffer)) { | |
$this->readToBuffer(); | |
} | |
return $this->buffer[$this->bufferPointer]; | |
} | |
public function prev() | |
{ | |
if ($this->sof()) { | |
return false; | |
} | |
if (empty($this->buffer)) { | |
$this->readToBuffer(); | |
} | |
$this->bufferPointer++; | |
if ($this->bufferPointer >= $this->bufferSize) { | |
// If already read from first line, then SOF is reached. Force bufferPointer | |
// to be last entry of buffer. | |
if ($this->readPointer === 0) { | |
$this->reachedStartOfFile = true; | |
$this->bufferPointer = $this->bufferSize - 1; | |
return false; | |
} | |
$this->readToBuffer(); | |
} | |
return true; | |
} | |
private function readToBuffer() | |
{ | |
$start = max($this->readPointer - $this->cacheSize, 0); | |
$amount = $start === 0 ? $this->readPointer : $this->cacheSize; | |
$iter = new \LimitIterator($this->file, $start, $amount); | |
$this->buffer = array_reverse(iterator_to_array($iter)); | |
$this->bufferSize = $amount; | |
$this->readPointer = $start; | |
$this->bufferPointer = 0; | |
} | |
public function sof() | |
{ | |
return $this->reachedStartOfFile; | |
} | |
public function eof() | |
{ | |
return $this->file->eof(); | |
} | |
public function lineCount() | |
{ | |
return $this->lineCount; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$file = new ReverseSplFileObject('test.log'); | |
do { | |
echo $file->current() . "\n"; | |
} while ($file->prev()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment