OpenHFT / Zero-Allocation-Hashing

Zero-allocation hashing for Java
Apache License 2.0
794 stars 136 forks source link

128 bit Hash #9

Closed hasswen closed 4 years ago

hasswen commented 8 years ago

Thank you for the awesome library! Is it possible to add a 128-bit version for one of the hash functions, such as Murmur3?

leventov commented 8 years ago

The problem is that there is no 128-bit primitive type in Java. So the lib should either return something like Result object with two long fields, that directly violates "zero-allocation" promise, carried to the library name. (I still don't trust Hotspot's escape analysis much and never rely on this feature.) Or, pass additional argument (of the same Result type) to all methods, that is very cumbersome, and would probably still require the lib user to keep this Result object somewhere in ThreadLocals.

steffenyount commented 7 years ago

Two other options for returning a 128-bit xxHash result with "zero-allocation" would be:

  1. pass a functional interface argument, that would be called to set both the hi/low long values before the function returns.
  2. pass a byte[16] array argument, that would be populated before the function returns.

It would be really interesting to see if the xxHash's high performance numbers can be extended to a 128-bit hash.

leventov commented 7 years ago

@steffenyount instead of byte[] array it seems better to me to create a specialized Int128 class with two mutable long fields, because it is smaller (no need for array.length field), safer (no need to check that array length is indeed 16) and easier to extract long words from.

Do you have incentives to implement this?

gzm55 commented 4 years ago

Another interface using lambda:

long hash128(..., LongBinaryOperator readAll) {
  // computing
  // internal result in low and high

  return readAll.applyAsLong(low, high);
}

class A{
long lowHolderField, highHolderField;
void main() {
  long low = hash128(..., h -> { lowHolderField = l; highHolderField = h; return l; });
}
}

OR

long hash128(..., LongConsumer readHigh) {
  // computing
  // internal result in low and high
  if (null != readHigh) {
   readHigh.accept(high);
  }
  return low;
}

class A{
long highHolderField;
void main() {
  long low = hash128(..., h -> {highHolderField = h;});
}
}
gzm55 commented 4 years ago

instead of byte[] array it seems better to me to create a specialized Int128 class with two mutable long fields, because it is smaller (no need for array.length field)

@leventov Using jol, we can see array.length is merge into the object header, at offset 12 size 4, so long[2] and Int128 will be the same size in memory (32bytes). But still Int128 can avoid size checking.

gzm55 commented 4 years ago

@leventov #34 is a working proposal for 128 or more bit hash.