diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleSetBuilder.java b/src/main/java/net/openhft/chronicle/map/ChronicleSetBuilder.java index fa593bc40..91bccbd0e 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleSetBuilder.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleSetBuilder.java @@ -23,30 +23,34 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; -import java.util.Collections; +import java.io.Serializable; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; import java.util.Set; import java.util.concurrent.TimeUnit; import static net.openhft.chronicle.map.Objects.builderEquals; -public class ChronicleSetBuilder implements Cloneable { +public class ChronicleSetBuilder implements Cloneable { - ChronicleMapBuilder chronicleMapBuilder; + private ChronicleMapBuilder chronicleMapBuilder; - ChronicleSetBuilder(Class keyClass) { - chronicleMapBuilder = new ChronicleMapBuilder(keyClass, Boolean.class); + ChronicleSetBuilder(Class keyClass) { + chronicleMapBuilder = new ChronicleMapBuilder(keyClass, Boolean.class); chronicleMapBuilder.constantValueSizeBySample(Boolean.TRUE); } public static ChronicleSetBuilder of(Class keyClass) { - return new ChronicleSetBuilder(keyClass); + return new ChronicleSetBuilder(keyClass); } + @Override - public ChronicleSetBuilder clone() { + public ChronicleSetBuilder clone() { try { @SuppressWarnings("unchecked") - final ChronicleSetBuilder result = (ChronicleSetBuilder) super.clone(); + final ChronicleSetBuilder result = (ChronicleSetBuilder) super.clone(); result.chronicleMapBuilder = chronicleMapBuilder.clone(); return result; } catch (CloneNotSupportedException e) { @@ -55,7 +59,7 @@ public class ChronicleSetBuilder implements Cloneable { } - public ChronicleSetBuilder actualSegments(int actualSegments) { + public ChronicleSetBuilder actualSegments(int actualSegments) { chronicleMapBuilder.actualSegments(actualSegments); return this; } @@ -70,7 +74,7 @@ public class ChronicleSetBuilder implements Cloneable { * @param minSegments the minimum number of segments in maps, constructed by this builder * @return this builder object back */ - public ChronicleSetBuilder minSegments(int minSegments) { + public ChronicleSetBuilder minSegments(int minSegments) { chronicleMapBuilder.minSegments(minSegments); return this; } @@ -80,7 +84,7 @@ public class ChronicleSetBuilder implements Cloneable { } - public ChronicleSetBuilder actualElementsPerSegment(int actualEntriesPerSegment) { + public ChronicleSetBuilder actualElementsPerSegment(int actualEntriesPerSegment) { chronicleMapBuilder.actualEntriesPerSegment(actualEntriesPerSegment); return this; } @@ -110,7 +114,7 @@ public class ChronicleSetBuilder implements Cloneable { * @return this {@code ChronicleSetBuilder} back * @see #constantElementsSizeBySample(Object) */ - public ChronicleSetBuilder elementSize(int elementSize) { + public ChronicleSetBuilder elementSize(int elementSize) { chronicleMapBuilder.keySize(elementSize); return this; } @@ -135,7 +139,7 @@ public class ChronicleSetBuilder implements Cloneable { * @param element the sample element * @return this builder back */ - public ChronicleSetBuilder constantElementsSizeBySample(K element) { + public ChronicleSetBuilder constantElementsSizeBySample(E element) { chronicleMapBuilder.constantKeySizeBySample(element); return this; } @@ -151,7 +155,7 @@ public class ChronicleSetBuilder implements Cloneable { * @param alignment the new alignment of the seta constructed by this builder * @return this {@code ChronicleSetBuilder} back */ - public ChronicleSetBuilder alignment(Alignment alignment) { + public ChronicleSetBuilder alignment(Alignment alignment) { chronicleMapBuilder.entryAndValueAlignment(alignment); return this; } @@ -168,7 +172,7 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.entryAndValueAlignment(); } - public ChronicleSetBuilder elements(long entries) { + public ChronicleSetBuilder elements(long entries) { chronicleMapBuilder.entries(entries); return this; } @@ -177,7 +181,7 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.entries(); } - public ChronicleSetBuilder replicas(int replicas) { + public ChronicleSetBuilder replicas(int replicas) { chronicleMapBuilder.replicas(replicas); return this; } @@ -193,7 +197,7 @@ public class ChronicleSetBuilder implements Cloneable { * @param transactional if the built map should be transactional * @return this {@code ChronicleMapBuilder} back */ - public ChronicleSetBuilder transactional(boolean transactional) { + public ChronicleSetBuilder transactional(boolean transactional) { chronicleMapBuilder.transactional(transactional); return this; } @@ -202,7 +206,7 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.transactional(); } - public ChronicleSetBuilder lockTimeOut(long lockTimeOut, TimeUnit unit) { + public ChronicleSetBuilder lockTimeOut(long lockTimeOut, TimeUnit unit) { chronicleMapBuilder.lockTimeOut(lockTimeOut, unit); return this; } @@ -212,7 +216,7 @@ public class ChronicleSetBuilder implements Cloneable { } - public ChronicleSetBuilder errorListener(MapErrorListener errorListener) { + public ChronicleSetBuilder errorListener(MapErrorListener errorListener) { chronicleMapBuilder.errorListener(errorListener); return this; } @@ -226,12 +230,12 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.largeSegments(); } - public ChronicleSetBuilder largeSegments(boolean largeSegments) { + public ChronicleSetBuilder largeSegments(boolean largeSegments) { chronicleMapBuilder.largeSegments(largeSegments); return this; } - public ChronicleSetBuilder metaDataBytes(int metaDataBytes) { + public ChronicleSetBuilder metaDataBytes(int metaDataBytes) { chronicleMapBuilder.metaDataBytes(metaDataBytes); return this; } @@ -269,17 +273,17 @@ public class ChronicleSetBuilder implements Cloneable { return toString().hashCode(); } - public ChronicleSetBuilder addReplicator(Replicator replicator) { + public ChronicleSetBuilder addReplicator(Replicator replicator) { chronicleMapBuilder.addReplicator(replicator); return this; } - public ChronicleSetBuilder setReplicators(Replicator... replicators) { + public ChronicleSetBuilder setReplicators(Replicator... replicators) { chronicleMapBuilder.setReplicators(replicators); return this; } - public ChronicleSetBuilder timeProvider(TimeProvider timeProvider) { + public ChronicleSetBuilder timeProvider(TimeProvider timeProvider) { chronicleMapBuilder.timeProvider(timeProvider); return this; } @@ -292,7 +296,7 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.bytesMarshallerFactory(); } - public ChronicleSetBuilder bytesMarshallerFactory(BytesMarshallerFactory bytesMarshallerFactory) { + public ChronicleSetBuilder bytesMarshallerFactory(BytesMarshallerFactory bytesMarshallerFactory) { chronicleMapBuilder.bytesMarshallerFactory(bytesMarshallerFactory); return this; } @@ -301,7 +305,7 @@ public class ChronicleSetBuilder implements Cloneable { return chronicleMapBuilder.objectSerializer(); } - public ChronicleSetBuilder objectSerializer(ObjectSerializer objectSerializer) { + public ChronicleSetBuilder objectSerializer(ObjectSerializer objectSerializer) { chronicleMapBuilder.objectSerializer(objectSerializer); return this; } @@ -309,12 +313,12 @@ public class ChronicleSetBuilder implements Cloneable { /** * For testing */ - ChronicleSetBuilder forceReplicatedImpl() { + ChronicleSetBuilder forceReplicatedImpl() { chronicleMapBuilder.forceReplicatedImpl(); return this; } - public ChronicleSetBuilder keyMarshaller(@NotNull BytesMarshaller keyMarshaller) { + public ChronicleSetBuilder keyMarshaller(@NotNull BytesMarshaller keyMarshaller) { chronicleMapBuilder.keyMarshaller(keyMarshaller); return this; } @@ -327,22 +331,109 @@ public class ChronicleSetBuilder implements Cloneable { * * @return this builder back */ - public ChronicleSetBuilder immutableKeys() { + public ChronicleSetBuilder immutableKeys() { chronicleMapBuilder.immutableKeys(); return this; } - public Set create(File file) throws IOException { - final ChronicleMap map = chronicleMapBuilder.create(file); - return Collections.newSetFromMap(map); + public ChronicleSet create(File file) throws IOException { + final ChronicleMap map = chronicleMapBuilder.create(file); + return new SetFromMap(map); } - public Set create() throws IOException { - final ChronicleMap map = chronicleMapBuilder.create(); - return Collections.newSetFromMap(map); + public ChronicleSet create() throws IOException { + final ChronicleMap map = chronicleMapBuilder.create(); + return new SetFromMap(map); } + private static class SetFromMap extends AbstractSet + implements ChronicleSet, Serializable { + + private final ChronicleMap m; // The backing map + private transient Set s; // Its keySet + + SetFromMap(ChronicleMap map) { + if (!map.isEmpty()) + throw new IllegalArgumentException("Map is non-empty"); + m = map; + s = map.keySet(); + } + + public void clear() { + m.clear(); + } + + public int size() { + return m.size(); + } + + public boolean isEmpty() { + return m.isEmpty(); + } + + public boolean contains(Object o) { + return m.containsKey(o); + } + + public boolean remove(Object o) { + return m.remove(o) != null; + } + + public boolean add(E e) { + return m.put(e, Boolean.TRUE) == null; + } + + public Iterator iterator() { + return s.iterator(); + } + + public Object[] toArray() { + return s.toArray(); + } + + public T[] toArray(T[] a) { + return s.toArray(a); + } + + public String toString() { + return s.toString(); + } + + public int hashCode() { + return s.hashCode(); + } + + public boolean equals(Object o) { + return o == this || s.equals(o); + } + + public boolean containsAll(Collection c) { + return s.containsAll(c); + } + + public boolean removeAll(Collection c) { + return s.removeAll(c); + } + + public boolean retainAll(Collection c) { + return s.retainAll(c); + } + // addAll is the only inherited implementation + + private static final long serialVersionUID = 2454657854757543876L; + + private void readObject(java.io.ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + s = m.keySet(); + } + + @Override + public long longSize() { + return m.longSize(); + } + } }