mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-387 add a way to limit hash lookup slots to 4 bytes
This commit is contained in:
@@ -555,6 +555,17 @@ public interface ChronicleHashBuilder<K, H extends ChronicleHash<K, ?, ?, ?>,
|
||||
*/
|
||||
B immutableKeys();
|
||||
|
||||
/**
|
||||
* Specifies whether on the current combination of platform, OS and Jvm aligned 8-byte reads
|
||||
* and writes are atomic or not. By default, Chronicle tries to determine this itself, but
|
||||
* if it fails it pessimistically assumes that 64-bit memory operations are <i>not</i> atomic.
|
||||
*
|
||||
* @param aligned64BitMemoryOperationsAtomic {@code true} if aligned 8-byte memory operations
|
||||
* are atomic
|
||||
* @return this builder back
|
||||
*/
|
||||
B aligned64BitMemoryOperationsAtomic(boolean aligned64BitMemoryOperationsAtomic);
|
||||
|
||||
/**
|
||||
* Configures replication of the hash containers, created by this builder. See <a
|
||||
* href="https://github.com/OpenHFT/Chronicle-Map#tcp--udp-replication"> the section about
|
||||
|
||||
@@ -37,4 +37,6 @@ public interface ChronicleHashBuilderPrivateAPI<K> {
|
||||
int actualSegments(boolean replicated);
|
||||
|
||||
long maxExtraTiers(boolean replicated);
|
||||
|
||||
boolean aligned64BitMemoryOperationsAtomic();
|
||||
}
|
||||
|
||||
@@ -187,6 +187,10 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
|
||||
segmentHashLookupKeyBits = keyBits(entriesPerSegment, segmentHashLookupValueBits);
|
||||
segmentHashLookupEntrySize =
|
||||
entrySize(segmentHashLookupKeyBits, segmentHashLookupValueBits);
|
||||
if (!privateAPI.aligned64BitMemoryOperationsAtomic() && segmentHashLookupEntrySize > 4) {
|
||||
throw new IllegalStateException("aligned64BitMemoryOperationsAtomic() == false, " +
|
||||
"but hash lookup slot is " + segmentHashLookupEntrySize);
|
||||
}
|
||||
segmentHashLookupCapacity = CompactOffHeapLinearHashTable.capacityFor(entriesPerSegment);
|
||||
segmentHashLookupInnerSize = segmentHashLookupCapacity * segmentHashLookupEntrySize;
|
||||
segmentHashLookupOuterSize = CACHE_LINES.align(segmentHashLookupInnerSize, BYTES);
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.core.OS;
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilder;
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI;
|
||||
import net.openhft.chronicle.hash.ChronicleHashInstanceBuilder;
|
||||
import net.openhft.chronicle.hash.impl.CompactOffHeapLinearHashTable;
|
||||
import net.openhft.chronicle.hash.impl.util.math.PoissonDistribution;
|
||||
import net.openhft.chronicle.hash.replication.*;
|
||||
import net.openhft.chronicle.hash.serialization.*;
|
||||
@@ -161,6 +163,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
private double maxBloatFactor = 1.0;
|
||||
private boolean allowSegmentTiering = true;
|
||||
private double nonTieredSegmentsPercentile = 0.99999;
|
||||
private boolean aligned64BitMemoryOperationsAtomic = OS.is64Bit() ? true : false;
|
||||
|
||||
private boolean putReturnsNull = false;
|
||||
private boolean removeReturnsNull = false;
|
||||
@@ -758,17 +761,18 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
entriesPerSegment = PoissonDistribution.inverseCumulativeProbability(
|
||||
averageEntriesPerSegment, nonTieredSegmentsPercentile);
|
||||
}
|
||||
if (actualChunksPerSegment > 0)
|
||||
return entriesPerSegment;
|
||||
double averageChunksPerEntry = averageChunksPerEntry(replicated);
|
||||
if (entriesPerSegment * averageChunksPerEntry >
|
||||
MAX_SEGMENT_CHUNKS)
|
||||
throw new IllegalStateException("Max chunks per segment is " +
|
||||
MAX_SEGMENT_CHUNKS +
|
||||
" configured entries() and " +
|
||||
"actualSegments() so that there should be " + entriesPerSegment +
|
||||
" entries per segment, while average chunks per entry is " +
|
||||
averageChunksPerEntry);
|
||||
boolean actualChunksDefined = actualChunksPerSegment > 0;
|
||||
if (!actualChunksDefined) {
|
||||
double averageChunksPerEntry = averageChunksPerEntry(replicated);
|
||||
if (entriesPerSegment * averageChunksPerEntry >
|
||||
MAX_SEGMENT_CHUNKS)
|
||||
throw new IllegalStateException("Max chunks per segment is " +
|
||||
MAX_SEGMENT_CHUNKS +
|
||||
" configured entries() and " +
|
||||
"actualSegments() so that there should be " + entriesPerSegment +
|
||||
" entries per segment, while average chunks per entry is " +
|
||||
averageChunksPerEntry);
|
||||
}
|
||||
if (entriesPerSegment > MAX_SEGMENT_ENTRIES)
|
||||
throw new IllegalStateException("shouldn't be more than " +
|
||||
MAX_SEGMENT_ENTRIES + " entries per segment");
|
||||
@@ -901,7 +905,9 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
long segments = tryHashLookupSlotSize(4, replicated);
|
||||
if (segments > 0)
|
||||
return (int) segments;
|
||||
long maxEntriesPerSegment = findMaxEntriesPerSegmentToFitHashLookupSlotSize(8, replicated);
|
||||
int maxHashLookupEntrySize = aligned64BitMemoryOperationsAtomic() ? 8 : 4;
|
||||
long maxEntriesPerSegment =
|
||||
findMaxEntriesPerSegmentToFitHashLookupSlotSize(maxHashLookupEntrySize, replicated);
|
||||
long maxSegments = trySegments(maxEntriesPerSegment, MAX_SEGMENTS, replicated);
|
||||
if (maxSegments > 0L)
|
||||
return (int) maxSegments;
|
||||
@@ -1187,6 +1193,17 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleMapBuilder<K, V> aligned64BitMemoryOperationsAtomic(
|
||||
boolean aligned64BitMemoryOperationsAtomic) {
|
||||
this.aligned64BitMemoryOperationsAtomic = aligned64BitMemoryOperationsAtomic;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean aligned64BitMemoryOperationsAtomic() {
|
||||
return aligned64BitMemoryOperationsAtomic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@code BytesMarshaller} used to serialize/deserialize values to/from off-heap
|
||||
* memory in maps, created by this builder. See <a href="https://github.com/OpenHFT/Chronicle-Map#serialization">the
|
||||
|
||||
@@ -71,4 +71,9 @@ class ChronicleMapBuilderPrivateAPI<K> implements ChronicleHashBuilderPrivateAPI
|
||||
public long maxExtraTiers(boolean replicated) {
|
||||
return b.maxExtraTiers(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean aligned64BitMemoryOperationsAtomic() {
|
||||
return b.aligned64BitMemoryOperationsAtomic();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,6 +286,12 @@ public final class ChronicleSetBuilder<K>
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleSetBuilder<K> aligned64BitMemoryOperationsAtomic(
|
||||
boolean aligned64BitMemoryOperationsAtomic) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChronicleSetBuilder<K> replication(SingleChronicleHashReplication replication) {
|
||||
chronicleMapBuilder.replication(replication);
|
||||
|
||||
Reference in New Issue
Block a user