export function x64hash128()

in javascript/packages/fury/lib/murmurHash3.ts [181:289]


export function x64hash128(
  buf: Uint8Array = new Uint8Array(0),
  state: u32 = 0x0,
): DataView {
  let h1: u64;
  let h2: u64;
  let i: number;
  let len: number;
  if (typeof state === 'number') {
    h1 = [0x0, state];
    h2 = [0x0, state];
    i = 0;
    len = 0;
  } else {
    ({ h1, h2, len } = state as x64hash128State);
    const rem = (state as x64hash128State).rem;
    
    if (rem.byteLength === 0) {
      i = 0;
    } else if (rem.byteLength + buf.byteLength >= 16) {
      len += 16;
      i = 16 - rem.byteLength;
      
      const blk = new Uint8Array(16);
      const dtv = new DataView(blk.buffer);
      blk.set(rem);
      blk.set(buf.subarray(0, i), rem.byteLength);
      
      [h1, h2] = x64mix128(
        h1, h2,
        [dtv.getUint32(4, true), dtv.getUint32(0, true)],
        [dtv.getUint32(12, true), dtv.getUint32(8, true)],
      );
    } else {
      const newBuf = new Uint8Array(buf.byteLength + rem.byteLength);
      newBuf.set(rem);
      newBuf.set(buf, rem.byteLength);
      buf = newBuf;
      i = 0;
    }
  }
  
  const dtv = new DataView(buf.buffer, buf.byteOffset);
  const remainder = (buf.byteLength - i) % 16;
  const bytes = buf.byteLength - i - remainder;
  len += bytes;
  
  for (; i < bytes; i += 16) {
    [h1, h2] = x64mix128(
      h1, h2,
      [dtv.getUint32(i + 4, true), dtv.getUint32(i, true)],
      [dtv.getUint32(i + 12, true), dtv.getUint32(i + 8, true)],
    );
  }
  
  {
    len += remainder;
    let k1: u64 = [0x0, 0x0];
    let k2: u64 = [0x0, 0x0];
    
    switch (remainder) {
      case 15: k2 = xor64(k2, shl64([0x0, buf[i + 14]], 48));
      case 14: k2 = xor64(k2, shl64([0x0, buf[i + 13]], 40));
      case 13: k2 = xor64(k2, shl64([0x0, buf[i + 12]], 32));
      case 12: k2 = xor64(k2, shl64([0x0, buf[i + 11]], 24));
      case 11: k2 = xor64(k2, shl64([0x0, buf[i + 10]], 16));
      case 10: k2 = xor64(k2, shl64([0x0, buf[i + 9]], 8));
      case 9:
        k2 = xor64(k2, [0x0, buf[i + 8]]);
        k2 = mul64(k2, x64hash128c2);
        k2 = rol64(k2, 33);
        k2 = mul64(k2, x64hash128c1);
        h2 = xor64(h2, k2);
      case 8: k1 = xor64(k1, shl64([0x0, buf[i + 7]], 56));
      case 7: k1 = xor64(k1, shl64([0x0, buf[i + 6]], 48));
      case 6: k1 = xor64(k1, shl64([0x0, buf[i + 5]], 40));
      case 5: k1 = xor64(k1, shl64([0x0, buf[i + 4]], 32));
      case 4: k1 = xor64(k1, shl64([0x0, buf[i + 3]], 24));
      case 3: k1 = xor64(k1, shl64([0x0, buf[i + 2]], 16));
      case 2: k1 = xor64(k1, shl64([0x0, buf[i + 1]], 8));
      case 1:
        k1 = xor64(k1, [0x0, buf[i]]);
        k1 = mul64(k1, x64hash128c1);
        k1 = rol64(k1, 31);
        k1 = mul64(k1, x64hash128c2);
        h1 = xor64(h1, k1);
    }
    
    h1 = xor64(h1, [0x0, len & 0xffffffff]);
    h2 = xor64(h2, [0x0, len & 0xffffffff]);
    
    h1 = add64(h1, h2);
    h2 = add64(h2, h1);
    
    h1 = x64fmix64(h1);
    h2 = x64fmix64(h2);
    
    h1 = add64(h1, h2);
    h2 = add64(h2, h1);
    
    const hash = new DataView(new ArrayBuffer(16));
    hash.setUint32(0, h1[0], false);
    hash.setUint32(4, h1[1], false);
    hash.setUint32(8, h2[0], false);
    hash.setUint32(12, h2[1], false);
    
    return hash;
  }
}