Skip to content

Commit

Permalink
Merge pull request #268 from dynatrace-oss/improvements
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
oertl committed Jul 31, 2024
2 parents ca58082 + 106a92e commit 6d02259
Show file tree
Hide file tree
Showing 9 changed files with 314 additions and 247 deletions.
117 changes: 58 additions & 59 deletions src/main/java/com/dynatrace/hash4j/hashing/AbstractFarmHash.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,11 @@ private void processBuffer() {

@Override
public final HashStream64 putByte(byte v) {
buffer[bufferCount] = v;
if (bufferCount >= 72) {
processBuffer();
bufferCount = 8;
buffer[8] = v;
}
buffer[bufferCount] = v;
bufferCount += 1;
return this;
}
Expand All @@ -294,6 +293,18 @@ public final HashStream64 putShort(short v) {
return this;
}

@Override
public final HashStream64 putChar(char v) {
setChar(buffer, bufferCount, v);
if (bufferCount >= 71) {
processBuffer();
bufferCount -= 64;
setChar(buffer, bufferCount, v);
}
bufferCount += 2;
return this;
}

@Override
public final HashStream64 putInt(int v) {
setInt(buffer, bufferCount, v);
Expand Down Expand Up @@ -370,68 +381,56 @@ public final HashStream64 putBytes(byte[] b, int off, int len) {

@Override
public final HashStream64 putChars(CharSequence s) {
if (bufferCount + s.length() * 2L < 73) {
for (int idx = 0; idx < s.length(); idx += 1) {
setChar(buffer, bufferCount + (idx << 1), s.charAt(idx));
}
bufferCount += s.length() << 1;
return this;
}
int idx = 0;
while (bufferCount < 72) {
setChar(buffer, bufferCount, s.charAt(idx));
bufferCount += 2;
idx += 1;
}
processBuffer();
int a = bufferCount & 1;
bufferCount = 8 - a;
idx -= a;
int lenMinus32 = s.length() - 32;
if (idx < lenMinus32) {
while (true) {

long b0 = getLong(s, idx);
long b1 = getLong(s, idx + 4);
long b2 = getLong(s, idx + 8);
long b3 = getLong(s, idx + 12);
long b4 = getLong(s, idx + 16);
long b5 = getLong(s, idx + 20);
long b6 = getLong(s, idx + 24);
long b7 = getLong(s, idx + 28);

if (a != 0) {
b0 = (b0 >>> 8) | (b1 << 56);
b1 = (b1 >>> 8) | (b2 << 56);
b2 = (b2 >>> 8) | (b3 << 56);
b3 = (b3 >>> 8) | (b4 << 56);
b4 = (b4 >>> 8) | (b5 << 56);
b5 = (b5 >>> 8) | (b6 << 56);
b6 = (b6 >>> 8) | (b7 << 56);
b7 = (b7 >>> 8) | ((long) s.charAt(idx + 32) << 56);
}
if (s.length() >= ((74 - bufferCount) >> 1)) {
idx = ((73 - bufferCount) >>> 1);
copyCharsToByteArray(s, 0, buffer, bufferCount, idx);
processBuffer();
int a = bufferCount & 1;
bufferCount = 8 - a;
idx -= a;
int lenMinus32 = s.length() - 32;
if (idx < lenMinus32) {
while (true) {

long b0 = getLong(s, idx);
long b1 = getLong(s, idx + 4);
long b2 = getLong(s, idx + 8);
long b3 = getLong(s, idx + 12);
long b4 = getLong(s, idx + 16);
long b5 = getLong(s, idx + 20);
long b6 = getLong(s, idx + 24);
long b7 = getLong(s, idx + 28);

if (a != 0) {
b0 = (b0 >>> 8) | (b1 << 56);
b1 = (b1 >>> 8) | (b2 << 56);
b2 = (b2 >>> 8) | (b3 << 56);
b3 = (b3 >>> 8) | (b4 << 56);
b4 = (b4 >>> 8) | (b5 << 56);
b5 = (b5 >>> 8) | (b6 << 56);
b6 = (b6 >>> 8) | (b7 << 56);
b7 = (b7 >>> 8) | ((long) s.charAt(idx + 32) << 56);
}

processBuffer(b0, b1, b2, b3, b4, b5, b6, b7);
idx += 32;
if (idx >= lenMinus32) {
setLong(buffer, 8, b0);
setLong(buffer, 16, b1);
setLong(buffer, 24, b2);
setLong(buffer, 32, b3);
setLong(buffer, 40, b4);
setLong(buffer, 48, b5);
setLong(buffer, 56, b6);
setLong(buffer, 64, b7);
break;
processBuffer(b0, b1, b2, b3, b4, b5, b6, b7);
idx += 32;
if (idx >= lenMinus32) {
setLong(buffer, 8, b0);
setLong(buffer, 16, b1);
setLong(buffer, 24, b2);
setLong(buffer, 32, b3);
setLong(buffer, 40, b4);
setLong(buffer, 48, b5);
setLong(buffer, 56, b6);
setLong(buffer, 64, b7);
break;
}
}
}
}

do {
setChar(buffer, bufferCount, s.charAt(idx));
bufferCount += 2;
idx += 1;
} while (idx < s.length());
copyCharsToByteArray(s, idx, buffer, bufferCount, s.length() - idx);
bufferCount += (s.length() - idx) << 1;
return this;
}

Expand Down
123 changes: 108 additions & 15 deletions src/main/java/com/dynatrace/hash4j/hashing/AbstractHashStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,35 @@ public HashStream putBooleans(boolean[] x) {

@Override
public HashStream putBooleans(boolean[] x, int off, int len) {
for (int i = 0; i < len; i++) {
putBoolean(x[off + i]);
int end = len + off;
while (off <= end - 8) {
long b0 = (x[off + 0] ? 1L : 0L) << (8 * 0);
long b1 = (x[off + 1] ? 1L : 0L) << (8 * 1);
long b2 = (x[off + 2] ? 1L : 0L) << (8 * 2);
long b3 = (x[off + 3] ? 1L : 0L) << (8 * 3);
long b4 = (x[off + 4] ? 1L : 0L) << (8 * 4);
long b5 = (x[off + 5] ? 1L : 0L) << (8 * 5);
long b6 = (x[off + 6] ? 1L : 0L) << (8 * 6);
long b7 = (x[off + 7] ? 1L : 0L) << (8 * 7);
putLong(b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7);
off += 8;
}
if (off <= end - 4) {
int b0 = (x[off + 0] ? 1 : 0) << (8 * 0);
int b1 = (x[off + 1] ? 1 : 0) << (8 * 1);
int b2 = (x[off + 2] ? 1 : 0) << (8 * 2);
int b3 = (x[off + 3] ? 1 : 0) << (8 * 3);
putInt(b0 | b1 | b2 | b3);
off += 4;
}
if (off <= end - 2) {
int b0 = (x[off + 0] ? 1 : 0) << (8 * 0);
int b1 = (x[off + 1] ? 1 : 0) << (8 * 1);
putChar((char) (b0 | b1));
off += 2;
}
if (off < end) {
putBoolean(x[off]);
}
return this;
}
Expand All @@ -54,8 +81,21 @@ public HashStream putBytes(byte[] b) {

@Override
public HashStream putBytes(byte[] b, int off, int len) {
for (int i = 0; i < len; i++) {
putByte(b[off + i]);
int end = len + off;
while (off <= end - 8) {
putLong(AbstractHasher.getLong(b, off));
off += 8;
}
if (off <= end - 4) {
putInt(AbstractHasher.getInt(b, off));
off += 4;
}
if (off <= end - 2) {
putChar(AbstractHasher.getChar(b, off));
off += 2;
}
if (off < end) {
putByte(b[off]);
}
return this;
}
Expand All @@ -78,17 +118,41 @@ public HashStream putChars(char[] x) {

@Override
public HashStream putChars(char[] x, int off, int len) {
for (int i = 0; i < len; i++) {
putChar(x[off + i]);
int end = len + off;
while (off <= end - 4) {
long b0 = (long) x[off + 0] << (16 * 0);
long b1 = (long) x[off + 1] << (16 * 1);
long b2 = (long) x[off + 2] << (16 * 2);
long b3 = (long) x[off + 3] << (16 * 3);
putLong(b0 | b1 | b2 | b3);
off += 4;
}
if (off <= end - 2) {
int b0 = x[off + 0] << (16 * 0);
int b1 = x[off + 1] << (16 * 1);
putInt(b0 | b1);
off += 2;
}
if (off < end) {
putChar(x[off]);
}
return this;
}

@Override
public HashStream putChars(CharSequence s) {
int len = s.length();
for (int i = 0; i < len; i++) {
putChar(s.charAt(i));
int end = s.length();
int off = 0;
while (off <= end - 4) {
putLong(AbstractHasher.getLong(s, off));
off += 4;
}
if (off <= end - 2) {
putInt(AbstractHasher.getInt(s, off));
off += 2;
}
if (off < end) {
putChar(s.charAt(off));
}
return this;
}
Expand Down Expand Up @@ -124,8 +188,23 @@ public HashStream putShorts(short[] x) {

@Override
public HashStream putShorts(short[] x, int off, int len) {
for (int i = 0; i < len; i++) {
putShort(x[off + i]);
int end = off + len;
while (off <= end - 4) {
long b0 = (x[off + 0] & 0xFFFFL) << (16 * 0);
long b1 = (x[off + 1] & 0xFFFFL) << (16 * 1);
long b2 = (x[off + 2] & 0xFFFFL) << (16 * 2);
long b3 = (x[off + 3] & 0xFFFFL) << (16 * 3);
putLong(b0 | b1 | b2 | b3);
off += 4;
}
if (off <= end - 2) {
int b0 = (x[off + 0] & 0xFFFF) << (16 * 0);
int b1 = (x[off + 1] & 0xFFFF) << (16 * 1);
putInt(b0 | b1);
off += 2;
}
if (off < end) {
putShort(x[off]);
}
return this;
}
Expand All @@ -151,8 +230,15 @@ public HashStream putInts(int[] x) {

@Override
public HashStream putInts(int[] x, int off, int len) {
for (int i = 0; i < len; i++) {
putInt(x[off + i]);
int end = off + len;
while (off <= end - 2) {
long b0 = x[off + 0] & 0xFFFFFFFFL;
long b1 = (long) x[off + 1] << 32;
putLong(b0 | b1);
off += 2;
}
if (off < end) {
putInt(x[off]);
}
return this;
}
Expand Down Expand Up @@ -195,8 +281,15 @@ public HashStream putFloats(float[] x) {

@Override
public HashStream putFloats(float[] x, int off, int len) {
for (int i = 0; i < len; ++i) {
putFloat(x[off + i]);
int end = off + len;
while (off <= end - 2) {
long b0 = Float.floatToRawIntBits(x[off + 0]) & 0xFFFFFFFFL;
long b1 = (long) Float.floatToRawIntBits(x[off + 1]) << 32;
putLong(b0 | b1);
off += 2;
}
if (off < end) {
putFloat(x[off]);
}
return this;
}
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/dynatrace/hash4j/hashing/AbstractHasher.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,32 @@ protected static int getInt(CharSequence s, int off) {
protected static void setChar(byte[] b, int off, char v) {
CHAR_HANDLE.set(b, off, v);
}

protected static void copyCharsToByteArray(
CharSequence charSequence,
int offetCharSequence,
byte[] byteArray,
int offsetByteArray,
int numChars) {
for (int charIdx = 0; charIdx <= numChars - 4; charIdx += 4) {
setLong(
byteArray,
offsetByteArray + (charIdx << 1),
getLong(charSequence, offetCharSequence + charIdx));
}
if ((numChars & 2) != 0) {
int charIdx = numChars & 0xFFFFFFFC;
setInt(
byteArray,
offsetByteArray + (charIdx << 1),
getInt(charSequence, offetCharSequence + charIdx));
}
if ((numChars & 1) != 0) {
int charIdx = numChars & 0xFFFFFFFE;
setChar(
byteArray,
offsetByteArray + (charIdx << 1),
charSequence.charAt(offetCharSequence + charIdx));
}
}
}
Loading

0 comments on commit 6d02259

Please sign in to comment.