mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Reduce ChronicleMapBuilder API surface, hide private API in a class
This commit is contained in:
@@ -505,4 +505,9 @@ public interface ChronicleHashBuilder<K, H extends ChronicleHash<K, ?, ?, ?>,
|
||||
* @see ChronicleHashInstanceBuilder#persistedTo(File)
|
||||
*/
|
||||
H createPersistedTo(File file) throws IOException;
|
||||
|
||||
/**
|
||||
* @deprecated don't use private API in the client code
|
||||
*/
|
||||
ChronicleHashBuilderPrivateAPI<K> privateAPI();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2015 higherfrequencytrading.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.openhft.chronicle.hash;
|
||||
|
||||
import net.openhft.chronicle.hash.serialization.internal.SerializationBuilder;
|
||||
|
||||
public interface ChronicleHashBuilderPrivateAPI<K> {
|
||||
|
||||
SerializationBuilder<K> keyBuilder();
|
||||
|
||||
int segmentEntrySpaceInnerOffset(boolean replicated);
|
||||
|
||||
long chunkSize(boolean replicated);
|
||||
|
||||
int maxChunksPerEntry(boolean replicated);
|
||||
|
||||
long entriesPerSegment(boolean replicated);
|
||||
|
||||
long actualChunksPerSegment(boolean replicated);
|
||||
|
||||
int segmentHeaderSize(boolean replicated);
|
||||
|
||||
int actualSegments(boolean replicated);
|
||||
}
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package net.openhft.chronicle.hash.impl;
|
||||
|
||||
import net.openhft.chronicle.hash.ChronicleHash;
|
||||
import net.openhft.chronicle.hash.ExternalHashQueryContext;
|
||||
import net.openhft.chronicle.hash.HashEntry;
|
||||
import net.openhft.chronicle.hash.HashSegmentContext;
|
||||
import net.openhft.chronicle.hash.*;
|
||||
import net.openhft.chronicle.hash.impl.util.BuildVersion;
|
||||
import net.openhft.chronicle.hash.serialization.BytesReader;
|
||||
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
|
||||
@@ -112,14 +109,16 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
|
||||
transient long segmentsOffset;
|
||||
|
||||
public transient CompactOffHeapLinearHashTable hashLookup;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
||||
public VanillaChronicleHash(ChronicleMapBuilder<K, ?> builder, boolean replicated) {
|
||||
// Version
|
||||
dataFileVersion = BuildVersion.version();
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
ChronicleHashBuilderPrivateAPI<K> privateAPI = builder.privateAPI();
|
||||
|
||||
// Data model
|
||||
SerializationBuilder<K> keyBuilder = builder.keyBuilder();
|
||||
SerializationBuilder<K> keyBuilder = privateAPI.keyBuilder();
|
||||
kClass = keyBuilder.eClass;
|
||||
keySizeMarshaller = keyBuilder.sizeMarshaller();
|
||||
originalKeyReader = keyBuilder.reader();
|
||||
@@ -127,17 +126,17 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
|
||||
originalMetaKeyInterop = (MKI) keyBuilder.metaInterop();
|
||||
metaKeyInteropProvider = (MetaProvider<K, KI, MKI>) keyBuilder.metaInteropProvider();
|
||||
|
||||
actualSegments = builder.actualSegments(replicated);
|
||||
actualSegments = privateAPI.actualSegments(replicated);
|
||||
hashSplitting = HashSplitting.Splitting.forSegments(actualSegments);
|
||||
|
||||
entriesPerSegment = builder.entriesPerSegment(replicated);
|
||||
entriesPerSegment = privateAPI.entriesPerSegment(replicated);
|
||||
|
||||
chunkSize = builder.chunkSize(replicated);
|
||||
maxChunksPerEntry = builder.maxChunksPerEntry(replicated);
|
||||
actualChunksPerSegment = builder.actualChunksPerSegment(replicated);
|
||||
chunkSize = privateAPI.chunkSize(replicated);
|
||||
maxChunksPerEntry = privateAPI.maxChunksPerEntry(replicated);
|
||||
actualChunksPerSegment = privateAPI.actualChunksPerSegment(replicated);
|
||||
|
||||
// Precomputed offsets and sizes for fast Context init
|
||||
segmentHeaderSize = builder.segmentHeaderSize(replicated);
|
||||
segmentHeaderSize = privateAPI.segmentHeaderSize(replicated);
|
||||
|
||||
segmentHashLookupValueBits = valueBits(actualChunksPerSegment);
|
||||
segmentHashLookupKeyBits = keyBits(entriesPerSegment, segmentHashLookupValueBits);
|
||||
@@ -152,7 +151,7 @@ public abstract class VanillaChronicleHash<K, KI, MKI extends MetaBytesInterop<K
|
||||
segmentFreeListOuterSize = CACHE_LINES.align(segmentFreeListInnerSize, BYTES);
|
||||
|
||||
segmentEntrySpaceInnerSize = chunkSize * actualChunksPerSegment;
|
||||
segmentEntrySpaceInnerOffset = builder.segmentEntrySpaceInnerOffset(replicated);
|
||||
segmentEntrySpaceInnerOffset = privateAPI.segmentEntrySpaceInnerOffset(replicated);
|
||||
segmentEntrySpaceOuterSize = CACHE_LINES.align(
|
||||
segmentEntrySpaceInnerOffset + segmentEntrySpaceInnerSize, BYTES);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilder;
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI;
|
||||
import net.openhft.chronicle.hash.ChronicleHashInstanceBuilder;
|
||||
import net.openhft.chronicle.hash.replication.*;
|
||||
import net.openhft.chronicle.hash.serialization.*;
|
||||
@@ -129,6 +130,8 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
private static final boolean strictStateChecks =
|
||||
Boolean.getBoolean("chronicle.strictStateChecks");
|
||||
|
||||
private ChronicleMapBuilderPrivateAPI<K> privateAPI = new ChronicleMapBuilderPrivateAPI<>(this);
|
||||
|
||||
SerializationBuilder<K> keyBuilder;
|
||||
SerializationBuilder<V> valueBuilder;
|
||||
|
||||
@@ -196,7 +199,8 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
}
|
||||
|
||||
public static <K, V> ChronicleMapStatelessClientBuilder<K, V> of(
|
||||
@NotNull Class<K> keyClass, @NotNull Class<V> valueClass, InetSocketAddress socketAddress) {
|
||||
@NotNull Class<K> keyClass, @NotNull Class<V> valueClass,
|
||||
InetSocketAddress socketAddress) {
|
||||
return ChronicleMapStatelessClientBuilder.of(socketAddress);
|
||||
}
|
||||
|
||||
@@ -236,12 +240,21 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
(ChronicleMapBuilder<K, V>) super.clone();
|
||||
result.keyBuilder = keyBuilder.clone();
|
||||
result.valueBuilder = valueBuilder.clone();
|
||||
result.privateAPI = new ChronicleMapBuilderPrivateAPI<>(result);
|
||||
return result;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated don't use private API in the client code
|
||||
*/
|
||||
@Override
|
||||
public ChronicleHashBuilderPrivateAPI<K> privateAPI() {
|
||||
return privateAPI;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
@@ -484,11 +497,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public SerializationBuilder<K> keyBuilder() {
|
||||
SerializationBuilder<K> keyBuilder() {
|
||||
return keyBuilder;
|
||||
}
|
||||
|
||||
@@ -547,11 +556,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return new EntrySizeInfo(size, worstAlignment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public int segmentEntrySpaceInnerOffset(boolean replicated) {
|
||||
int segmentEntrySpaceInnerOffset(boolean replicated) {
|
||||
// This is needed, if chunkSize = constant entry size is not aligned, for entry alignment
|
||||
// to be always the same, we should _misalign_ the first chunk.
|
||||
if (!constantlySizedEntries())
|
||||
@@ -607,11 +612,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return greatestCommonDivisor(b, a % b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public long chunkSize(boolean replicated) {
|
||||
long chunkSize(boolean replicated) {
|
||||
if (actualChunkSize > 0)
|
||||
return actualChunkSize;
|
||||
double averageEntrySize = entrySizeInfo(replicated).averageEntrySize;
|
||||
@@ -632,7 +633,6 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
double averageChunksPerEntry(boolean replicated) {
|
||||
if (constantlySizedEntries())
|
||||
return 1.0;
|
||||
@SuppressWarnings("deprecation")
|
||||
long chunkSize = chunkSize(replicated);
|
||||
// assuming we always has worst internal fragmentation. This affects total segment
|
||||
// entry space which is allocated lazily on Linux (main target platform)
|
||||
@@ -653,14 +653,9 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public int maxChunksPerEntry(boolean replicated) {
|
||||
int maxChunksPerEntry(boolean replicated) {
|
||||
if (constantlySizedEntries())
|
||||
return 1;
|
||||
@SuppressWarnings("deprecation")
|
||||
long actualChunksPerSegment = actualChunksPerSegment(replicated);
|
||||
int result = (int) Math.min(actualChunksPerSegment, (long) Integer.MAX_VALUE);
|
||||
if (this.maxChunksPerEntry > 0)
|
||||
@@ -739,16 +734,11 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public long entriesPerSegment(boolean replicated) {
|
||||
long entriesPerSegment(boolean replicated) {
|
||||
long entriesPerSegment;
|
||||
if (this.entriesPerSegment > 0L) {
|
||||
entriesPerSegment = this.entriesPerSegment;
|
||||
} else {
|
||||
@SuppressWarnings("deprecation")
|
||||
int actualSegments = actualSegments(replicated);
|
||||
long totalEntries = totalEntriesIfPoorDistribution(actualSegments);
|
||||
entriesPerSegment = divideUpper(totalEntries, actualSegments);
|
||||
@@ -799,11 +789,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public long actualChunksPerSegment(boolean replicated) {
|
||||
long actualChunksPerSegment(boolean replicated) {
|
||||
if (actualChunksPerSegment > 0)
|
||||
return actualChunksPerSegment;
|
||||
return chunksPerSegment(entriesPerSegment(replicated), replicated);
|
||||
@@ -850,7 +836,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return (int) Math.min(Maths.nextPower2(entries() / 32, 1), estimateSegmentsBasedOnSize());
|
||||
}
|
||||
|
||||
//TODO reivew because this heuristic doesn't seem to perform well
|
||||
//TODO review because this heuristic doesn't seem to perform well
|
||||
private int estimateSegmentsBasedOnSize() {
|
||||
// the idea is that if values are huge, operations on them (and simply ser/deser)
|
||||
// could take long time, so we want more segment to minimize probablity that
|
||||
@@ -892,11 +878,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public int actualSegments(boolean replicated) {
|
||||
int actualSegments(boolean replicated) {
|
||||
if (actualSegments > 0)
|
||||
return actualSegments;
|
||||
if (entriesPerSegment > 0) {
|
||||
@@ -984,12 +966,7 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
return segments <= maxSegments ? segments : -segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated part of private API, shouldn't be used in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
public int segmentHeaderSize(boolean replicated) {
|
||||
@SuppressWarnings("deprecation")
|
||||
int segmentHeaderSize(boolean replicated) {
|
||||
int segments = actualSegments(replicated);
|
||||
// reduce false sharing unless we have a lot of segments.
|
||||
return segments <= 16 * 1024 ? 64 : 32;
|
||||
@@ -1589,7 +1566,6 @@ public final class ChronicleMapBuilder<K, V> implements
|
||||
if (builder.constantSizeMarshaller())
|
||||
return round(ceil(averageSize));
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
int maxChunksPerEntry = maxChunksPerEntry(replicated);
|
||||
// if maxChunksPerEntry is Integer.MAX_VALUE, we, of cause,
|
||||
// are not going to allocate such big buffers
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2015 higherfrequencytrading.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI;
|
||||
import net.openhft.chronicle.hash.serialization.internal.SerializationBuilder;
|
||||
|
||||
class ChronicleMapBuilderPrivateAPI<K> implements ChronicleHashBuilderPrivateAPI<K> {
|
||||
|
||||
private ChronicleMapBuilder<K, ?> b;
|
||||
|
||||
public ChronicleMapBuilderPrivateAPI(ChronicleMapBuilder<K, ?> b) {
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SerializationBuilder<K> keyBuilder() {
|
||||
return b.keyBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int segmentEntrySpaceInnerOffset(boolean replicated) {
|
||||
return b.segmentEntrySpaceInnerOffset(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long chunkSize(boolean replicated) {
|
||||
return b.chunkSize(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxChunksPerEntry(boolean replicated) {
|
||||
return b.maxChunksPerEntry(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long entriesPerSegment(boolean replicated) {
|
||||
return b.entriesPerSegment(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long actualChunksPerSegment(boolean replicated) {
|
||||
return b.actualChunksPerSegment(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int segmentHeaderSize(boolean replicated) {
|
||||
return b.segmentHeaderSize(replicated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int actualSegments(boolean replicated) {
|
||||
return b.actualSegments(replicated);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package net.openhft.chronicle.set;
|
||||
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilder;
|
||||
import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI;
|
||||
import net.openhft.chronicle.hash.ChronicleHashInstanceBuilder;
|
||||
import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication;
|
||||
import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
|
||||
@@ -288,5 +289,14 @@ public final class ChronicleSetBuilder<K>
|
||||
ChronicleMap<K, DummyValue> map = chronicleMapBuilder.createPersistedTo(file);
|
||||
return new SetFromMap<>(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated don't use private API in the client code
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public ChronicleHashBuilderPrivateAPI<K> privateAPI() {
|
||||
return chronicleMapBuilder.privateAPI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user