Skip to content

Commit d30b46a

Browse files
committed
feat: new buffer implementation
1 parent 89a5f29 commit d30b46a

File tree

3 files changed

+239
-204
lines changed

3 files changed

+239
-204
lines changed

src/buffer.js

Lines changed: 47 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,70 @@
1-
const BUFFER_SIZE = 10000; // lines
1+
const BUFFER_SIZE = 100; // lines
22

3-
const { readChunk } = require('./file');
3+
const { readChunk, countLines } = require('./file');
44

55
class FileBuffer {
6-
constructor(file, { firstLine=0, bufferSize=BUFFER_SIZE, _readChunk=readChunk }) {
6+
constructor(file, { firstLine=0, bufferSize=BUFFER_SIZE, _readChunk=readChunk, log=console.log }={}) {
77
this.file = file;
8-
this.firstLine = firstLine;
9-
this.readChunk = _readChunk;
8+
this.firstBufferLine = firstLine;
109
this.bufferSize = bufferSize;
10+
this.readChunk = _readChunk;
11+
this.log = log;
1112
}
1213

13-
get lastLine() {
14-
return this.firstLine + this.bufferSize;
14+
get lastBufferLine() {
15+
return this.firstBufferLine + this.lines.length || 0;
1516
}
1617

17-
read(callback) {
18-
this.readChunk({
19-
file: this.file,
20-
start: this.firstLine,
21-
length: this.bufferSize,
22-
}, lines => {
23-
this.lines = lines;
24-
callback(lines);
25-
});
26-
}
18+
get(line, count, callback) {
19+
if (!this.lines) {
20+
this.log('initial load');
21+
return this.countLines(total => {
22+
this.lastFileLine = total;
23+
this.loadBuffer(line, count, callback);
24+
});
25+
}
2726

28-
get bufferRange() {
29-
return [this.firstLine, this.lastLine];
30-
}
27+
if (line + count > this.lastFileLine) {
28+
this.log('after end of file');
29+
count = this.lastFileLine - line;
30+
}
3131

32-
isInCache(n, length) {
33-
return FileBuffer.withinRange(this.bufferRange, [n, n + length]);
34-
}
32+
// this.log('line', line);
33+
// this.log('this.firstBufferLine', this.firstBufferLine);
34+
// this.log('this.lastBufferLine', this.lastBufferLine);
3535

36-
readLines(n, length, callback) {
37-
this.firstLine = n;
38-
this.readChunk({
39-
file: this.file,
40-
start: this.firstLine,
41-
length: this.bufferSize,
42-
}, lines => {
43-
this.lines = lines;
44-
callback(lines.slice(0, length));
45-
});
46-
}
36+
if (line < this.firstBufferLine) {
37+
this.log('before buffer');
38+
return this.loadBuffer(line, count, callback);
39+
}
4740

48-
redoLines(n, length, callback) {
49-
this.readChunk({
50-
file: this.file,
51-
start: n,
52-
length: this.bufferSize / 2,
53-
}, lines => {
54-
const newLines = this.lines.concat(lines);
55-
const pos = newLines.length - this.bufferSize;
56-
this.lines = newLines.slice(pos);
57-
callback(lines.slice(0, length));
58-
});
59-
}
41+
// this.log('(line + count)', (line + count));
6042

61-
getLines(n, length, callback) {
62-
if (this.isInCache(n, length)) {
63-
return this.lines.slice(n, n+length);
43+
if ((line + count) > this.lastBufferLine) {
44+
this.log('after buffer');
45+
return this.loadBuffer(line, count, callback);
6446
}
6547

66-
const missingLines = FileBuffer.missingLines(this.bufferRange, [n, n + length]);
67-
if (missingLines) {
68-
this.redoLines(n, length, callback);
69-
} else {
70-
this.readLines(n, length, callback);
71-
}
48+
const start = line - this.firstBufferLine;
49+
callback(this.lines.slice(start, start + count));
7250
}
73-
}
74-
75-
FileBuffer.withinRange = (range, compare) => {
76-
return compare[0] >= range[0] && compare[1] <= range[1];
77-
};
7851

79-
FileBuffer.rangePosition = (r1, r2) => {
80-
if (r2[1] > r1[1] && r2[0] <= r1[1]) {
81-
return 1;
82-
}
83-
if (r2[0] < r1[0] && r2[1] >= r1[0]) {
84-
return -1;
52+
countLines(callback) {
53+
countLines(this.file, callback);
8554
}
86-
};
8755

88-
FileBuffer.missingLines = (range, required) => {
89-
const position = FileBuffer.rangePosition(range, required);
90-
if (position === -1) {
91-
return [required[0], range[0]-1];
92-
}
93-
if (position === 1) {
94-
return [range[1]+1, required[1]];
56+
loadBuffer(line, count, callback) {
57+
const start = Math.max(0, line - this.bufferSize / 2);
58+
const length = this.bufferSize;
59+
60+
this.log('start', start);
61+
62+
return this.readChunk({ file: this.file, start, length }, lines => {
63+
this.firstBufferLine = start;
64+
this.lines = lines;
65+
this.get(line, count, callback);
66+
});
9567
}
96-
};
68+
}
9769

9870
module.exports = FileBuffer;

src/widgets/MainPanel.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const _ = require('lodash');
33

44
const { formatRows, levelColors } = require('../utils');
55
const { readChunk, countLines } = require('../file');
6+
const FileBuffer = require('../buffer');
67

78
const BaseWidget = require('./BaseWidget');
89
const LogDetails = require('./LogDetails');
@@ -29,6 +30,7 @@ class MainPanel extends BaseWidget {
2930
this.updated = true;
3031
this.loading = false;
3132
this.lastRow = null;
33+
this.fileBuffer = new FileBuffer(this.file, { log: this.log.bind(this) });
3234

3335
this.log('pageWidth', this.pageWidth);
3436
this.on('resize', () => {
@@ -87,11 +89,16 @@ class MainPanel extends BaseWidget {
8789

8890
this.log('readLines', filters);
8991

90-
readChunk({ file, start, length, filter, log: (...s) => this.log(...s) }, lines => {
92+
this.fileBuffer.get(start, length, lines => {
9193
this.lines = lines;
9294
this.renderLines();
9395
this.clearLoading();
9496
});
97+
// readChunk({ file, start, length, filter, log: (...s) => this.log(...s) }, lines => {
98+
// this.lines = lines;
99+
// this.renderLines();
100+
// this.clearLoading();
101+
// });
95102
}
96103

97104
calcLines() {

0 commit comments

Comments
 (0)