Skip to content

Commit

Permalink
Merge pull request #134 from Coollector/polymurhash
Browse files Browse the repository at this point in the history
Polymurhash optimized
  • Loading branch information
oertl authored Jul 18, 2023
2 parents b75a069 + ac15760 commit ba35393
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 6 deletions.
186 changes: 182 additions & 4 deletions src/main/java/com/dynatrace/hash4j/hashing/PolymurHash2_0.java
Original file line number Diff line number Diff line change
Expand Up @@ -429,14 +429,160 @@ public HashStream64 putLong(long v) {

@Override
public HashStream64 putBytes(byte[] b, int off, int len) {
// TODO more efficient implementation
return super.putBytes(b, off, len);
if (len == 0) {
return this;
}

byteCount += len;

if (len + offset > 49) {

if (offset != 0) {
int x = 49 - offset;
System.arraycopy(b, off, buffer, offset, x);
processBuffer();
len -= x;
off += x;
offset = 0;
}

while (len > 49) {
processBuffer(b, off);

len -= 49;
off += 49;
}
}

System.arraycopy(b, off, buffer, offset, len);
offset += len;

return this;
}

@Override
public HashStream64 putChars(CharSequence s) {
// TODO more efficient implementation
return super.putChars(s);
int len = s.length();

if (len == 0) {
return this;
}

int off = 0;
byteCount += len * 2L;

if (len * 2 + offset > 98) {
if (offset != 0) {
int left = (50 - offset) / 2;
len -= left;
off += left;

if (offset % 2 == 0) {
int temp = Math.min(len, 24);

len -= temp;
off += temp;

for (int i = 0; i <= left - 4; i += 4) {
setLong(buffer, offset + i * 2, getLong(s, i));
}

if ((left & 3) > 0) {
setChar(buffer, 48, s.charAt(left - 1));
if ((left & 3) > 1) {
setChar(buffer, 46, s.charAt(left - 2));
if ((left & 3) > 2) {
setChar(buffer, 44, s.charAt(left - 3));
}
}
}

processBuffer();
buffer[0] = buffer[49];

for (int i = 0; i < 24; i += 4) {
setLong(buffer, 1 + i * 2, getLong(s, left + i));
}

} else {
for (int i = 0; i <= left - 4; i += 4) {
setLong(buffer, offset + i * 2, getLong(s, i));
}

if ((left & 3) > 0) {
setChar(buffer, 47, s.charAt(left - 1));
if ((left & 3) > 1) {
setChar(buffer, 45, s.charAt(left - 2));
if ((left & 3) > 2) {
setChar(buffer, 43, s.charAt(left - 3));
}
}
}
}

processBuffer();

offset = 0;
}

if (len >= 49) {
for (int i = 0; i < 24; i += 4) {
setLong(buffer, i * 2, getLong(s, off + i));
}
setChar(buffer, 48, s.charAt(off + 24));

processBuffer();
buffer[0] = buffer[49];

for (int i = 0; i < 24; i += 4) {
setLong(buffer, 1 + i * 2, getLong(s, 25 + off + i));
}

len -= 49;
off += 49;

while (len > 49) {
processBuffer();
for (int i = 0; i < 24; i += 4) {
setLong(buffer, i * 2, getLong(s, off + i));
}
setChar(buffer, 48, s.charAt(off + 24));

processBuffer();
buffer[0] = buffer[49];

for (int i = 0; i < 24; i += 4) {
setLong(buffer, 1 + i * 2, getLong(s, 25 + off + i));
}

len -= 49;
off += 49;
}
offset = 49;
}
}

while (len > 0) {
len--;

setChar(buffer, offset, s.charAt(off));
off++;

offset += 2;

if (offset == 51) {
processBuffer();
buffer[0] = buffer[49];
buffer[1] = buffer[50];
offset = 2;
} else if (offset == 50) {
processBuffer();
buffer[0] = buffer[49];
offset = 1;
}
}

return this;
}

private void processBuffer() {
Expand Down Expand Up @@ -467,6 +613,38 @@ private void processBuffer() {
h = polymurRed611(t0Hi, t0Lo);
}

/*
* steps over the System.arraycopy() step (time optimization)
* do only call if offset == 0
*/
private void processBuffer(byte[] directProcess, int off) {

long m0 = (getLong(directProcess, off) & 0x00ffffffffffffffL) + k;
long m1 = (getLong(directProcess, off + 7) & 0x00ffffffffffffffL) + k6;
long m2 = (getLong(directProcess, off + 14) & 0x00ffffffffffffffL) + k2;
long m3 = (getLong(directProcess, off + 21) & 0x00ffffffffffffffL) + k5;
long m4 = (getLong(directProcess, off + 28) & 0x00ffffffffffffffL) + k3x;
long m5 = (getLong(directProcess, off + 35) & 0x00ffffffffffffffL) + k4x;
long m6 = (getLong(directProcess, off + 41) >>> 8) + h;

long t0Hi = unsignedMultiplyHigh(m0, m1);
long t0Lo = m0 * m1;
long t1Hi = unsignedMultiplyHigh(m2, m3);
long t1Lo = m2 * m3 + 0x8000000000000000L;
long t2Hi = unsignedMultiplyHigh(m4, m5);
long t2Lo = m4 * m5;
long t3Hi = unsignedMultiplyHigh(m6, k7);
long t3Lo = m6 * k7 + 0x8000000000000000L;

t0Lo += t1Lo;
t0Hi += t1Hi + ((t0Lo < t1Lo) ? 1 : 0);
t2Lo += t3Lo;
t2Hi += t3Hi + ((t2Lo < t3Lo) ? 1 : 0);
t0Lo += t2Lo;
t0Hi += t2Hi + ((t0Lo + 0x8000000000000000L < t2Lo) ? 1 : 0);
h = polymurRed611(t0Hi, t0Lo);
}

private long finish() {
long polyAcc = tweak;
if (byteCount >= 8) {
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/com/dynatrace/hash4j/hashing/package-info.java

This file was deleted.

0 comments on commit ba35393

Please sign in to comment.