From 56e5e93388c58ff15be18ba7a56a6b6d8bc9dda0 Mon Sep 17 00:00:00 2001 From: leventov Date: Sun, 17 Jan 2016 17:08:13 +0300 Subject: [PATCH] Hide the remaining parts of the replication API from the public eye --- pom.xml | 2 +- .../chronicle/hash/ChronicleHashBuilder.java | 43 +----- .../hash/ChronicleHashBuilderPrivateAPI.java | 46 +++++- .../hash/impl/VanillaChronicleHash.java | 5 +- .../DefaultEventualConsistencyStrategy.java | 5 +- .../hash/replication/ReplicableEntry.java | 5 +- .../hash/replication/TimeProvider.java | 3 +- .../chronicle/map/ChronicleMapBuilder.java | 17 +-- .../map/ChronicleMapBuilderPrivateAPI.java | 30 +++- .../map/replication/MapRemoteOperations.java | 2 +- .../chronicle/set/ChronicleSetBuilder.java | 51 ++----- .../set/ChronicleSetBuilderPrivateAPI.java | 131 ++++++++++++++++++ .../chronicle/map/Issue62ChronicleClient.java | 7 +- .../chronicle/map/Issue62ChronicleServer.java | 5 +- .../openhft/chronicle/map/RecoverTest.java | 38 ++--- .../map/ReplicatedChronicleMapTest.java | 19 +-- 16 files changed, 272 insertions(+), 137 deletions(-) create mode 100644 src/main/java/net/openhft/chronicle/set/ChronicleSetBuilderPrivateAPI.java diff --git a/pom.xml b/pom.xml index 0dc4311aa..973685d79 100755 --- a/pom.xml +++ b/pom.xml @@ -244,7 +244,7 @@ http://openhft.github.io/Chronicle-Values/apidocs/ - net.openhft.chronicle.hash.serialization.impl:net.openhft.xstream:net.openhft.chronicle.hash.impl:net.openhft.chronicle.map.impl + net.openhft.chronicle.hash.serialization.impl:net.openhft.xstream:net.openhft.chronicle.hash.impl:net.openhft.chronicle.map.impl:**.replication net/openhft/chronicle/hash/ChronicleHashBuilderPrivateAPI.java diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java index 7f191e5e9..513518542 100755 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java @@ -18,7 +18,6 @@ package net.openhft.chronicle.hash; import net.openhft.chronicle.bytes.Byteable; import net.openhft.chronicle.bytes.Bytes; -import net.openhft.chronicle.hash.replication.ReplicableEntry; import net.openhft.chronicle.hash.serialization.*; import net.openhft.chronicle.map.ChronicleMap; import net.openhft.chronicle.map.ChronicleMapBuilder; @@ -32,7 +31,6 @@ import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; /** * This interface defines the meaning of configurations, common to {@link ChronicleMapBuilder} and @@ -382,43 +380,6 @@ public interface ChronicleHashBuilder, */ B actualSegments(int actualSegments); - /** - * Configures timeout after which entries, marked as removed in the Chronicle Hash, constructed - * by this builder, are allowed to be completely removed from the data store. In replicated - * Chronicle nodes, when {@code remove()} on the key is called, the corresponding entry - * is not immediately erased from the data store, to let the distributed system eventually - * converge on some value for this key (or converge on the fact, that this key is removed). - * Chronicle Hash watch in runtime after the entries, and if one is removed and not updated - * in any way for this {@code removedEntryCleanupTimeout}, Chronicle is allowed to remove this - * entry completely from the data store. This timeout should depend on your distributed - * system topology, and typical replication latencies, that should be determined experimentally. - * - *

Default timeout is 1 minute. - * - * @param removedEntryCleanupTimeout timeout, after which stale removed entries could be erased - * from Chronicle Hash data store completely - * @param unit time unit, in which the timeout is given - * @return this builder back - * @throws IllegalArgumentException is the specified timeout is less than 1 millisecond - * @see #cleanupRemovedEntries(boolean) - * @see ReplicableEntry#doRemoveCompletely() - */ - B removedEntryCleanupTimeout(long removedEntryCleanupTimeout, TimeUnit unit); - - /** - * Configures if replicated Chronicle Hashes, constructed by this builder, should - * completely erase entries, removed some time ago. See {@link #removedEntryCleanupTimeout( - * long, TimeUnit)} for more details on this mechanism. - * - *

Default value is {@code true} -- old removed entries are erased with 1 second timeout. - * - * @param cleanupRemovedEntries if stale removed entries should be purged from Chronicle Hash - * @return this builder back - * @see #removedEntryCleanupTimeout(long, TimeUnit) - * @see ReplicableEntry#doRemoveCompletely() - */ - B cleanupRemovedEntries(boolean cleanupRemovedEntries); - /** * Configures the {@code DataAccess} and {@code SizedReader} used to serialize and deserialize * keys to and from off-heap memory in hash containers, created by this builder. @@ -511,8 +472,6 @@ public interface ChronicleHashBuilder, */ B checksumEntries(boolean checksumEntries); - B replication(byte identifier); - /** * Creates a new hash container from this builder, storing it's data in off-heap memory, not * mapped to any file. On {@link ChronicleHash#close()} called on the returned container, or @@ -622,5 +581,5 @@ public interface ChronicleHashBuilder, * @deprecated don't use private API in the client code */ @Deprecated - ChronicleHashBuilderPrivateAPI privateAPI(); + Object privateAPI(); } diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilderPrivateAPI.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilderPrivateAPI.java index b4b500bcf..c5baedeca 100644 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilderPrivateAPI.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilderPrivateAPI.java @@ -16,9 +16,12 @@ package net.openhft.chronicle.hash; +import net.openhft.chronicle.hash.replication.ReplicableEntry; import net.openhft.chronicle.hash.serialization.impl.SerializationBuilder; -public interface ChronicleHashBuilderPrivateAPI { +import java.util.concurrent.TimeUnit; + +public interface ChronicleHashBuilderPrivateAPI { SerializationBuilder keyBuilder(); @@ -43,4 +46,45 @@ public interface ChronicleHashBuilderPrivateAPI { boolean aligned64BitMemoryOperationsAtomic(); boolean checksumEntries(); + + void replication(byte identifier); + + /** + * Configures if replicated Chronicle Hashes, constructed by this builder, should + * completely erase entries, removed some time ago. See {@link #removedEntryCleanupTimeout( + * long, TimeUnit)} for more details on this mechanism. + * + *

Default value is {@code true} -- old removed entries are erased with 1 second timeout. + * + * @param cleanupRemovedEntries if stale removed entries should be purged from Chronicle Hash + * @return this builder back + * @see #removedEntryCleanupTimeout(long, TimeUnit) + * @see ReplicableEntry#doRemoveCompletely() + */ + void cleanupRemovedEntries(boolean cleanupRemovedEntries); + + /** + * Configures timeout after which entries, marked as removed in the Chronicle Hash, constructed + * by this builder, are allowed to be completely removed from the data store. In replicated + * Chronicle nodes, when {@code remove()} on the key is called, the corresponding entry + * is not immediately erased from the data store, to let the distributed system eventually + * converge on some value for this key (or converge on the fact, that this key is removed). + * Chronicle Hash watch in runtime after the entries, and if one is removed and not updated + * in any way for this {@code removedEntryCleanupTimeout}, Chronicle is allowed to remove this + * entry completely from the data store. This timeout should depend on your distributed + * system topology, and typical replication latencies, that should be determined experimentally. + * + *

Default timeout is 1 minute. + * + * @param removedEntryCleanupTimeout timeout, after which stale removed entries could be erased + * from Chronicle Hash data store completely + * @param unit time unit, in which the timeout is given + * @return this builder back + * @throws IllegalArgumentException is the specified timeout is less than 1 millisecond + * @see #cleanupRemovedEntries(boolean) + * @see ReplicableEntry#doRemoveCompletely() + */ + void removedEntryCleanupTimeout(long removedEntryCleanupTimeout, TimeUnit unit); + + void remoteOperations(RO remoteOperations); } diff --git a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java index 8aec28bd7..9b58e7bb1 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java @@ -162,8 +162,9 @@ public abstract class VanillaChronicleHash privateAPI = builder.privateAPI(); + @SuppressWarnings({"deprecation", "unchecked"}) + ChronicleHashBuilderPrivateAPI privateAPI = + (ChronicleHashBuilderPrivateAPI) builder.privateAPI(); // Data model SerializationBuilder keyBuilder = privateAPI.keyBuilder(); diff --git a/src/main/java/net/openhft/chronicle/hash/replication/DefaultEventualConsistencyStrategy.java b/src/main/java/net/openhft/chronicle/hash/replication/DefaultEventualConsistencyStrategy.java index 767601861..08487e7e8 100644 --- a/src/main/java/net/openhft/chronicle/hash/replication/DefaultEventualConsistencyStrategy.java +++ b/src/main/java/net/openhft/chronicle/hash/replication/DefaultEventualConsistencyStrategy.java @@ -18,6 +18,7 @@ package net.openhft.chronicle.hash.replication; import net.openhft.chronicle.hash.ChronicleHash; import net.openhft.chronicle.hash.ChronicleHashBuilder; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import net.openhft.chronicle.map.replication.MapRemoteOperations; import net.openhft.chronicle.set.replication.SetRemoteOperations; @@ -25,8 +26,8 @@ import static net.openhft.chronicle.hash.replication.DefaultEventualConsistencyS import static net.openhft.chronicle.hash.replication.DefaultEventualConsistencyStrategy.AcceptanceDecision.DISCARD; /** - * Specifies the default eventual consistency strategy for {@link ChronicleHashBuilder#replication( - * byte) replicated} {@link ChronicleHash}es: + * Specifies the default eventual consistency strategy for {@link + * ChronicleHashBuilderPrivateAPI#replication(byte) replicated} {@link ChronicleHash}es: * last write wins. If two writes to a single entry occurred simultaneously on different * nodes, the write on the node with lower identifier wins. * diff --git a/src/main/java/net/openhft/chronicle/hash/replication/ReplicableEntry.java b/src/main/java/net/openhft/chronicle/hash/replication/ReplicableEntry.java index a300593d2..b96ac7160 100644 --- a/src/main/java/net/openhft/chronicle/hash/replication/ReplicableEntry.java +++ b/src/main/java/net/openhft/chronicle/hash/replication/ReplicableEntry.java @@ -18,6 +18,7 @@ package net.openhft.chronicle.hash.replication; import net.openhft.chronicle.hash.ChronicleHash; import net.openhft.chronicle.hash.ChronicleHashBuilder; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import net.openhft.chronicle.hash.HashAbsentEntry; import net.openhft.chronicle.hash.HashEntry; import net.openhft.chronicle.map.ChronicleMap; @@ -121,8 +122,8 @@ public interface ReplicableEntry { * method any subsequent call of any method of {@code ReplicableEntry} class throws {@code * IllegalStateException}. * - * @see ChronicleHashBuilder#cleanupRemovedEntries(boolean) - * @see ChronicleHashBuilder#removedEntryCleanupTimeout(long, TimeUnit) + * @see ChronicleHashBuilderPrivateAPI#cleanupRemovedEntries(boolean) + * @see ChronicleHashBuilderPrivateAPI#removedEntryCleanupTimeout(long, TimeUnit) */ void doRemoveCompletely(); } diff --git a/src/main/java/net/openhft/chronicle/hash/replication/TimeProvider.java b/src/main/java/net/openhft/chronicle/hash/replication/TimeProvider.java index fdd64f9c3..743cfe527 100644 --- a/src/main/java/net/openhft/chronicle/hash/replication/TimeProvider.java +++ b/src/main/java/net/openhft/chronicle/hash/replication/TimeProvider.java @@ -18,6 +18,7 @@ package net.openhft.chronicle.hash.replication; import net.openhft.chronicle.hash.ChronicleHash; import net.openhft.chronicle.hash.ChronicleHashBuilder; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -32,7 +33,7 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; * * @see ReplicableEntry#originTimestamp() * @see RemoteOperationContext#remoteTimestamp() - * @see ChronicleHashBuilder#removedEntryCleanupTimeout(long, TimeUnit) + * @see ChronicleHashBuilderPrivateAPI#removedEntryCleanupTimeout(long, TimeUnit) */ public final class TimeProvider { diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java index 295b95352..98695887f 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilder.java @@ -22,7 +22,6 @@ import net.openhft.chronicle.bytes.Bytes; import net.openhft.chronicle.bytes.BytesStore; import net.openhft.chronicle.core.OS; import net.openhft.chronicle.hash.ChronicleHashBuilder; -import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import net.openhft.chronicle.hash.ChronicleHashRecoveryFailedException; import net.openhft.chronicle.hash.impl.CompactOffHeapLinearHashTable; import net.openhft.chronicle.hash.impl.stage.entry.ChecksumStrategy; @@ -146,7 +145,8 @@ public final class ChronicleMapBuilder implements private static int MAX_BOOTSTRAPPING_HEADER_SIZE = (int) MemoryUnit.KILOBYTES.toBytes(16); // not final because of cloning - private ChronicleMapBuilderPrivateAPI privateAPI = new ChronicleMapBuilderPrivateAPI<>(this); + private ChronicleMapBuilderPrivateAPI privateAPI = + new ChronicleMapBuilderPrivateAPI<>(this); ////////////////////////////// // Configuration fields @@ -267,7 +267,7 @@ public final class ChronicleMapBuilder implements */ @Override @Deprecated - public ChronicleHashBuilderPrivateAPI privateAPI() { + public Object privateAPI() { return privateAPI; } @@ -1152,8 +1152,7 @@ public final class ChronicleMapBuilder implements return toString().hashCode(); } - @Override - public ChronicleMapBuilder removedEntryCleanupTimeout( + ChronicleMapBuilder removedEntryCleanupTimeout( long removedEntryCleanupTimeout, TimeUnit unit) { if (unit.toMillis(removedEntryCleanupTimeout) < 1) { throw new IllegalArgumentException("timeout should be >= 1 millisecond, " + @@ -1164,8 +1163,7 @@ public final class ChronicleMapBuilder implements return this; } - @Override - public ChronicleMapBuilder cleanupRemovedEntries(boolean cleanupRemovedEntries) { + ChronicleMapBuilder cleanupRemovedEntries(boolean cleanupRemovedEntries) { this.cleanupRemovedEntries = cleanupRemovedEntries; return this; } @@ -1342,8 +1340,7 @@ public final class ChronicleMapBuilder implements return this; } - @Override - public ChronicleMapBuilder replication(byte identifier) { + ChronicleMapBuilder replication(byte identifier) { if (identifier <= 0) throw new IllegalArgumentException("Identifier must be positive, " + identifier + " given"); @@ -1608,7 +1605,7 @@ public final class ChronicleMapBuilder implements return this; } - public ChronicleMapBuilder remoteOperations( + ChronicleMapBuilder remoteOperations( MapRemoteOperations remoteOperations) { Objects.requireNonNull(remoteOperations); this.remoteOperations = remoteOperations; diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderPrivateAPI.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderPrivateAPI.java index adb7d5575..7936e6c70 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderPrivateAPI.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapBuilderPrivateAPI.java @@ -18,12 +18,16 @@ package net.openhft.chronicle.map; import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import net.openhft.chronicle.hash.serialization.impl.SerializationBuilder; +import net.openhft.chronicle.map.replication.MapRemoteOperations; -class ChronicleMapBuilderPrivateAPI implements ChronicleHashBuilderPrivateAPI { +import java.util.concurrent.TimeUnit; - private ChronicleMapBuilder b; +class ChronicleMapBuilderPrivateAPI + implements ChronicleHashBuilderPrivateAPI> { - public ChronicleMapBuilderPrivateAPI(ChronicleMapBuilder b) { + private final ChronicleMapBuilder b; + + public ChronicleMapBuilderPrivateAPI(ChronicleMapBuilder b) { this.b = b; } @@ -86,4 +90,24 @@ class ChronicleMapBuilderPrivateAPI implements ChronicleHashBuilderPrivateAPI public boolean checksumEntries() { return b.checksumEntries(); } + + @Override + public void replication(byte identifier) { + b.replication(identifier); + } + + @Override + public void cleanupRemovedEntries(boolean cleanupRemovedEntries) { + b.cleanupRemovedEntries(cleanupRemovedEntries); + } + + @Override + public void removedEntryCleanupTimeout(long removedEntryCleanupTimeout, TimeUnit unit) { + b.removedEntryCleanupTimeout(removedEntryCleanupTimeout, unit); + } + + @Override + public void remoteOperations(MapRemoteOperations remoteOperations) { + b.remoteOperations(remoteOperations); + } } diff --git a/src/main/java/net/openhft/chronicle/map/replication/MapRemoteOperations.java b/src/main/java/net/openhft/chronicle/map/replication/MapRemoteOperations.java index 856a7e575..da41cb430 100644 --- a/src/main/java/net/openhft/chronicle/map/replication/MapRemoteOperations.java +++ b/src/main/java/net/openhft/chronicle/map/replication/MapRemoteOperations.java @@ -64,7 +64,7 @@ import static net.openhft.chronicle.hash.replication.DefaultEventualConsistencyS * @param the map value type * @param the return type of {@link MapEntryOperations} specified fro the queried map * @see DefaultEventualConsistencyStrategy - * @see ChronicleMapBuilder#remoteOperations(MapRemoteOperations) + * @see ChronicleMapBuilderPrivateAPI#remoteOperations(MapRemoteOperations) */ public interface MapRemoteOperations { diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java index dd1fdfcf3..dca82d590 100755 --- a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java +++ b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilder.java @@ -22,14 +22,10 @@ import net.openhft.chronicle.hash.Data; import net.openhft.chronicle.hash.serialization.*; import net.openhft.chronicle.map.*; import net.openhft.chronicle.map.replication.MapRemoteOperations; -import net.openhft.chronicle.map.replication.MapRemoteQueryContext; -import net.openhft.chronicle.set.replication.SetRemoteOperations; -import net.openhft.chronicle.set.replication.SetRemoteQueryContext; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; -import java.util.concurrent.TimeUnit; /** * {@code ChronicleSetBuilder} manages the whole set of {@link ChronicleSet} configurations, could @@ -46,12 +42,17 @@ public final class ChronicleSetBuilder implements ChronicleHashBuilder, ChronicleSetBuilder> { private ChronicleMapBuilder chronicleMapBuilder; + private ChronicleSetBuilderPrivateAPI privateAPI; ChronicleSetBuilder(Class keyClass) { chronicleMapBuilder = ChronicleMapBuilder.of(keyClass, DummyValue.class) .valueReaderAndDataAccess( DummyValueMarshaller.INSTANCE, DummyValueMarshaller.INSTANCE) .valueSizeMarshaller(SizeMarshaller.constant(0)); + //noinspection deprecation,unchecked + privateAPI = new ChronicleSetBuilderPrivateAPI<>( + (ChronicleHashBuilderPrivateAPI>) + chronicleMapBuilder.privateAPI()); } public static ChronicleSetBuilder of(Class keyClass) { @@ -195,19 +196,6 @@ public final class ChronicleSetBuilder return toString().hashCode(); } - @Override - public ChronicleSetBuilder removedEntryCleanupTimeout( - long removedEntryCleanupTimeout, TimeUnit unit) { - chronicleMapBuilder.removedEntryCleanupTimeout(removedEntryCleanupTimeout, unit); - return this; - } - - @Override - public ChronicleSetBuilder cleanupRemovedEntries(boolean cleanupRemovedEntries) { - chronicleMapBuilder.cleanupRemovedEntries(cleanupRemovedEntries); - return this; - } - @Override public ChronicleSetBuilder keyReaderAndDataAccess( SizedReader keyReader, @NotNull DataAccess keyDataAccess) { @@ -262,44 +250,24 @@ public final class ChronicleSetBuilder return this; } - @Override - public ChronicleSetBuilder replication(byte identifier) { - chronicleMapBuilder.replication(identifier); - return this; - } - public ChronicleSetBuilder entryOperations(SetEntryOperations entryOperations) { chronicleMapBuilder.entryOperations(new MapEntryOperations() { @Override public Object remove(@NotNull MapEntry entry) { + //noinspection unchecked return entryOperations.remove((SetEntry) entry); } @Override public Object insert( @NotNull MapAbsentEntry absentEntry, Data value) { + //noinspection unchecked return entryOperations.insert((SetAbsentEntry) absentEntry); } }); return this; } - public ChronicleSetBuilder remoteOperations(SetRemoteOperations remoteOperations) { - chronicleMapBuilder.remoteOperations(new MapRemoteOperations() { - @Override - public void remove(MapRemoteQueryContext q) { - remoteOperations.remove((SetRemoteQueryContext) q); - } - - @Override - public void put( - MapRemoteQueryContext q, Data newValue) { - remoteOperations.put((SetRemoteQueryContext) q); - } - }); - return this; - } - @Override public ChronicleSet create() { final ChronicleMap map = chronicleMapBuilder.create(); @@ -331,9 +299,8 @@ public final class ChronicleSetBuilder */ @Deprecated @Override - public ChronicleHashBuilderPrivateAPI privateAPI() { - //noinspection deprecation - return chronicleMapBuilder.privateAPI(); + public Object privateAPI() { + return privateAPI; } } diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilderPrivateAPI.java b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilderPrivateAPI.java new file mode 100644 index 000000000..ccfc78b21 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/set/ChronicleSetBuilderPrivateAPI.java @@ -0,0 +1,131 @@ +/* + * 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 . + */ + +package net.openhft.chronicle.set; + +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; +import net.openhft.chronicle.hash.Data; +import net.openhft.chronicle.hash.serialization.impl.SerializationBuilder; +import net.openhft.chronicle.map.replication.MapRemoteOperations; +import net.openhft.chronicle.map.replication.MapRemoteQueryContext; +import net.openhft.chronicle.set.replication.SetRemoteOperations; +import net.openhft.chronicle.set.replication.SetRemoteQueryContext; + +import java.util.concurrent.TimeUnit; + +class ChronicleSetBuilderPrivateAPI + implements ChronicleHashBuilderPrivateAPI> { + + private final ChronicleHashBuilderPrivateAPI> mapB; + + public ChronicleSetBuilderPrivateAPI( + ChronicleHashBuilderPrivateAPI> mapB) { + this.mapB = mapB; + } + + @Override + public SerializationBuilder keyBuilder() { + return mapB.keyBuilder(); + } + + @Override + public int segmentEntrySpaceInnerOffset() { + return mapB.segmentEntrySpaceInnerOffset(); + } + + @Override + public long chunkSize() { + return mapB.chunkSize(); + } + + @Override + public int maxChunksPerEntry() { + return mapB.maxChunksPerEntry(); + } + + @Override + public long entriesPerSegment() { + return mapB.entriesPerSegment(); + } + + @Override + public long tierHashLookupCapacity() { + return mapB.tierHashLookupCapacity(); + } + + @Override + public long actualChunksPerSegmentTier() { + return mapB.actualChunksPerSegmentTier(); + } + + @Override + public int segmentHeaderSize() { + return mapB.segmentHeaderSize(); + } + + @Override + public int actualSegments() { + return mapB.actualSegments(); + } + + @Override + public long maxExtraTiers() { + return mapB.maxExtraTiers(); + } + + @Override + public boolean aligned64BitMemoryOperationsAtomic() { + return mapB.aligned64BitMemoryOperationsAtomic(); + } + + @Override + public boolean checksumEntries() { + return mapB.checksumEntries(); + } + + @Override + public void replication(byte identifier) { + mapB.replication(identifier); + } + + @Override + public void cleanupRemovedEntries(boolean cleanupRemovedEntries) { + mapB.cleanupRemovedEntries(cleanupRemovedEntries); + } + + @Override + public void removedEntryCleanupTimeout(long removedEntryCleanupTimeout, TimeUnit unit) { + mapB.removedEntryCleanupTimeout(removedEntryCleanupTimeout, unit); + } + + @Override + public void remoteOperations(SetRemoteOperations remoteOperations) { + mapB.remoteOperations(new MapRemoteOperations() { + @Override + public void remove(MapRemoteQueryContext q) { + //noinspection unchecked + remoteOperations.remove((SetRemoteQueryContext) q); + } + + @Override + public void put( + MapRemoteQueryContext q, Data newValue) { + //noinspection unchecked + remoteOperations.put((SetRemoteQueryContext) q); + } + }); + } +} diff --git a/src/test/java/net/openhft/chronicle/map/Issue62ChronicleClient.java b/src/test/java/net/openhft/chronicle/map/Issue62ChronicleClient.java index ad8c0b30e..300c820b4 100644 --- a/src/test/java/net/openhft/chronicle/map/Issue62ChronicleClient.java +++ b/src/test/java/net/openhft/chronicle/map/Issue62ChronicleClient.java @@ -16,12 +16,11 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.net.InetSocketAddress; import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; import static net.openhft.chronicle.map.Issue62ChronicleServer.MAP_FILE_B; import static net.openhft.chronicle.map.Issue62ChronicleServer.prepare; @@ -37,9 +36,11 @@ public class Issue62ChronicleClient { ChronicleMapBuilder.of(String.class, Long.class) //.averageKeySize(100) .averageKey(Issue62ChronicleServer.STR) - .replication((byte) 2) .entries(50_000); + ((ChronicleHashBuilderPrivateAPI) cityPostalCodesMapBuilder.privateAPI()) + .replication((byte) 2); + try (ChronicleMap map = cityPostalCodesMapBuilder.createPersistedTo(MAP_FILE_B)) { diff --git a/src/test/java/net/openhft/chronicle/map/Issue62ChronicleServer.java b/src/test/java/net/openhft/chronicle/map/Issue62ChronicleServer.java index f2b1faf42..9fada2820 100644 --- a/src/test/java/net/openhft/chronicle/map/Issue62ChronicleServer.java +++ b/src/test/java/net/openhft/chronicle/map/Issue62ChronicleServer.java @@ -16,6 +16,7 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,9 +50,11 @@ public class Issue62ChronicleServer { ChronicleMapBuilder.of(String.class, Long.class) //.averageKeySize(100) .averageKey(STR) - .replication((byte) 1) .entries(50_000); + ((ChronicleHashBuilderPrivateAPI) cityPostalCodesMapBuilder.privateAPI()) + .replication((byte) 1); + ChronicleMap cityPostalCodes = cityPostalCodesMapBuilder.createPersistedTo(MAP_FILE_A); diff --git a/src/test/java/net/openhft/chronicle/map/RecoverTest.java b/src/test/java/net/openhft/chronicle/map/RecoverTest.java index 809c354b6..19ad71ff7 100644 --- a/src/test/java/net/openhft/chronicle/map/RecoverTest.java +++ b/src/test/java/net/openhft/chronicle/map/RecoverTest.java @@ -16,6 +16,8 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.hash.ChronicleHashBuilder; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; @@ -44,14 +46,17 @@ public class RecoverTest { File mapFile = File.createTempFile("recoverTestFile", ".map"); mapFile.deleteOnExit(); - map = (ReplicatedChronicleMap) ChronicleMap + ChronicleMapBuilder builder = ChronicleMap .of(Integer.class, Integer.class) .entries(2) .actualSegments(1) - .checksumEntries(true) - .replication((byte) 1) - .cleanupRemovedEntries(false) - .createPersistedTo(mapFile); + .checksumEntries(true); + ChronicleHashBuilderPrivateAPI privateAPI = + (ChronicleHashBuilderPrivateAPI) builder.privateAPI(); + privateAPI.replication((byte) 1); + privateAPI.cleanupRemovedEntries(false); + + map = (ReplicatedChronicleMap) builder.createPersistedTo(mapFile); map.acquireModificationIterator((byte) 2); @@ -74,14 +79,8 @@ public class RecoverTest { map.close(); - map = (ReplicatedChronicleMap) ChronicleMap - .of(Integer.class, Integer.class) - .entries(2) - .actualSegments(1) - .checksumEntries(true) - .replication((byte) 1) - .cleanupRemovedEntries(false) - .recoverPersistedTo(mapFile, true); + map = (ReplicatedChronicleMap) + builder.recoverPersistedTo(mapFile, true); // acquires read lock successfully assertNull(map.get(0)); @@ -101,11 +100,14 @@ public class RecoverTest { for (int bit = 0; bit < 64; bit++) { LOG.error("flip bit {} of word at {}", bit, offset); mapBB.putLong((int) offset, mapBB.getLong((int) offset) ^ (1L << bit)); - try (ChronicleMap recovered = ChronicleMap - .of(Integer.class, Integer.class) - .replication((byte) 1) - .cleanupRemovedEntries(false) - .recoverPersistedTo(mapFile, false)) { + ChronicleMapBuilder recoverBuilder = ChronicleMap + .of(Integer.class, Integer.class); + ChronicleHashBuilderPrivateAPI recoverPrivateAPI = + (ChronicleHashBuilderPrivateAPI) recoverBuilder.privateAPI(); + recoverPrivateAPI.replication((byte) 1); + recoverPrivateAPI.cleanupRemovedEntries(false); + try (ChronicleMap recovered = + recoverBuilder.recoverPersistedTo(mapFile, false)) { recovered.put(1, 1); recovered.put(2, 2); recovered.remove(1); diff --git a/src/test/java/net/openhft/chronicle/map/ReplicatedChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/ReplicatedChronicleMapTest.java index db535cb94..bce08b63b 100644 --- a/src/test/java/net/openhft/chronicle/map/ReplicatedChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/ReplicatedChronicleMapTest.java @@ -16,6 +16,7 @@ package net.openhft.chronicle.map; +import net.openhft.chronicle.hash.ChronicleHashBuilderPrivateAPI; import net.openhft.chronicle.map.jsr166.JSR166TestCase; import org.junit.Ignore; import org.junit.Test; @@ -34,20 +35,22 @@ import static org.junit.Assert.*; */ public class ReplicatedChronicleMapTest extends JSR166TestCase { ChronicleMap newShmIntString() throws IOException { - return ChronicleMapBuilder.of(Integer.class, CharSequence.class) - .replication((byte) 1) + ChronicleMapBuilder builder = ChronicleMap + .of(Integer.class, CharSequence.class) .entries(1000) - .averageValueSize(20) - .create(); + .averageValueSize(20); + ((ChronicleHashBuilderPrivateAPI) builder.privateAPI()).replication((byte) 1); + return builder.create(); } ChronicleMap newShmStringString() throws IOException { - return ChronicleMapBuilder.of(CharSequence.class, CharSequence.class) - .replication((byte) 1) + ChronicleMapBuilder builder = ChronicleMap + .of(CharSequence.class, CharSequence.class) .entries(1000) .averageKeySize(20) - .averageValueSize(20) - .create(); + .averageValueSize(20); + ((ChronicleHashBuilderPrivateAPI) builder.privateAPI()).replication((byte) 1); + return builder.create(); } /**