Skip to content

Commit

Permalink
Merge pull request #200 from dynatrace-oss/errorprone
Browse files Browse the repository at this point in the history
introduced errorprone, fixed hashTestObject4 jmh benchmark
  • Loading branch information
oertl authored Dec 28, 2023
2 parents c29f726 + aa74d70 commit c747024
Show file tree
Hide file tree
Showing 40 changed files with 626 additions and 612 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ However, this algorithm can be useful for file indexes, for example, to find ide
```java
// create some file in the given path
File file = path.resolve("test.txt").toFile();
try (FileWriter fileWriter = new FileWriter(file)) {
try (FileWriter fileWriter = new FileWriter(file, StandardCharsets.UTF_8)) {
fileWriter.write("this is the file content");
}

Expand Down
10 changes: 9 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ plugins {
id 'signing'
id 'io.github.gradle-nexus.publish-plugin' version '1.3.0'
id "com.palantir.revapi" version "1.7.0"
id "net.ltgt.errorprone" version "3.1.0"
}

static def readJavaLicense(licenseName) {
Expand Down Expand Up @@ -185,6 +186,7 @@ dependencies {
testImplementation group: 'net.openhft', name: 'zero-allocation-hashing', version: '0.16'
testImplementation group: 'com.appmattus.crypto', name: 'cryptohash', version: '0.10.1'
testImplementation group: 'org.greenrobot', name: 'essentials', version: '3.1.0'
errorprone("com.google.errorprone:error_prone_core:2.24.0")
}

jacocoTestReport {
Expand Down Expand Up @@ -383,4 +385,10 @@ nexusPublishing {

if (file("extra-configuration.gradle").exists()) {
apply from: 'extra-configuration.gradle'
}
}

tasks.withType(JavaCompile).configureEach {
options.compilerArgs << "-Werror"
options.errorprone.disableWarningsInGeneratedCode = false
// options.errorprone.enabled = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void distinctCountAddWithMartingaleEstimator(AddState addState, Blackhole
blackhole.consume(martingaleEstimator.getDistinctCountEstimate());
}

@SuppressWarnings("ImmutableEnumChecker")
public enum Estimator {
MAXIMUM_LIKELIHOOD_ESTIMATOR(HyperLogLog.MAXIMUM_LIKELIHOOD_ESTIMATOR),
CORRECTED_RAW_ESTIMATOR(HyperLogLog.CORRECTED_RAW_ESTIMATOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void distinctCountAddWithMartingaleEstimator(AddState addState, Blackhole
blackhole.consume(martingaleEstimator.getDistinctCountEstimate());
}

@SuppressWarnings("ImmutableEnumChecker")
public enum Estimator {
MAXIMUM_LIKELIHOOD_ESTIMATOR(UltraLogLog.MAXIMUM_LIKELIHOOD_ESTIMATOR),
OPTIMAL_FGRA_ESTIMATOR(UltraLogLog.OPTIMAL_FGRA_ESTIMATOR);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Dynatrace LLC
* Copyright 2022-2023 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -281,8 +281,7 @@ private static String createRandomString(int minLen, int maxLen, SplittableRando
int len = random.nextInt(minLen, maxLen + 1);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; ++i) {
char c = 'a';
c += random.nextInt(0, 26);
char c = (char) ('a' + random.nextInt(0, 26));
sb.append(c);
}
return sb.toString();
Expand All @@ -292,9 +291,8 @@ private static String createRandomGreekString(int minLen, int maxLen, Splittable
int len = random.nextInt(minLen, maxLen + 1);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; ++i) {
char c = 0x03B1;
c += random.nextInt(0, 24);
if (c >= 0x03C2) c += 1;
char c = (char) (0x03B1 + random.nextInt(0, 24));
if (c >= 0x03C2) c = (char) (c + 1);
sb.append(c);
}
return sb.toString();
Expand All @@ -311,8 +309,6 @@ private static TestObject[] createTestObjects(
}

static {
final SplittableRandom random = new SplittableRandom(0);

BYTE_ARRAYS_1 = createRandomByteArrays(NUM_OBJECTS, 1, 1, 0x035348bcb49493a4L);
BYTE_ARRAYS_4 = createRandomByteArrays(NUM_OBJECTS, 1, 4, 0xcc6444ca02edfbd0L);
BYTE_ARRAYS_16 = createRandomByteArrays(NUM_OBJECTS, 1, 16, 0x187c616cabc3e0a7L);
Expand Down Expand Up @@ -346,7 +342,7 @@ private static TestObject[] createTestObjects(
TEST_OBJECTS1 = createTestObjects(NUM_OBJECTS, TestObject1::new, 0x37569b3107539e19L);
TEST_OBJECTS2 = createTestObjects(NUM_OBJECTS, TestObject2::new, 0x892da841ae127839L);
TEST_OBJECTS3 = createTestObjects(NUM_OBJECTS, TestObject3::new, 0xb443e2873a03f397L);
TEST_OBJECTS4 = createTestObjects(NUM_OBJECTS, TestObject3::new, 0x49952ea071f1cc0aL);
TEST_OBJECTS4 = createTestObjects(NUM_OBJECTS, TestObject4::new, 0x49952ea071f1cc0aL);
}

private void directBytesTest(byte[][] data, Blackhole blackhole) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Dynatrace LLC
* Copyright 2022-2023 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -45,6 +45,7 @@ protected long hashCharsIndirect(String s) {

protected abstract LongHashFunction createHashFunction();

@Override
protected long hashObject(TestObject testObject) {
try {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
Expand Down
12 changes: 7 additions & 5 deletions src/jmh/java/com/dynatrace/hash4j/hashing/UnorderedHashTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Dynatrace LLC
* Copyright 2022-2023 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,7 +19,6 @@
import java.util.List;
import java.util.SplittableRandom;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.ToLongFunction;
import java.util.stream.Collectors;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
Expand All @@ -40,10 +39,13 @@ public class UnorderedHashTest {
}

private static final HashFunnel<Long> LONG_FUNNEL = (l, h) -> h.putLong(l);
private static final ToLongFunction<Long> LONG_2_HASH =
x -> Hashing.murmur3_128().hashToLong(x, LONG_FUNNEL);

private static final long long2Hash(long x) {
return Hashing.murmur3_128().hashToLong(x, LONG_FUNNEL);
}

private static final HashFunnel<List<Long>> LIST_LONG_FUNNEL =
(l, h) -> h.putUnorderedIterable(l, LONG_2_HASH);
(l, h) -> h.putUnorderedIterable(l, UnorderedHashTest::long2Hash);

@Benchmark
@BenchmarkMode(Mode.AverageTime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ public static int computeToken(long hashValue) {
*/
@Override
public HyperLogLog add(long hashValue, StateChangeObserver stateChangeObserver) {
int idx = (int) (hashValue >>> (-p));
int idx = (int) (hashValue >>> -p);
int newValue = Long.numberOfLeadingZeros(~(~hashValue << p)) + 1;
int oldValue = (int) ARRAY_HANDLER.update(state, idx, newValue, Math::max);
if (stateChangeObserver != null && newValue > oldValue) {
Expand Down Expand Up @@ -601,7 +601,7 @@ private static final class MaximumLikelihoodEstimator implements Estimator {
//
// for a numerical evaluation see
// https://www.wolframalpha.com/input?i=sqrt%28ln%282%29%2Fzeta%282%2C2%29%29
private static final double INV_SQRT_FISHER_INFORMATION = 1.0367047097785011;
private static final double INV_SQRT_FISHER_INFORMATION = 1.0367047097785012;
private static final double ML_EQUATION_SOLVER_EPS =
0.001 * INV_SQRT_FISHER_INFORMATION; // 0.1% of theoretical relative error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ public static int computeToken(long hashValue) {
public UltraLogLog add(long hashValue, StateChangeObserver stateChangeObserver) {
int q = Long.numberOfLeadingZeros(state.length - 1L); // q = 64 - p
int idx = (int) (hashValue >>> q);
int nlz = Long.numberOfLeadingZeros(~(~hashValue << (-q))); // nlz in {0, 1, ..., 64-p}
int nlz = Long.numberOfLeadingZeros(~(~hashValue << -q)); // nlz in {0, 1, ..., 64-p}
byte oldState = state[idx];
long hashPrefix = unpack(oldState);
hashPrefix |= 1L << (nlz + (~q)); // (nlz + (~q)) = (nlz + p - 1) in {p-1, ... 63}
hashPrefix |= 1L << (nlz + ~q); // (nlz + (~q)) = (nlz + p - 1) in {p-1, ... 63}
byte newState = pack(hashPrefix);
state[idx] = newState;
if (stateChangeObserver != null && newState != oldState) {
Expand Down Expand Up @@ -323,7 +323,7 @@ static long unpack(byte register) {
// visible for testing
static byte pack(long hashPrefix) {
int nlz = Long.numberOfLeadingZeros(hashPrefix) + 1;
return (byte) (((-nlz) << 2) | ((hashPrefix << nlz) >>> 62));
return (byte) ((-nlz << 2) | ((hashPrefix << nlz) >>> 62));
}

/**
Expand Down Expand Up @@ -410,7 +410,7 @@ private static final class MaximumLikelihoodEstimator implements Estimator {
//
// for a numerical evaluation see
// https://www.wolframalpha.com/input?i=3%2F2+*+ln%282%29+*+zeta%283%2C5%2F4%29%2F%28zeta%282%2C5%2F4%29%29%5E2
private static final double ML_BIAS_CORRECTION_CONSTANT = 0.48147376527720066;
private static final double ML_BIAS_CORRECTION_CONSTANT = 0.48147376527720065;

// returns contribution to alpha, scaled by 2^64
private static long contribute(int r, int[] b, int p) {
Expand Down Expand Up @@ -772,7 +772,7 @@ static double smallRangeEstimate(long c0, long c4, long c8, long c10, long m) {
long alpha = m + 3 * (c0 + c4 + c8 + c10);
long beta = m - c0 - c4;
long gamma = 4 * c0 + 2 * c4 + 3 * c8 + c10;
double quadRootZ = (sqrt(beta * beta + 4 * alpha * gamma) - beta) / (2 * alpha);
double quadRootZ = (sqrt((double) (beta * beta + 4 * alpha * gamma)) - beta) / (2 * alpha);
double rootZ = quadRootZ * quadRootZ;
return rootZ * rootZ;
}
Expand All @@ -781,7 +781,7 @@ static double largeRangeEstimate(long c4w0, long c4w1, long c4w2, long c4w3, lon
long alpha = m + 3 * (c4w0 + c4w1 + c4w2 + c4w3);
long beta = c4w0 + c4w1 + 2 * (c4w2 + c4w3);
long gamma = m + 2 * c4w0 + c4w2 - c4w3;
return sqrt((sqrt(beta * beta + 4 * alpha * gamma) - beta) / (2 * alpha));
return sqrt((sqrt((double) (beta * beta + 4 * alpha * gamma)) - beta) / (2 * alpha));
}

// this is psi as defined in the paper divided by ETA_X
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public HashStream putInts(int[] x, int off, int len) {

@Override
public HashStream putLong(long v) {
putInt((int) (v));
putInt((int) v);
putInt((int) (v >> 32));
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public HashStream64 putChars(CharSequence s) {
remainingChars -= 32;
off += 32;
} while (remainingChars >= 32);
buffer[0] = (byte) (z);
buffer[0] = (byte) z;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ protected static long[] makeSecret(long seed) {
ok = true;
seed += 0xa0761d6478bd642fL;
secret[i] =
(c[(int) (Long.remainderUnsigned(wymix(seed, seed ^ 0xe7037ed1a0b428dbL), c.length))]
(c[(int) Long.remainderUnsigned(wymix(seed, seed ^ 0xe7037ed1a0b428dbL), c.length)]
& 0xFFL);
if ((secret[i] & 1) == 0) {
seed += 0x633acdbf4d2dbd49L; // = 7 * 0xa0761d6478bd642fL
Expand All @@ -232,7 +232,7 @@ protected static long[] makeSecret(long seed) {
for (int j = 8; j < 64; j += 8) {
seed += 0xa0761d6478bd642fL;
secret[i] |=
(c[(int) (Long.remainderUnsigned(wymix(seed, seed ^ 0xe7037ed1a0b428dbL), c.length))]
(c[(int) Long.remainderUnsigned(wymix(seed, seed ^ 0xe7037ed1a0b428dbL), c.length)]
& 0xFFL)
<< j;
}
Expand Down Expand Up @@ -438,7 +438,7 @@ public HashStream64 putChars(CharSequence s) {
setLong(buffer, 32, b4);
setLong(buffer, 40, b5);
}
buffer[0] = (byte) (z);
buffer[0] = (byte) z;
}
}
while (remainingChars >= 4) {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/dynatrace/hash4j/hashing/FarmHashNa.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,9 @@ class FarmHashNa extends AbstractHasher64 {
private static final long K1 = 0xb492b66fbe98f273L;
protected static final long K2 = 0x9ae16a3b2f90404fL;
private static final long K_MUL = 0x9ddfea08eb382d69L;
private static final long SEED = 81;
private static final long START_X = SEED * K2;
private static final long START_Y = SEED * K1 + 113;
private static final long START_Z = shiftMix(START_Y * K2 + 113) * K2;
private static final long START_X = 0x1529cba0ca458ffL;
private static final long START_Y = 0x226bb95b4e64b6d4L;
private static final long START_Z = 0x134a747f856d0526L;

private static final FarmHashNa INSTANCE = new FarmHashNa();

Expand Down Expand Up @@ -733,6 +732,7 @@ private long naHashLen33To64(int bufferCount) {
rotateRight(e + f, 43) + rotateRight(g, 30) + h, e + rotateRight(f + a, 18) + g, mul);
}

@Override
public long getAsLong() {
return finalizeHash(processRemaining());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Dynatrace LLC
* Copyright 2022-2023 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -171,5 +171,6 @@ <T> HashStream128 putUnorderedIterable(
*
* @return this
*/
@Override
HashStream128 reset();
}
3 changes: 2 additions & 1 deletion src/main/java/com/dynatrace/hash4j/hashing/HashStream64.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Dynatrace LLC
* Copyright 2022-2023 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -171,5 +171,6 @@ <T> HashStream64 putUnorderedIterable(
*
* @return this
*/
@Override
HashStream64 reset();
}
4 changes: 2 additions & 2 deletions src/main/java/com/dynatrace/hash4j/hashing/Komihash4_3.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public long hashBytesToLong(byte[] input, int off, int len) {
} else if (len > 3) {
long fb = getInt(input, off) & 0xFFFFFFFFL;
long y = getInt(input, off + len - 4);
fb |= (y << 32) >>> (-ml8);
fb |= (y << 32) >>> -ml8;
fb |= 1L << ml8 << (y >>> 63);
r2l ^= fb;
} else if (len > 0) {
Expand Down Expand Up @@ -267,7 +267,7 @@ public long hashCharsToLong(CharSequence input) {
} else if (len > 1) {
long fb = getInt(input, off) & 0xFFFFFFFFL;
long y = getInt(input, off + len - 2);
fb |= (y << 32) >>> (-ml8);
fb |= (y << 32) >>> -ml8;
fb |= 1L << ml8 << (y >>> 63);
r2l ^= fb;
} else if (len > 0) {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/dynatrace/hash4j/hashing/Komihash5_0.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ public long hashBytesToLong(byte[] input, int off, int len) {
if (len > 7) {
r2l ^= getLong(input, off);
long y = getLong(input, off + len - 8);
r2h ^= (1L << ml8) | (y >>> 1 >>> (~ml8));
r2h ^= (1L << ml8) | (y >>> 1 >>> ~ml8);
} else if (len > 3) {
long mh = getInt(input, off + len - 4);
long ml = getInt(input, off) & 0xFFFFFFFFL;
r2l ^= (1L << ml8) | ml | (mh << 32 >>> (-ml8));
r2l ^= (1L << ml8) | ml | (mh << 32 >>> -ml8);
} else if (len > 0) {
long m = (1L << ml8) | (input[off] & 0xFFL);
if (len > 1) m |= (input[off + 1] & 0xFFL) << 8;
Expand Down Expand Up @@ -256,11 +256,11 @@ public long hashCharsToLong(CharSequence input) {
if (len > 3) {
r2l ^= getLong(input, off);
long y = getLong(input, off + len - 4);
r2h ^= (1L << ml8) | (y >>> 1 >>> (~ml8));
r2h ^= (1L << ml8) | (y >>> 1 >>> ~ml8);
} else if (len > 1) {
long mh = getInt(input, off + len - 2);
long ml = getInt(input, off) & 0xFFFFFFFFL;
r2l ^= (1L << ml8) | ml | (mh << 32 >>> (-ml8));
r2l ^= (1L << ml8) | ml | (mh << 32 >>> -ml8);
} else if (len > 0) {
long m = (1L << ml8) | input.charAt(off);
r2l ^= m;
Expand Down
Loading

0 comments on commit c747024

Please sign in to comment.