Spaces:
Sleeping
Sleeping
| ; | |
| 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 }; | |
| } | |