From 6816810b9055d74f0f65e8bd81ad12ae5777f6ae Mon Sep 17 00:00:00 2001 From: Rob Austin Date: Tue, 11 Nov 2014 16:46:32 +0000 Subject: [PATCH] HCOLL-200 fixed - testBootstrapAndHeartbeat --- .../chronicle/hash/ChronicleHashBuilder.java | 2 + .../hash/replication/AbstractReplication.java | 3 - .../map/AbstractChronicleMapBuilder.java | 121 +++++++++--------- .../chronicle/set/ChronicleSetBuilder.java | 39 +++--- .../TCPSocketReplicationBootStrapTest.java | 5 - 5 files changed, 88 insertions(+), 82 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java index c34fe9906..74c757787 100644 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java @@ -397,6 +397,8 @@ public interface ChronicleHashBuilder statelessClient(InetSocketAddress remoteAddress); ChronicleHashInstanceConfig instance(); diff --git a/src/main/java/net/openhft/chronicle/hash/replication/AbstractReplication.java b/src/main/java/net/openhft/chronicle/hash/replication/AbstractReplication.java index dd4079e5d..4bf537ded 100644 --- a/src/main/java/net/openhft/chronicle/hash/replication/AbstractReplication.java +++ b/src/main/java/net/openhft/chronicle/hash/replication/AbstractReplication.java @@ -116,9 +116,6 @@ public abstract class AbstractReplication { if (identifier <= 0) throw new IllegalArgumentException("Identifier must be positive, " + identifier + " given"); - if (udpConfig == null && tcpConfig == null) - throw new IllegalStateException( - "At least one transport method (TCP or UDP) should be configured"); } } } diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java index 2abcc5b65..f54953bf1 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMapBuilder.java @@ -55,18 +55,18 @@ import java.util.concurrent.TimeUnit; import static net.openhft.chronicle.map.Objects.builderEquals; /** - * {@code AbstractChronicleMapBuilder} manages most of {@link ChronicleMap} configurations; has two - * concrete subclasses: {@link ChronicleMapBuilder} should be used to create maps with ordinary - * values, {@link OffHeapUpdatableChronicleMapBuilder} -- maps with {@link Byteable} values, which - * point directly to off-heap memory; could be used as a classic builder and/or factory. This means + * {@code AbstractChronicleMapBuilder} manages most of {@link ChronicleMap} configurations; has two concrete + * subclasses: {@link ChronicleMapBuilder} should be used to create maps with ordinary values, {@link + * OffHeapUpdatableChronicleMapBuilder} -- maps with {@link Byteable} values, which point directly to off-heap + * memory; could be used as a classic builder and/or factory. This means * that in addition to the standard builder usage pattern:
{@code
  * ChronicleMap map = ChronicleMapBuilder
  *     .of(Key.class, Value.class)
  *     .entries(100500)
  *     // ... other configurations
  *     .create();}
- * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link ChronicleMapBuilder} or - * {@link OffHeapUpdatableChronicleMapBuilder}, could be prepared and used to create many similar + * one of concrete {@code AbstractChronicleMapBuilder} subclasses, {@link ChronicleMapBuilder} or {@link + * OffHeapUpdatableChronicleMapBuilder}, could be prepared and used to create many similar * maps:
{@code
  * OffHeapUpdatableChronicleMapBuilder builder = OffHeapUpdatableChronicleMapBuilder
  *     .of(Key.class, Value.class)
@@ -77,17 +77,16 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
  * i. e. created {@code ChronicleMap} instances don't depend on the builder.
  *
  * 

{@code AbstractChronicleMapBuilder} and it's subclasses are mutable, see a note in {@link - * ChronicleHashBuilder} interface documentation.

Later in this documentation, - * "ChronicleMap" means "ChronicleMaps, created by {@code AbstractChronicleMapBuilder}", unless - * specified different, because theoretically someone might provide {@code ChronicleMap} - * implementations with completely different properties.

{@code ChronicleMap} - * ("ChronicleMaps, created by {@code AbstractChronicleMapBuilder}") currently doesn't support - * resizing. That is why you should always configure {@linkplain #entries(long) number of - * entries} you are going to insert into the created map at most. See {@link #entries(long)} - * method documentation for more information on this.

{@code ChronicleMap} allocates memory - * by equally sized chunks. This size is called {@linkplain #entrySize(int) entry size}, you are - * strongly recommended to configure it to achieve least memory consumption and best speed. See - * {@link #entrySize(int)} method documentation for more information on this.

+ * ChronicleHashBuilder} interface documentation.

Later in this documentation, "ChronicleMap" means + * "ChronicleMaps, created by {@code AbstractChronicleMapBuilder}", unless specified different, because + * theoretically someone might provide {@code ChronicleMap} implementations with completely different + * properties.

{@code ChronicleMap} ("ChronicleMaps, created by {@code AbstractChronicleMapBuilder}") + * currently doesn't support resizing. That is why you should always configure {@linkplain + * #entries(long) number of entries} you are going to insert into the created map at most. See {@link + * #entries(long)} method documentation for more information on this.

{@code ChronicleMap} allocates + * memory by equally sized chunks. This size is called {@linkplain #entrySize(int) entry size}, you are + * strongly recommended to configure it to achieve least memory consumption and best speed. See {@link + * #entrySize(int)} method documentation for more information on this.

* * @param key type of the maps, produced by this builder * @param value type of the maps, produced by this builder @@ -205,9 +204,9 @@ public abstract class AbstractChronicleMapBuilder - * (Note that 10 is chosen as key size in bytes despite strings in Java are UTF-16 encoded (and - * each character takes 2 bytes on-heap), because default off-heap {@link String} encoding is - * UTF-8 in {@code ChronicleMap}.) + * (Note that 10 is chosen as key size in bytes despite strings in Java are UTF-16 encoded (and each + * character takes 2 bytes on-heap), because default off-heap {@link String} encoding is UTF-8 in {@code + * ChronicleMap}.) * * @see #constantKeySizeBySample(Object) * @see #entrySize(int) @@ -270,11 +269,11 @@ public abstract class AbstractChronicleMapBuilderIn fully default case you can expect entry size to be about 256 bytes. But it is strongly - * recommended always to configure {@linkplain #keySize(int) key size} and {@linkplain - * #valueSize(int) value size}, if they couldn't be derived statically.

If entry size is - * not configured explicitly by calling this method, it is computed based on {@linkplain - * #metaDataBytes(int) meta data bytes}, plus {@linkplain #keySize(int) key size}, plus - * {@linkplain #valueSize(int) value size}, plus a few bytes required by implementations.

+ * recommended always to configure {@linkplain #keySize(int) key size} and {@linkplain #valueSize(int) + * value size}, if they couldn't be derived statically.

If entry size is not configured explicitly + * by calling this method, it is computed based on {@linkplain #metaDataBytes(int) meta data bytes}, plus + * {@linkplain #keySize(int) key size}, plus {@linkplain #valueSize(int) value size}, plus a few bytes + * required by implementations.

* * @see #entries(long) */ @@ -468,20 +467,18 @@ public abstract class AbstractChronicleMapBuilder{@link Map#put(Object, Object) Map.put()} returns the previous value, functionality which - * is rarely used but fairly cheap for {@link HashMap}. In the case, for an off heap collection, - * it has to create a new object and deserialize the data from off-heap memory. It's expensive - * for something you probably don't use.

By default, of cause, {@code ChronicleMap} - * conforms the general {@code Map} contract and returns the previous mapped value on {@code - * put()} calls.

+ *

{@link Map#put(Object, Object) Map.put()} returns the previous value, functionality which is rarely + * used but fairly cheap for {@link HashMap}. In the case, for an off heap collection, it has to create a + * new object and deserialize the data from off-heap memory. It's expensive for something you probably + * don't use.

By default, of cause, {@code ChronicleMap} conforms the general {@code Map} contract + * and returns the previous mapped value on {@code put()} calls.

* * @param putReturnsNull {@code true} if you want {@link ChronicleMap#put(Object, Object) - * ChronicleMap.put()} to not return the value that was replaced but - * instead return {@code null} + * ChronicleMap.put()} to not return the value that was replaced but instead return + * {@code null} * @return an instance of the map builder back * @see #removeReturnsNull(boolean) */ @@ -495,17 +492,17 @@ public abstract class AbstractChronicleMapBuilder{@link Map#remove(Object) Map.remove()} returns the previous value, functionality which is - * rarely used but fairly cheap for {@link HashMap}. In the case, for an off heap collection, it - * has to create a new object and deserialize the data from off-heap memory. It's expensive for - * something you probably don't use.

+ *

{@link Map#remove(Object) Map.remove()} returns the previous value, functionality which is rarely + * used but fairly cheap for {@link HashMap}. In the case, for an off heap collection, it has to create a + * new object and deserialize the data from off-heap memory. It's expensive for something you probably + * don't use.

* * @param removeReturnsNull {@code true} if you want {@link ChronicleMap#remove(Object) - * ChronicleMap.remove()} to not return the value of the removed entry - * but instead return {@code null} + * ChronicleMap.remove()} to not return the value of the removed entry but + * instead return {@code null} * @return an instance of the map builder back * @see #putReturnsNull(boolean) */ @@ -650,19 +647,18 @@ public abstract class AbstractChronicleMapBuilderDefault value deserialization factory is {@link NewInstanceObjectFactory}, which creates a - * new value instance using {@link Class#newInstance()} default constructor. You could provide - * an {@link AllocateInstanceObjectFactory}, which uses {@code Unsafe.allocateInstance(Class)} - * (you might want to do this for better performance or if you don't want to initialize fields), - * or a factory which calls a value class constructor with some arguments, or a factory which - * internally delegates to instance pool or {@link ThreadLocal}, to reduce allocations.

+ *

Default value deserialization factory is {@link NewInstanceObjectFactory}, which creates a new value + * instance using {@link Class#newInstance()} default constructor. You could provide an {@link + * AllocateInstanceObjectFactory}, which uses {@code Unsafe.allocateInstance(Class)} (you might want to do + * this for better performance or if you don't want to initialize fields), or a factory which calls a + * value class constructor with some arguments, or a factory which internally delegates to instance pool + * or {@link ThreadLocal}, to reduce allocations.

* - * @param valueDeserializationFactory the value factory used to produce instances to deserialize - * data in + * @param valueDeserializationFactory the value factory used to produce instances to deserialize data in * @return this builder back */ public B valueDeserializationFactory(@NotNull ObjectFactory valueDeserializationFactory) { @@ -680,8 +676,8 @@ public abstract class AbstractChronicleMapBuilderThis configuration overrides any previous {@link #defaultValueProvider(DefaultValueProvider)} * configuration to this {@code AbstractChronicleMapBuilder}.

@@ -703,8 +699,8 @@ public abstract class AbstractChronicleMapBuilderThis configuration overrides any previous {@link #defaultValue(Object)} configuration to - * this {@code AbstractChronicleMapBuilder}.

+ *

This configuration overrides any previous {@link #defaultValue(Object)} configuration to this {@code + * AbstractChronicleMapBuilder}.

* * @param defaultValueProvider the strategy to obtain a default value by the absent key * @return this builder object back @@ -754,6 +750,13 @@ public abstract class AbstractChronicleMapBuilder{@code ChronicleMapBuilder} is mutable, see a note in {@link ChronicleHashBuilder} interface * documentation. @@ -104,9 +107,9 @@ public class ChronicleSetBuilder * .keySize(10) * .create();}
* - *

(Note that 10 is chosen as key size in bytes despite strings in Java are UTF-16 encoded - * (and each character takes 2 bytes on-heap), because default off-heap {@link String} encoding - * is UTF-8 in {@code ChronicleSet}.) + *

(Note that 10 is chosen as key size in bytes despite strings in Java are UTF-16 encoded (and each + * character takes 2 bytes on-heap), because default off-heap {@link String} encoding is UTF-8 in {@code + * ChronicleSet}.) * * @see #constantKeySizeBySample(Object) * @see #entrySize(int) @@ -136,13 +139,13 @@ public class ChronicleSetBuilder /** * {@inheritDoc} * - *

In fully default case you can expect entry size to be about 120-130 bytes. But it is - * strongly recommended always to configure {@linkplain #keySize(int) key size}, if they - * couldn't be derived statically. + *

In fully default case you can expect entry size to be about 120-130 bytes. But it is strongly + * recommended always to configure {@linkplain #keySize(int) key size}, if they couldn't be derived + * statically. * *

If entry size is not configured explicitly by calling this method, it is computed based on - * {@linkplain #metaDataBytes(int) meta data bytes}, plus {@linkplain #keySize(int) key size}, - * plus a few bytes required by implementations. + * {@linkplain #metaDataBytes(int) meta data bytes}, plus {@linkplain #keySize(int) key size}, plus a few + * bytes required by implementations. */ @Override public ChronicleSetBuilder entrySize(int entrySize) { @@ -245,10 +248,10 @@ public class ChronicleSetBuilder /** * {@inheritDoc} * - *

Actually this is just a convenience method supporting key marshaller configurations, made - * initially during {@link #of(Class)} call. Because if you {@linkplain - * #keyMarshaller(BytesMarshaller) configure} own custom key marshaller, this method doesn't - * take any effect on the maps constructed by this builder. + *

Actually this is just a convenience method supporting key marshaller configurations, made initially + * during {@link #of(Class)} call. Because if you {@linkplain #keyMarshaller(BytesMarshaller) configure} + * own custom key marshaller, this method doesn't take any effect on the maps constructed by this + * builder. * * @see #of(Class) */ @@ -277,6 +280,12 @@ public class ChronicleSetBuilder return this; } + @Override + public ChronicleSetBuilder replication(byte identifier) { + chronicleMapBuilder.replication(identifier); + return this; + } + @Override public StatelessClientConfig> statelessClient( InetSocketAddress remoteAddress) { diff --git a/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationBootStrapTest.java b/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationBootStrapTest.java index 6baa3c50a..041c066b4 100644 --- a/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationBootStrapTest.java +++ b/src/test/java/net/openhft/chronicle/map/TCPSocketReplicationBootStrapTest.java @@ -89,8 +89,6 @@ public class TCPSocketReplicationBootStrapTest { map1 = newTcpSocketShmIntString((byte) 1, 8068, new InetSocketAddress("localhost", 8067)); - Thread.sleep(1); - File persistenceFile = getPersistenceFile(); final ReplicatedChronicleMap map2a = (ReplicatedChronicleMap) @@ -107,7 +105,6 @@ public class TCPSocketReplicationBootStrapTest { } while (lastModificationTime == 0); map2a.close(); - // Thread.sleep(1); { // restart map 2 but does not connect it to map1 @@ -118,8 +115,6 @@ public class TCPSocketReplicationBootStrapTest { map2b.close(); } - // Thread.sleep(1); - // now restart map2a and doConnect it to map1, map1 should bootstrap the missing entry map2 = newTcpSocketShmBuilder(Integer.class, CharSequence.class, (byte) 2, 8067).createPersistedTo(persistenceFile);