mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Tweek the sizing rules as well as optimise the hashing algo so it creates a more even distribution (for at least one set of test cases)
This commit is contained in:
@@ -23,11 +23,12 @@ import sun.misc.Unsafe;
|
||||
import static java.nio.ByteOrder.LITTLE_ENDIAN;
|
||||
import static java.nio.ByteOrder.nativeOrder;
|
||||
|
||||
public final class Hasher {
|
||||
public enum Hasher {
|
||||
;
|
||||
|
||||
private static final long LONG_LEVEL_PRIME_MULTIPLE = 1011001110001111L;
|
||||
private static final int SHORT_LEVEL_PRIME_MULTIPLE = 101111;
|
||||
private static final long BYTE_LEVEL_PRIME_MULTIPLE = 2111;
|
||||
private static final short SHORT_LEVEL_PRIME_MULTIPLE = 10191;
|
||||
private static final byte BYTE_LEVEL_PRIME_MULTIPLE = 109;
|
||||
|
||||
private static final int INT_HASH_LOW_SHORT_MULTIPLE =
|
||||
nativeOrder() == LITTLE_ENDIAN ? SHORT_LEVEL_PRIME_MULTIPLE : 1;
|
||||
@@ -72,10 +73,8 @@ public final class Hasher {
|
||||
}
|
||||
|
||||
public static long hash(long value) {
|
||||
value *= 11018881818881011L;
|
||||
value ^= (value >>> 41) ^ (value >>> 21);
|
||||
value ^= (value >>> 41) - (value >>> 21);
|
||||
value ^= (value >>> 15) + (value >>> 7);
|
||||
return value;
|
||||
}
|
||||
|
||||
private Hasher() {}
|
||||
}
|
||||
|
||||
@@ -390,10 +390,10 @@ public class ChronicleMapBuilder<K, V> implements Cloneable,
|
||||
if (actualEntriesPerSegment > 0)
|
||||
return actualEntriesPerSegment;
|
||||
int as = actualSegments();
|
||||
long actualEntries =
|
||||
as == 1 ? entries + 1 : // The extra 1 might not be needed.
|
||||
as <= 4 ? entries * 10L / 9 : // 10%, assumes you are trying to be tight.
|
||||
entries * 5L / 4; // 25%
|
||||
long actualEntries = entries +
|
||||
(as == 1 ? 1 : // The extra 1 might not be needed.
|
||||
as <= 8 ? entries / 12 : // 6%, (3% was min for tests)
|
||||
entries / 6); // 16% (8% was min for tests)
|
||||
|
||||
// round up to the next multiple of 64.
|
||||
return (int) (Math.max(1, actualEntries / as) + 63) & ~63;
|
||||
|
||||
@@ -262,7 +262,7 @@ class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
int segmentNum = getSegment(hash);
|
||||
int segmentHash = segmentHash(hash);
|
||||
return segment(segmentNum).acquire(copies, metaKeyWriter, keyWriter, key, value,
|
||||
segmentHash, create, timeProvider.currentTimeMillis());
|
||||
segmentHash, create, create ? timeProvider.currentTimeMillis() : 0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.common.ChronicleHashErrorListener;
|
||||
import net.openhft.chronicle.common.serialization.*;
|
||||
import net.openhft.chronicle.common.threadlocal.Provider;
|
||||
import net.openhft.chronicle.common.threadlocal.ThreadLocalCopies;
|
||||
import net.openhft.chronicle.common.serialization.*;
|
||||
import net.openhft.lang.Maths;
|
||||
import net.openhft.lang.collection.DirectBitSet;
|
||||
import net.openhft.lang.collection.SingleThreadedDirectBitSet;
|
||||
@@ -910,10 +910,10 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
ret = (int) freeList.setNextNContinuousClearBits(0, blocks);
|
||||
if (ret == DirectBitSet.NOT_FOUND) {
|
||||
if (blocks == 1) {
|
||||
throw new IllegalArgumentException(
|
||||
throw new IllegalStateException(
|
||||
"Segment is full, no free entries found");
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
throw new IllegalStateException(
|
||||
"Segment is full or has no ranges of " + blocks
|
||||
+ " continuous free blocks"
|
||||
);
|
||||
@@ -970,7 +970,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
|
||||
/**
|
||||
* Removes a key (or key-value pair) from the Segment.
|
||||
*
|
||||
* <p/>
|
||||
* <p>The entry will only be removed if {@code expectedValue} equals to {@code null}
|
||||
* or the value previously corresponding to the specified key.
|
||||
*
|
||||
@@ -1446,4 +1446,11 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
return super.setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
int[] segmentSizes() {
|
||||
int[] sizes = new int[segments.length];
|
||||
for (int i = 0; i < segments.length; i++)
|
||||
sizes[i] = segments[i].getSize();
|
||||
return sizes;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user