Skip to content

Commit

Permalink
perf: reduce callback count
Browse files Browse the repository at this point in the history
  • Loading branch information
gurgunday committed Aug 16, 2024
1 parent 8505186 commit e244bf6
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 43 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ The constructor may throw:
- `lookbehindBuffer` (Uint8Array | null): Buffer containing data from previous chunks that might be part of a match.
- `currentBuffer` (Uint8Array | null): The current buffer being processed.

Note:
**Note:**

- The callback will contain EITHER the `lookbehindBuffer` OR the `currentBuffer`, not both at the same time.
The callback will contain **either** the `lookbehindBuffer` or the `currentBuffer`, not both at the same time.

## Usage

Expand Down
2 changes: 1 addition & 1 deletion bench/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import StreamSearch from "streamsearch";
import { Bench } from "tinybench";
import { Buffer } from "node:buffer";

const bench = new Bench({ time: 1000 });
const bench = new Bench({ time: 5000 });
const pattern = "exampleexampleexampleexampleexampleexample";
const longText =
`This is a long text with multiple occurrences of the word example. ` +
Expand Down
52 changes: 22 additions & 30 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,12 @@ const Match = class {
write(chunk) {
const buffer =
chunk instanceof Uint8Array ? chunk : this.#from(String(chunk));
this.#bufferIndex = 0;

while (this.#bufferIndex !== buffer.length) {
this.#bufferIndex = this.#search(buffer);
}

return this.#bufferIndex;
this.#bufferIndex = 0;
}

#search(buffer) {
Expand All @@ -95,23 +94,23 @@ const Match = class {
char === patternLastChar &&
this.#matchPattern(buffer, index, patternLastCharIndex)
) {
if (-index < this.#lookbehindSize) {
++this.#matches;

if (-index === this.#lookbehindSize) {
this.#callback(true, 0, 0, null, null);
} else {
this.#callback(
false,
true,
0,
index + this.#lookbehindSize,
this.#lookbehindSize + index,
this.#lookbehind,
null,
);
}

++this.#matches;
this.#callback(true, 0, 0, null, null);
this.#lookbehindSize = 0;

this.#bufferIndex = index + this.#pattern.length;

return this.#bufferIndex;
return index + this.#pattern.length;
}

index += this.#skip[char];
Expand All @@ -128,9 +127,7 @@ const Match = class {
this.#lookbehind.set(buffer, this.#lookbehindSize - bytesToCutOff);
this.#lookbehindSize += buffer.length;

this.#bufferIndex = buffer.length;

return this.#bufferIndex;
return buffer.length;
}

this.#callback(false, 0, this.#lookbehindSize, this.#lookbehind, null);
Expand All @@ -148,34 +145,28 @@ const Match = class {
) {
++this.#matches;

if (index) {
this.#callback(true, this.#bufferIndex, index, null, buffer);
} else {
if (!index) {
this.#callback(true, 0, 0, null, null);
} else {
this.#callback(true, this.#bufferIndex, index, null, buffer);
}

this.#bufferIndex = index + this.#pattern.length;

return this.#bufferIndex;
return index + this.#pattern.length;
}

index += this.#skip[char];
}

if (index < buffer.length) {
if (index !== this.#bufferIndex) {
this.#callback(false, this.#bufferIndex, index, null, buffer);
}

if (index !== buffer.length) {
this.#lookbehind.set(buffer.subarray(index));
this.#lookbehindSize = buffer.length - index;

if (index !== this.#bufferIndex) {
this.#callback(false, this.#bufferIndex, index, null, buffer);
}
} else {
this.#callback(false, this.#bufferIndex, buffer.length, null, buffer);
}

this.#bufferIndex = buffer.length;

return this.#bufferIndex;
return buffer.length;
}

#matchPattern(buffer, index, length) {
Expand All @@ -201,8 +192,9 @@ const Match = class {

static #table(buffer) {
const table = new Uint8Array(256).fill(buffer.length);
const length = buffer.length - 1;

for (let i = 0, length = buffer.length - 1; i !== length; ++i) {
for (let i = 0; i !== length; ++i) {
table[buffer[i]] = length - i;
}

Expand Down
42 changes: 32 additions & 10 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,19 +260,11 @@ test("pattern test", (t, done) => {
++count;

if (count === 1) {
assert.strictEqual(isMatch, false);
assert.strictEqual(isMatch, true);
assert.strictEqual(start, 0);
assert.strictEqual(end, 1);
assert.strictEqual(String.fromCharCode(l[0]), "s");
assert.strictEqual(b, null);
}

if (count === 2) {
assert.strictEqual(isMatch, true);
assert.strictEqual(start, 0);
assert.strictEqual(end, 0);
assert.strictEqual(l, null);
assert.strictEqual(b, null);
done();
}
});
Expand All @@ -285,7 +277,7 @@ test("pattern test /2", (t, done) => {
let buffer = Buffer.from([]);

const m = new Match("Hello, World!", (isMatch, start, end, l, b) => {
if (!isMatch) {
if (l ?? b) {
buffer = Buffer.concat([buffer, (l ?? b).subarray(start, end)]);
}
});
Expand All @@ -301,3 +293,33 @@ test("pattern test /2", (t, done) => {
assert.deepEqual(buffer.toString("utf8"), `"".........Hello, Gurgun`);
done();
});

test("pattern test /3", (t, done) => {
let buffer = Buffer.from([]);

const m = new Match("Hello, World!", (isMatch, start, end, l, b) => {
if (l ?? b) {
buffer = Buffer.concat([buffer, (l ?? b).subarray(start, end)]);
}
});

m.write("Hello");
m.write(", World.Hello, World.asd");

assert.deepEqual(buffer.toString("utf8"), `Hello, World.Hello, World.`);
done();
});

test("pattern test /4", (t, done) => {
let c = 0;

const m = new Match("Hello, World!", () => {
c++;
});

m.write("Hello");
m.write(", World!");

assert.strictEqual(c, 1);
done();
});

0 comments on commit e244bf6

Please sign in to comment.