Skip to content

Commit 97f3e0b

Browse files
committed
v 1.0
1 parent a2cb917 commit 97f3e0b

File tree

3 files changed

+82
-6
lines changed

3 files changed

+82
-6
lines changed

packages/gearhash-wasm/README.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,57 @@
11
JS and WASM implementations of https://github.com/srijs/rust-gearhash
22

3-
Using [AssemblyScript](https://www.assemblyscript.org/) to generate a lean WASM.
3+
Using [AssemblyScript](https://www.assemblyscript.org/) to generate a lean WASM.
4+
5+
## Usage
6+
7+
```javascript
8+
import { nextMatch } from '@huggingface/gearhash-wasm';
9+
10+
// Create a Uint8Array of data to search through
11+
const data = new Uint8Array(1000000); // Example: 1MB of data
12+
// ... fill data with your content ...
13+
14+
// Search for a pattern with a specific mask
15+
const mask = 0x0000d90003530000n; // Example mask as a BigInt
16+
const matchResult = nextMatch(data, mask);
17+
18+
// matchIndex will be the position where the pattern was found
19+
// or -1 if no match was found
20+
```
21+
22+
The `nextMatch` function takes two parameters:
23+
- `data`: A Uint8Array containing the data to search through
24+
- `mask`: A BigInt representing the pattern mask to search for
25+
26+
The function returns an object with the `position` (i32) and `hash` (u64) properties
27+
28+
You can continuously feed data like this:
29+
30+
```javascript
31+
let hash = 0n;
32+
const mask = 0x0000d90003530000n;
33+
34+
let position = 0;
35+
for await (const chunk of dataSource) {
36+
let index = 0;
37+
while (1) {
38+
let match = nextMatch(chunk.subArray(index), mask, hash);
39+
40+
if (match.position !== -1) {
41+
console.log({
42+
position: match.position + position,
43+
hash: match.hash
44+
})
45+
46+
index += match.position;
47+
position = 0;
48+
hash = 0n;
49+
} else {
50+
position += chunk.length - index;
51+
break;
52+
}
53+
}
54+
}
55+
56+
console.log(position, "bytes without a match, ending hash: ", hash);
57+
```

packages/gearhash-wasm/assembly/next-match.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22

33
import { DEFAULT_TABLE } from "./table";
44

5+
// Interface for the match result
6+
export class MatchResult {
7+
position: i32 = -1;
8+
hash: u64 = 0;
9+
}
10+
511
// Function to find the next match in the buffer
6-
export function nextMatch(buf: Uint8Array, mask: u64, hash: u64 = 0, table: StaticArray<u64> = DEFAULT_TABLE): i32 {
12+
export function nextMatch(buf: Uint8Array, mask: u64, hash: u64 = 0): MatchResult {
713
for (let i = 0; i < buf.length; i++) {
814
const b = buf[i];
9-
hash = (hash << 1) + table[b];
15+
hash = (hash << 1) + DEFAULT_TABLE[b];
1016

1117
if ((hash & mask) == 0) {
12-
return i + 1;
18+
return { position: i + 1, hash };
1319
}
1420
}
1521

16-
return -1; // Return -1 to indicate no match found (equivalent to None in Rust)
22+
return { position: -1, hash }; // Return -1 position to indicate no match found, along with the final hash
1723
}

packages/gearhash-wasm/tests/index.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
11
import assert from "assert";
22
import { nextMatch } from "../build/debug.js";
3-
assert.strictEqual(nextMatch(new Uint8Array([1, 2, 3]), 0xaf2900n), 3);
3+
4+
// Simple seeded random number generator
5+
function seededRandom(seed) {
6+
return function () {
7+
seed = (seed * 16807) % 2147483647;
8+
return (seed - 1) / 2147483646;
9+
};
10+
}
11+
12+
// Create seeded random data
13+
const seed = 12345; // Fixed seed for deterministic results
14+
const random = seededRandom(seed);
15+
const randomData = new Uint8Array(1000000).map(() => Math.floor(random() * 256));
16+
17+
// Test with a known mask
18+
assert.deepStrictEqual(nextMatch(randomData, 0xaf2900n), { position: 128, hash: 11757411513747408525n });
19+
assert.deepStrictEqual(nextMatch(randomData.subarray(128), 0xaf2900n), { position: 184, hash: 7438883163016807155n });
420
console.log("ok");

0 commit comments

Comments
 (0)