kenqtade's picture
Use ken-q org namespace for project Spaces
0865492
Raw
History Blame Contribute Delete
2.16 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.xorbHash = xorbHash;
const blake3_jit_1 = require("@huggingface/blake3-jit");
const xet_chunker_js_1 = require("./xet-chunker.js");
const MEAN_CHUNK_PER_NODE = 4;
const BLAKE3_NODE_KEY = new Uint8Array([
1, 126, 197, 199, 165, 71, 41, 150, 253, 148, 102, 102, 180, 138, 2, 230, 93, 221, 83, 111, 55, 199, 109, 210, 248,
99, 82, 230, 74, 83, 113, 63,
]);
const INDEX_OF_LAST_BYTE_OF_LAST_U64_IN_CHUNK_HASH = 3 * 8;
const nodeHasher = blake3_jit_1.Hasher.newKeyed(BLAKE3_NODE_KEY);
function xorbHash(chunks) {
if (chunks.length === 0) {
return new Uint8Array(32);
}
let currentChunks = chunks;
while (currentChunks.length > 1) {
const nodes = [];
let currentIndex = 0;
let numOfChildrenSoFar = 0;
for (let i = 0; i < currentChunks.length; i++) {
if (i === currentChunks.length - 1 ||
numOfChildrenSoFar === 2 * MEAN_CHUNK_PER_NODE ||
(numOfChildrenSoFar >= 2 &&
currentChunks[i].hash[INDEX_OF_LAST_BYTE_OF_LAST_U64_IN_CHUNK_HASH] % MEAN_CHUNK_PER_NODE === 0)) {
nodes.push(mergedHashOfSequence(currentChunks.slice(currentIndex, i + 1)));
currentIndex = i + 1;
numOfChildrenSoFar = 0;
}
else {
numOfChildrenSoFar++;
}
}
currentChunks = nodes;
}
return currentChunks[0].hash;
}
/**
* Matches Rust's `merged_hash_of_sequence`: serializes each entry as
* "{hash_hex} : {length_decimal}\n" then hashes with BLAKE3_NODE_KEY.
*/
function mergedHashOfSequence(chunks) {
let text = "";
let totalLength = 0;
for (const chunk of chunks) {
text += (0, xet_chunker_js_1.hashToHex)(chunk.hash) + " : " + chunk.length + "\n";
totalLength += chunk.length;
}
const bytes = new Uint8Array(text.length);
for (let i = 0; i < text.length; i++) {
bytes[i] = text.charCodeAt(i);
}
const hash = nodeHasher.reset().update(bytes).finalize(32);
return { hash, length: totalLength };
}