Skip to content

Commit 9bb8f4f

Browse files
author
Piotr Kołaczkowski
committed
CNDB-16243: Improve hash quality for small numbers even further
1 parent e00e8ac commit 9bb8f4f

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

src/java/org/apache/cassandra/cache/ChunkCache.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public int hashCode()
314314
{
315315
// Mix readerId and position into a single long using a large prime multiplier
316316
// This constant is a mixing constant derived from the Golden Ratio
317-
long mixed = (Long.rotateLeft(readerId, 16) + Long.rotateLeft(position, 16)) * 0x9E3779B97F4A7C15L;
317+
long mixed = (Long.rotateLeft(readerId, 16) + position) * 0x9E3779B97F4A7C15L;
318318

319319
// Spread the bits (XOR-shift) to ensure high bits affect low bits
320320
mixed ^= (mixed >>> 32);

test/unit/org/apache/cassandra/cache/ChunkCacheKeyTest.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
import org.junit.Test;
2929

30+
import org.apache.cassandra.utils.Pair;
31+
3032
import static org.junit.Assert.assertEquals;
3133
import static org.junit.Assert.assertFalse;
3234
import static org.junit.Assert.assertNotEquals;
@@ -199,15 +201,36 @@ public void testHashCodeDistribution() throws Exception
199201
{
200202
// Test that hash codes are reasonably distributed
201203
Set<Integer> hashes = new HashSet<>();
202-
for (long i = 0; i < 1000; i++)
204+
Set<ChunkCache.Key> keys = new HashSet<>();
205+
206+
for (long i = 0; i < 10000; i++)
203207
{
204-
ChunkCache.Key key = createKey(i, i * 2);
208+
ChunkCache.Key key = createKey(i * 2, i);
209+
keys.add(key);
205210
hashes.add(key.hashCode());
206211
}
207212

208-
// We should have a good distribution - at least 90% unique hashes
209-
assertTrue("Hash distribution is poor: " + hashes.size() + " unique hashes out of 1000",
210-
hashes.size() > 900);
213+
testHashCollisions(hashes, keys);
214+
215+
hashes.clear();
216+
keys.clear();
217+
for (long i = 0; i < 100; i++)
218+
{
219+
for (long j = 0; j < 100; j++)
220+
{
221+
ChunkCache.Key key = createKey(i, j);
222+
keys.add(key);
223+
hashes.add(key.hashCode());
224+
}
225+
}
226+
227+
testHashCollisions(hashes, keys);
228+
}
229+
230+
private static void testHashCollisions(Set<Integer> hashes, Set<ChunkCache.Key> keys)
231+
{
232+
assertTrue("Hash distribution is poor: " + hashes.size() + " unique hashes out of " + keys.size(),
233+
hashes.size() >= keys.size() * 0.99);
211234
}
212235

213236
@Test

0 commit comments

Comments
 (0)