|
1 | | -import { nextMatch } from "../build/debug.js"; |
| 1 | +import { nextMatch, nextMatches } from "../build/debug.js"; |
2 | 2 |
|
3 | | -// Simple deterministic RNG for reproducible results (same as Rust version) |
| 3 | +// Simple deterministic RNG for reproducible results (32-bit version) |
4 | 4 | class SimpleRng { |
5 | 5 | constructor(seed) { |
6 | | - this.state = BigInt(seed); |
| 6 | + this.state = seed; |
7 | 7 | } |
8 | 8 |
|
9 | | - nextU64() { |
10 | | - // Simple xorshift algorithm (same as Rust version) |
11 | | - this.state ^= this.state << 13n; |
12 | | - this.state ^= this.state >> 7n; |
13 | | - this.state ^= this.state << 17n; |
| 9 | + nextU32() { |
| 10 | + // Simple 32-bit xorshift algorithm (same as Rust version) |
| 11 | + this.state ^= this.state << 13; |
| 12 | + this.state ^= this.state >> 17; |
| 13 | + this.state ^= this.state << 5; |
14 | 14 | return this.state; |
15 | 15 | } |
16 | 16 |
|
| 17 | + nextU64() { |
| 18 | + // Generate two 32-bit values and combine them |
| 19 | + const low = this.nextU32(); |
| 20 | + const high = this.nextU32(); |
| 21 | + return (BigInt(high) << 32n) | BigInt(low); |
| 22 | + } |
| 23 | + |
17 | 24 | fillBytes(dest) { |
18 | 25 | for (let i = 0; i < dest.length; i += 8) { |
19 | 26 | const value = this.nextU64(); |
@@ -50,38 +57,20 @@ function testGearhash() { |
50 | 57 | console.log("Chunk | Offset | Size | Hash"); |
51 | 58 | console.log("------|--------|------|------------------"); |
52 | 59 |
|
53 | | - while (offset < inputBuf.length) { |
54 | | - const chunkStart = offset; |
55 | | - |
56 | | - const result = nextMatch(inputBuf.subarray(offset), BENCH_MASK, hash); |
57 | | - if (result.matchSize > 0) { |
58 | | - offset += result.matchSize; |
59 | | - totalProcessed += result.matchSize; |
60 | | - chunkCount += 1; |
61 | | - hash = result.hash; |
| 60 | + const result = nextMatches(inputBuf, BENCH_MASK, 0); |
| 61 | + const matches = [...result.matches, { position: result.remaining, hash: result.hash }]; |
62 | 62 |
|
63 | | - console.log( |
64 | | - `${chunkCount.toString().padStart(5)} | ${chunkStart.toString().padStart(6)} | ${result.matchSize |
65 | | - .toString() |
66 | | - .padStart(4)} | 0x${hash.toString(16).padStart(16, "0")}` |
67 | | - ); |
68 | | - } else { |
69 | | - // No more matches, process remaining bytes |
70 | | - const remaining = inputBuf.length - offset; |
71 | | - // Update hash for remaining bytes |
72 | | - for (let i = 0; i < remaining; i++) { |
73 | | - hash = ((hash << 1n) + BigInt(inputBuf[offset + i])) & 0xffffffffffffffffn; |
74 | | - } |
75 | | - totalProcessed += remaining; |
76 | | - chunkCount += 1; |
| 63 | + for (const match of matches) { |
| 64 | + offset += match.position; |
| 65 | + totalProcessed += match.position; |
| 66 | + chunkCount += 1; |
| 67 | + hash = match.hash; |
77 | 68 |
|
78 | | - console.log( |
79 | | - `${chunkCount.toString().padStart(5)} | ${offset.toString().padStart(6)} | ${remaining |
80 | | - .toString() |
81 | | - .padStart(4)} | 0x${hash.toString(16).padStart(16, "0")} (final)` |
82 | | - ); |
83 | | - break; |
84 | | - } |
| 69 | + console.log( |
| 70 | + `${chunkCount.toString().padStart(5)} | ${offset.toString().padStart(6)} | ${match.position |
| 71 | + .toString() |
| 72 | + .padStart(4)} | 0x${match.hash.toString(16).padStart(16, "0")}` |
| 73 | + ); |
85 | 74 | } |
86 | 75 |
|
87 | 76 | console.log("\nSummary:"); |
|
0 commit comments