| 179 | |
| 180 | |
| 181 | export function x64hash128( |
| 182 | buf: Uint8Array = new Uint8Array(0), |
| 183 | state: u32 = 0x0, |
| 184 | ): DataView { |
| 185 | let h1: u64; |
| 186 | let h2: u64; |
| 187 | let i: number; |
| 188 | let len: number; |
| 189 | if (typeof state === 'number') { |
| 190 | h1 = [0x0, state]; |
| 191 | h2 = [0x0, state]; |
| 192 | i = 0; |
| 193 | len = 0; |
| 194 | } else { |
| 195 | ({ h1, h2, len } = state as x64hash128State); |
| 196 | const rem = (state as x64hash128State).rem; |
| 197 | |
| 198 | if (rem.byteLength === 0) { |
| 199 | i = 0; |
| 200 | } else if (rem.byteLength + buf.byteLength >= 16) { |
| 201 | len += 16; |
| 202 | i = 16 - rem.byteLength; |
| 203 | |
| 204 | const blk = new Uint8Array(16); |
| 205 | const dtv = new DataView(blk.buffer); |
| 206 | blk.set(rem); |
| 207 | blk.set(buf.subarray(0, i), rem.byteLength); |
| 208 | |
| 209 | [h1, h2] = x64mix128( |
| 210 | h1, h2, |
| 211 | [dtv.getUint32(4, true), dtv.getUint32(0, true)], |
| 212 | [dtv.getUint32(12, true), dtv.getUint32(8, true)], |
| 213 | ); |
| 214 | } else { |
| 215 | const newBuf = new Uint8Array(buf.byteLength + rem.byteLength); |
| 216 | newBuf.set(rem); |
| 217 | newBuf.set(buf, rem.byteLength); |
| 218 | buf = newBuf; |
| 219 | i = 0; |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | const dtv = new DataView(buf.buffer, buf.byteOffset); |
| 224 | const remainder = (buf.byteLength - i) % 16; |
| 225 | const bytes = buf.byteLength - i - remainder; |
| 226 | len += bytes; |
| 227 | |
| 228 | for (; i < bytes; i += 16) { |
| 229 | [h1, h2] = x64mix128( |
| 230 | h1, h2, |
| 231 | [dtv.getUint32(i + 4, true), dtv.getUint32(i, true)], |
| 232 | [dtv.getUint32(i + 12, true), dtv.getUint32(i + 8, true)], |
| 233 | ); |
| 234 | } |
| 235 | |
| 236 | { |
| 237 | len += remainder; |
| 238 | let k1: u64 = [0x0, 0x0]; |