code: public void update(long a0, long a1, long a2, long a3) {
      if (done) {
        throw new IllegalStateException("Can compute a hash only once per instance");
      }
      v1[0] += mul0[0] + a0;
      v1[1] += mul0[1] + a1;
      v1[2] += mul0[2] + a2;
      v1[3] += mul0[3] + a3;
      for (int i = 0; i < 4; ++i) {
        mul0[i] ^= (v1[i] & 0xffffffffL) * (v0[i] >>> 32);
        v0[i] += mul1[i];
        mul1[i] ^= (v0[i] & 0xffffffffL) * (v1[i] >>> 32);
      }
      v0[0] += zipperMerge0(v1[1], v1[0]);
      v0[1] += zipperMerge1(v1[1], v1[0]);
      v0[2] += zipperMerge0(v1[3], v1[2]);
      v0[3] += zipperMerge1(v1[3], v1[2]);
      v1[0] += zipperMerge0(v0[1], v0[0]);
      v1[1] += zipperMerge1(v0[1], v0[0]);
      v1[2] += zipperMerge0(v0[3], v0[2]);
      v1[3] += zipperMerge1(v0[3], v0[2]);
    }
docs: Updates the hash with 32 bytes of data given as 4 longs. This function is
  more efficient than updatePacket when you can use it.
  @param a0 first 8 bytes in little endian 64-bit long
  @param a1 next 8 bytes in little endian 64-bit long
  @param a2 next 8 bytes in little endian 64-bit long
  @param a3 last 8 bytes in little endian 64-bit long