Skip to content

Commit ee1f422

Browse files
authored
Merge pull request #1179 from nextcloud/logiterator-larger-chunks
perf: read larger chunks in logiterator
2 parents 43e6c1f + 32f93c2 commit ee1f422

File tree

1 file changed

+27
-47
lines changed

1 file changed

+27
-47
lines changed

lib/Log/LogIterator.php

Lines changed: 27 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -29,39 +29,22 @@ class LogIterator implements \Iterator {
2929
* @var resource
3030
*/
3131
private $handle;
32+
private string $buffer = '';
33+
private int $position = 0;
34+
private string $lastLine;
3235

33-
/**
34-
* @var int
35-
*/
36-
private $position = 0;
37-
38-
/**
39-
* @var string
40-
*/
41-
private $lastLine;
42-
43-
/**
44-
* @var string
45-
*/
46-
private $currentLine = '';
47-
48-
private $currentKey = -1;
36+
private int $currentKey = -1;
37+
private string $dateFormat;
38+
private \DateTimeZone $timezone;
4939

50-
/**
51-
* @var string
52-
*/
53-
private $dateFormat;
54-
55-
private $timezone;
56-
57-
public const CHUNK_SIZE = 100; // how many chars do we try at once to find a new line
40+
public const CHUNK_SIZE = 8192; // how many chars do we try at once to find a new line
5841

5942
/**
6043
* @param resource $handle
6144
* @param string $dateFormat
6245
* @param string $timezone
6346
*/
64-
public function __construct($handle, $dateFormat, $timezone) {
47+
public function __construct($handle, string $dateFormat, string $timezone) {
6548
$this->handle = $handle;
6649
$this->dateFormat = $dateFormat;
6750
$this->timezone = new \DateTimeZone($timezone);
@@ -71,7 +54,7 @@ public function __construct($handle, $dateFormat, $timezone) {
7154

7255
public function rewind(): void {
7356
fseek($this->handle, 0, SEEK_END);
74-
$this->position = ftell($this->handle) - self::CHUNK_SIZE;
57+
$this->position = ftell($this->handle);
7558
$this->currentKey = 0;
7659
}
7760

@@ -96,32 +79,29 @@ public function key(): int {
9679
return $this->currentKey;
9780
}
9881

99-
public function next(): void {
100-
$this->currentLine = '';
82+
private function fillBuffer(): void {
83+
$chunkSize = min($this->position, self::CHUNK_SIZE);
84+
$this->position -= $chunkSize;
85+
fseek($this->handle, $this->position);
86+
$chunk = fread($this->handle, $chunkSize);
87+
$this->buffer = $chunk . $this->buffer;
88+
}
10189

90+
public function next(): void {
10291
// Loop through each character of the file looking for new lines
103-
while ($this->position > 0) {
104-
fseek($this->handle, $this->position);
105-
$chars = fread($this->handle, self::CHUNK_SIZE);
106-
$newlinePos = strrpos($chars, "\n");
92+
while ($this->position >= 0) {
93+
$newlinePos = strrpos($this->buffer, "\n");
10794
if ($newlinePos !== false) {
108-
$this->currentLine = substr($chars, $newlinePos + 1) . $this->currentLine;
109-
$this->lastLine = $this->currentLine;
95+
$this->lastLine = substr($this->buffer, $newlinePos + 1);
96+
$this->buffer = substr($this->buffer, 0, $newlinePos);
11097
$this->currentKey++;
111-
$this->position -= (self::CHUNK_SIZE - $newlinePos);
98+
return;
99+
} elseif ($this->position === 0) {
100+
$this->lastLine = $this->buffer;
101+
$this->buffer = '';
112102
return;
113103
} else {
114-
$this->currentLine = $chars . $this->currentLine;
115-
if ($this->position >= self::CHUNK_SIZE) {
116-
$this->position -= self::CHUNK_SIZE;
117-
} else {
118-
$remaining = $this->position;
119-
fseek($this->handle, 0);
120-
$chars = fread($this->handle, $remaining);
121-
$this->currentLine = $chars . $this->currentLine;
122-
$this->lastLine = $this->currentLine;
123-
$this->position = 0;
124-
}
104+
$this->fillBuffer();
125105
}
126106
}
127107
}
@@ -135,7 +115,7 @@ public function valid(): bool {
135115
return true;
136116
}
137117

138-
if ($this->currentLine === '') {
118+
if ($this->lastLine === '') {
139119
return false;
140120
}
141121

0 commit comments

Comments
 (0)