From 072c323e05b37c644009c0e2fc5bef611338ed02 Mon Sep 17 00:00:00 2001 From: Otmar Ertl Date: Wed, 30 Aug 2023 15:15:45 +0200 Subject: [PATCH] align naming with paper --- .../hash4j/distinctcount/UltraLogLog.java | 12 +-- .../hash4j/distinctcount/UltraLogLogTest.java | 84 +++++++++---------- 2 files changed, 46 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/dynatrace/hash4j/distinctcount/UltraLogLog.java b/src/main/java/com/dynatrace/hash4j/distinctcount/UltraLogLog.java index 71427b6e..76f29583 100644 --- a/src/main/java/com/dynatrace/hash4j/distinctcount/UltraLogLog.java +++ b/src/main/java/com/dynatrace/hash4j/distinctcount/UltraLogLog.java @@ -308,9 +308,9 @@ public UltraLogLog add(long hashValue, StateChangeObserver stateChangeObserver) int idx = (int) (hashValue >>> q); int nlz = Long.numberOfLeadingZeros(~(~hashValue << (-q))); // nlz in {0, 1, ..., 64-p} byte oldState = state[idx]; - long hashPrefix = registerToHashPrefix(oldState); + long hashPrefix = unpack(oldState); hashPrefix |= 1L << (nlz + (~q)); // (nlz + (~q)) = (nlz + p - 1) in {p-1, ... 63} - byte newState = hashPrefixToRegister(hashPrefix); + byte newState = pack(hashPrefix); state[idx] = newState; if (stateChangeObserver != null && newState != oldState) { int p = 64 - q; @@ -359,7 +359,7 @@ public UltraLogLog add(UltraLogLog other) { final int deltaP = otherP - p; int j = 0; for (int i = 0; i < state.length; ++i) { - long hashPrefix = registerToHashPrefix(state[i]) | registerToHashPrefix(otherData[j]); + long hashPrefix = unpack(state[i]) | unpack(otherData[j]); j += 1; for (long k = 1; k < 1L << deltaP; ++k) { if (otherData[j] != 0) { @@ -368,19 +368,19 @@ public UltraLogLog add(UltraLogLog other) { j += 1; } if (hashPrefix != 0) { - state[i] = hashPrefixToRegister(hashPrefix); + state[i] = pack(hashPrefix); } } return this; } // visible for testing - static long registerToHashPrefix(byte register) { + static long unpack(byte register) { return (4L | (register & 3)) << ((register >>> 2) - 2); } // visible for testing - static byte hashPrefixToRegister(long hashPrefix) { + static byte pack(long hashPrefix) { int nlz = Long.numberOfLeadingZeros(hashPrefix) + 1; return (byte) (((-nlz) << 2) | ((hashPrefix << nlz) >>> 62)); } diff --git a/src/test/java/com/dynatrace/hash4j/distinctcount/UltraLogLogTest.java b/src/test/java/com/dynatrace/hash4j/distinctcount/UltraLogLogTest.java index 13640fbe..b80a3318 100644 --- a/src/test/java/com/dynatrace/hash4j/distinctcount/UltraLogLogTest.java +++ b/src/test/java/com/dynatrace/hash4j/distinctcount/UltraLogLogTest.java @@ -77,47 +77,43 @@ void testRelativeStandardErrorOfOptimalFGRAEstimatorAgainstConstants() { } @Test - void testPrefixConversion() { - assertThat(UltraLogLog.hashPrefixToRegister(0x4L)).isEqualTo((byte) 8); - assertThat(UltraLogLog.hashPrefixToRegister(0x5L)).isEqualTo((byte) 9); - assertThat(UltraLogLog.hashPrefixToRegister(0x6L)).isEqualTo((byte) 10); - assertThat(UltraLogLog.hashPrefixToRegister(0x7L)).isEqualTo((byte) 11); - assertThat(UltraLogLog.hashPrefixToRegister(0x8L)).isEqualTo((byte) 12); - assertThat(UltraLogLog.hashPrefixToRegister(0x9L)).isEqualTo((byte) 12); - assertThat(UltraLogLog.hashPrefixToRegister(0xAL)).isEqualTo((byte) 13); - assertThat(UltraLogLog.hashPrefixToRegister(0xBL)).isEqualTo((byte) 13); - assertThat(UltraLogLog.hashPrefixToRegister(12)).isEqualTo((byte) 14); - assertThat(UltraLogLog.hashPrefixToRegister(1L << (12 - 1))).isEqualTo((byte) 44); - assertThat(UltraLogLog.hashPrefixToRegister(1L << 12)).isEqualTo((byte) 48); - assertThat(UltraLogLog.hashPrefixToRegister((1L << (12 - 1)) | (1L << (12)))) - .isEqualTo((byte) 50); - assertThat(UltraLogLog.hashPrefixToRegister(1L << (12 + 1))).isEqualTo((byte) 52); - assertThat(UltraLogLog.hashPrefixToRegister(0x8000000000000000L)).isEqualTo((byte) 252); - assertThat(UltraLogLog.hashPrefixToRegister(0xFFFFFFFFFFFFFFFFL)).isEqualTo((byte) 255); - - assertThat(UltraLogLog.registerToHashPrefix((byte) 0)).isZero(); - assertThat(UltraLogLog.registerToHashPrefix((byte) 4)).isZero(); - assertThat(UltraLogLog.registerToHashPrefix((byte) 8)).isEqualTo(4); - assertThat(UltraLogLog.registerToHashPrefix((byte) 9)).isEqualTo(5); - assertThat(UltraLogLog.registerToHashPrefix((byte) 10)).isEqualTo(6); - assertThat(UltraLogLog.registerToHashPrefix((byte) 11)).isEqualTo(7); - assertThat(UltraLogLog.registerToHashPrefix((byte) 12)).isEqualTo(8); - assertThat(UltraLogLog.registerToHashPrefix((byte) 13)).isEqualTo(10); - assertThat(UltraLogLog.registerToHashPrefix((byte) 14)).isEqualTo(12); - assertThat(UltraLogLog.registerToHashPrefix((byte) 44)).isEqualTo(1L << (12 - 1)); - assertThat(UltraLogLog.registerToHashPrefix((byte) 45)) - .isEqualTo((1L << (12 - 1)) + (1L << (12 - 3))); - assertThat(UltraLogLog.registerToHashPrefix((byte) 46)) - .isEqualTo((1L << (12 - 1)) + (1L << (12 - 2))); - assertThat(UltraLogLog.registerToHashPrefix((byte) 47)) + void testRegisterPacking() { + assertThat(UltraLogLog.pack(0x4L)).isEqualTo((byte) 8); + assertThat(UltraLogLog.pack(0x5L)).isEqualTo((byte) 9); + assertThat(UltraLogLog.pack(0x6L)).isEqualTo((byte) 10); + assertThat(UltraLogLog.pack(0x7L)).isEqualTo((byte) 11); + assertThat(UltraLogLog.pack(0x8L)).isEqualTo((byte) 12); + assertThat(UltraLogLog.pack(0x9L)).isEqualTo((byte) 12); + assertThat(UltraLogLog.pack(0xAL)).isEqualTo((byte) 13); + assertThat(UltraLogLog.pack(0xBL)).isEqualTo((byte) 13); + assertThat(UltraLogLog.pack(12)).isEqualTo((byte) 14); + assertThat(UltraLogLog.pack(1L << (12 - 1))).isEqualTo((byte) 44); + assertThat(UltraLogLog.pack(1L << 12)).isEqualTo((byte) 48); + assertThat(UltraLogLog.pack((1L << (12 - 1)) | (1L << (12)))).isEqualTo((byte) 50); + assertThat(UltraLogLog.pack(1L << (12 + 1))).isEqualTo((byte) 52); + assertThat(UltraLogLog.pack(0x8000000000000000L)).isEqualTo((byte) 252); + assertThat(UltraLogLog.pack(0xFFFFFFFFFFFFFFFFL)).isEqualTo((byte) 255); + + assertThat(UltraLogLog.unpack((byte) 0)).isZero(); + assertThat(UltraLogLog.unpack((byte) 4)).isZero(); + assertThat(UltraLogLog.unpack((byte) 8)).isEqualTo(4); + assertThat(UltraLogLog.unpack((byte) 9)).isEqualTo(5); + assertThat(UltraLogLog.unpack((byte) 10)).isEqualTo(6); + assertThat(UltraLogLog.unpack((byte) 11)).isEqualTo(7); + assertThat(UltraLogLog.unpack((byte) 12)).isEqualTo(8); + assertThat(UltraLogLog.unpack((byte) 13)).isEqualTo(10); + assertThat(UltraLogLog.unpack((byte) 14)).isEqualTo(12); + assertThat(UltraLogLog.unpack((byte) 44)).isEqualTo(1L << (12 - 1)); + assertThat(UltraLogLog.unpack((byte) 45)).isEqualTo((1L << (12 - 1)) + (1L << (12 - 3))); + assertThat(UltraLogLog.unpack((byte) 46)).isEqualTo((1L << (12 - 1)) + (1L << (12 - 2))); + assertThat(UltraLogLog.unpack((byte) 47)) .isEqualTo((1L << (12 - 1)) + (1L << (12 - 2)) + (1L << (12 - 3))); - assertThat(UltraLogLog.registerToHashPrefix((byte) 255)).isEqualTo(0xE000000000000000L); + assertThat(UltraLogLog.unpack((byte) 255)).isEqualTo(0xE000000000000000L); int smallestRegisterValue = (MIN_P << 2) - 4; for (int i = smallestRegisterValue; i < 256; i += 1) { byte b = (byte) i; - assertThat(UltraLogLog.hashPrefixToRegister(UltraLogLog.registerToHashPrefix(b))) - .isEqualTo(b); + assertThat(UltraLogLog.pack(UltraLogLog.unpack(b))).isEqualTo(b); } } @@ -132,13 +128,13 @@ void testSmallestRegisterValues() { long hashPrefix6 = 6L << (p - 1); long hashPrefix7 = 7L << (p - 1); - byte register1 = UltraLogLog.hashPrefixToRegister(hashPrefix1); - byte register2 = UltraLogLog.hashPrefixToRegister(hashPrefix2); - byte register3 = UltraLogLog.hashPrefixToRegister(hashPrefix3); - byte register4 = UltraLogLog.hashPrefixToRegister(hashPrefix4); - byte register5 = UltraLogLog.hashPrefixToRegister(hashPrefix5); - byte register6 = UltraLogLog.hashPrefixToRegister(hashPrefix6); - byte register7 = UltraLogLog.hashPrefixToRegister(hashPrefix7); + byte register1 = UltraLogLog.pack(hashPrefix1); + byte register2 = UltraLogLog.pack(hashPrefix2); + byte register3 = UltraLogLog.pack(hashPrefix3); + byte register4 = UltraLogLog.pack(hashPrefix4); + byte register5 = UltraLogLog.pack(hashPrefix5); + byte register6 = UltraLogLog.pack(hashPrefix6); + byte register7 = UltraLogLog.pack(hashPrefix7); assertThat(register1).isEqualTo((byte) ((p << 2) - 4)); assertThat(register2).isEqualTo((byte) (p << 2)); @@ -150,7 +146,7 @@ void testSmallestRegisterValues() { } long hashPrefixLargest = 0xFFFFFFFFFFFFFFFFL; - byte registerLargest = UltraLogLog.hashPrefixToRegister(hashPrefixLargest); + byte registerLargest = UltraLogLog.pack(hashPrefixLargest); assertThat(registerLargest).isEqualTo((byte) 255); }