Add ChronicleSetBuilder.entryOperations() and .remoteOperations() interception configuration methods; Rename SetRemoteOperations.insert() to put(), for consistency with MapRemoteOperations

This commit is contained in:
leventov
2015-11-28 23:20:29 +03:00
parent ec3bd9447e
commit bfa9988551
30 changed files with 464 additions and 99 deletions
@@ -25,6 +25,7 @@ import net.openhft.chronicle.hash.impl.stage.entry.HashLookupSearch;
import net.openhft.chronicle.hash.impl.stage.entry.SegmentStages;
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.hash.serialization.DataAccess;
import net.openhft.chronicle.set.SetEntry;
import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@@ -33,7 +34,7 @@ import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.PRESENT;
@Staged
public abstract class HashQuery<K> implements HashEntry<K> {
public abstract class HashQuery<K> implements SetEntry<K> {
@StageRef public VanillaChronicleHashHolder<K> hh;
@StageRef public SegmentStages s;
@@ -16,6 +16,7 @@
package net.openhft.chronicle.map;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.HashContext;
import net.openhft.chronicle.hash.Data;
@@ -35,9 +36,7 @@ public interface MapContext<K, V, R>
* Returns the accessed {@code ChronicleMap}. Synonym to {@link #map()}.
*/
@Override
default ChronicleMap<K, V> hash() {
return map();
}
ChronicleHash<K, ?, ?, ?> hash();
/**
* Returns the accessed {@code ChronicleMap}. Synonym to {@link #hash()}.
@@ -30,6 +30,7 @@ import net.openhft.chronicle.map.impl.*;
import net.openhft.chronicle.map.impl.CompiledMapIterationContext;
import net.openhft.chronicle.map.impl.CompiledMapQueryContext;
import net.openhft.chronicle.map.impl.ret.InstanceReturnValue;
import net.openhft.chronicle.set.ChronicleSet;
import net.openhft.chronicle.values.Values;
import net.openhft.chronicle.wire.WireIn;
import net.openhft.chronicle.wire.WireOut;
@@ -72,6 +73,9 @@ public class VanillaChronicleMap<K, V, R>
transient boolean removeReturnsNull;
transient Set<Entry<K, V>> entrySet;
/** @see net.openhft.chronicle.set.SetFromMap */
public transient ChronicleSet<K> chronicleSet;
public transient MapEntryOperations<K, V, R> entryOperations;
public transient MapMethods<K, V, R> methods;
@@ -58,7 +58,6 @@ import net.openhft.sg.Staged;
MapAbsent.class,
DefaultValue.class,
ValueBytesInterop.class,
MapAbsentHolder.class,
QueryAlloc.class,
},
@@ -67,7 +67,6 @@ import net.openhft.sg.Staged;
ReplicatedMapAbsent.class,
DefaultValue.class,
ValueBytesInterop.class,
ReplicatedMapAbsentHolder.class,
ReplicationUpdate.class,
ReplicatedInput.class,
@@ -20,6 +20,7 @@ import net.openhft.chronicle.hash.impl.VanillaChronicleHash;
import net.openhft.chronicle.hash.impl.VanillaChronicleHashHolder;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.VanillaChronicleMap;
import net.openhft.chronicle.set.ChronicleSet;
public interface VanillaChronicleMapHolder<K, V, R> extends VanillaChronicleHashHolder<K> {
@@ -33,4 +34,6 @@ public interface VanillaChronicleMapHolder<K, V, R> extends VanillaChronicleHash
default ChronicleMap<K, V> map() {
return m();
}
ChronicleSet<K> set();
}
@@ -47,7 +47,7 @@ public abstract class MapSegmentIteration<K, V, R> extends HashSegmentIteration<
@NotNull
@Override
public MapContext<K, V, ?> context() {
public WrappedValueInstanceValueHolder<K, V, ?> context() {
return wrappedValueInstanceValueHolder;
}
}
@@ -20,22 +20,23 @@ import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.replication.ReplicableEntryDelegating;
import net.openhft.chronicle.hash.replication.ReplicableEntry;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapContext;
import net.openhft.chronicle.map.impl.stage.entry.ReplicatedMapEntryStages;
import net.openhft.chronicle.map.impl.stage.map.WrappedValueInstanceValueHolder;
import net.openhft.chronicle.set.SetAbsentEntry;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@Staged
public class ReplicatedMapAbsentDelegatingForIteration<K, V>
implements MapAbsentEntry<K, V>, ReplicableEntryDelegating {
implements MapAbsentEntry<K, V>, SetAbsentEntry<K>, ReplicableEntryDelegating {
@StageRef ReplicatedMapSegmentIteration<K, V, ?> delegate;
@StageRef ReplicatedMapEntryStages<K, V> e;
@NotNull
@Override
public MapContext<K, V, ?> context() {
public WrappedValueInstanceValueHolder<K, V, ?> context() {
return delegate.context();
}
@@ -44,6 +45,11 @@ public class ReplicatedMapAbsentDelegatingForIteration<K, V>
delegate.doInsert(value);
}
@Override
public void doInsert() {
delegate.doInsert();
}
@NotNull
@Override
public Data<V> defaultValue() {
@@ -19,14 +19,16 @@ package net.openhft.chronicle.map.impl.stage.iter;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.ReplicatedHashSegmentContext;
import net.openhft.chronicle.hash.impl.CompactOffHeapLinearHashTable;
import net.openhft.chronicle.hash.impl.VanillaChronicleHashHolder;
import net.openhft.chronicle.hash.replication.ReplicableEntry;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapEntry;
import net.openhft.chronicle.map.impl.ReplicatedIterationContext;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.chronicle.map.impl.stage.data.DummyValueZeroData;
import net.openhft.chronicle.map.impl.stage.entry.ReplicatedMapEntryStages;
import net.openhft.chronicle.map.impl.stage.replication.ReplicationUpdate;
import net.openhft.chronicle.set.DummyValueData;
import net.openhft.chronicle.set.SetAbsentEntry;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@@ -36,9 +38,9 @@ import java.util.function.Predicate;
@Staged
public abstract class ReplicatedMapSegmentIteration<K, V, R> extends MapSegmentIteration<K, V, R>
implements ReplicatedIterationContext<K, V, R>, ReplicableEntry,
ReplicatedHashSegmentContext<K, MapEntry<K, V>>, MapAbsentEntry<K, V> {
ReplicatedHashSegmentContext<K, MapEntry<K, V>>, MapAbsentEntry<K, V>, SetAbsentEntry<K> {
@StageRef VanillaChronicleHashHolder<?> hh;
@StageRef VanillaChronicleMapHolder<K, V, R> mh;
@StageRef ReplicatedMapEntryStages<K, V> e;
@StageRef ReplicationUpdate<K> ru;
@StageRef DummyValueZeroData<V> dummyValue;
@@ -73,7 +75,7 @@ public abstract class ReplicatedMapSegmentIteration<K, V, R> extends MapSegmentI
return true;
boolean interrupted = false;
long startPos = 0L;
CompactOffHeapLinearHashTable hashLookup = hh.h().hashLookup;
CompactOffHeapLinearHashTable hashLookup = mh.h().hashLookup;
while (!hashLookup.empty(hashLookup.readEntry(s.tierBaseAddr, startPos))) {
startPos = hashLookup.step(startPos);
}
@@ -155,4 +157,11 @@ public abstract class ReplicatedMapSegmentIteration<K, V, R> extends MapSegmentI
"Entry is present in the map when doInsert() is called");
}
}
@Override
public void doInsert() {
if (mh.set() == null)
throw new IllegalStateException("Called SetAbsentEntry.doInsert() from Map context");
doInsert((Data<V>) DummyValueData.INSTANCE);
}
}
@@ -16,11 +16,13 @@
package net.openhft.chronicle.map.impl.stage.map;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.impl.stage.hash.Chaining;
import net.openhft.chronicle.hash.impl.stage.hash.ChainingInterface;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.ReplicatedChronicleMap;
import net.openhft.chronicle.map.impl.ReplicatedChronicleMapHolder;
import net.openhft.chronicle.set.ChronicleSet;
import net.openhft.sg.Staged;
@Staged
@@ -49,4 +51,13 @@ public class ReplicatedChronicleMapHolderImpl<K, V, R> extends Chaining
public ChronicleMap<K, V> map() {
return m();
}
@Override
public ChronicleSet<K> set() {
return m.chronicleSet;
}
public ChronicleHash<K, ?, ?, ?> hash() {
return set() != null ? set() : map();
}
}
@@ -16,11 +16,13 @@
package net.openhft.chronicle.map.impl.stage.map;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.impl.stage.hash.Chaining;
import net.openhft.chronicle.hash.impl.stage.hash.ChainingInterface;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.VanillaChronicleMap;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.chronicle.set.ChronicleSet;
import net.openhft.sg.Staged;
@Staged
@@ -49,4 +51,13 @@ public class VanillaChronicleMapHolderImpl<K, V, R> extends Chaining
public ChronicleMap<K, V> map() {
return m();
}
@Override
public ChronicleSet<K> set() {
return m.chronicleSet;
}
public ChronicleHash<K, ?, ?, ?> hash() {
return set() != null ? set() : map();
}
}
@@ -20,11 +20,13 @@ import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.map.MapContext;
import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceDataHolder;
import net.openhft.chronicle.set.SetContext;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@Staged
public abstract class WrappedValueInstanceValueHolder<K, V, R> implements MapContext<K, V, R> {
public abstract class WrappedValueInstanceValueHolder<K, V, R>
implements MapContext<K, V, R>, SetContext<K, R> {
@StageRef CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef
@@ -17,17 +17,12 @@
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.impl.MapAbsentEntryHolder;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import net.openhft.chronicle.set.SetAbsentEntry;
import org.jetbrains.annotations.NotNull;
@Staged
public class MapAbsentHolder<K, V> implements MapAbsentEntryHolder<K, V> {
@StageRef MapAbsent<K, V> ab;
public interface Absent<K, V> extends MapAbsentEntry<K, V>, SetAbsentEntry<K> {
@NotNull
@Override
public MapAbsentEntry<K, V> absent() {
return ab;
}
MapAndSetContext<K, V, ?> context();
}
@@ -23,8 +23,10 @@ import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation;
import net.openhft.chronicle.hash.impl.stage.query.HashQuery.EntryPresence;
import net.openhft.chronicle.hash.impl.stage.query.KeySearch;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapContext;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.chronicle.set.DummyValueData;
import net.openhft.chronicle.set.SetAbsentEntry;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +34,7 @@ import org.jetbrains.annotations.NotNull;
import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.PRESENT;
@Staged
public abstract class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
public abstract class MapAbsent<K, V> implements Absent<K, V> {
@StageRef public KeySearch<K> ks;
@StageRef MapQuery<K, V, ?> q;
@@ -40,6 +42,7 @@ public abstract class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
@StageRef public HashLookupSearch hashLookupSearch;
@StageRef public CheckOnEachPublicOperation checkOnEachPublicOperation;
@StageRef public SegmentStages s;
@StageRef VanillaChronicleMapHolder<K, V, ?> mh;
void putEntry(Data<V> value) {
assert ks.searchStateAbsent();
@@ -52,7 +55,7 @@ public abstract class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
@NotNull
@Override
public MapContext<K, V, ?> context() {
public MapQuery<K, V, ?> context() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return q;
}
@@ -82,4 +85,11 @@ public abstract class MapAbsent<K, V> implements MapAbsentEntry<K, V> {
"Entry is present in the map when doInsert() is called");
}
}
@Override
public void doInsert() {
if (mh.set() == null)
throw new IllegalStateException("Called SetAbsentEntry.doInsert() from Map context");
doInsert((Data<V>) DummyValueData.INSTANCE);
}
}
@@ -14,11 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.chronicle.map.impl;
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapContext;
import net.openhft.chronicle.set.SetContext;
public interface MapAbsentEntryHolder<K, V> {
MapAbsentEntry<K, V> absent();
public interface MapAndSetContext<K, V, R> extends MapContext<K, V, R>, SetContext<K, R> {
}
@@ -22,15 +22,13 @@ import net.openhft.chronicle.hash.impl.stage.query.KeySearch;
import net.openhft.chronicle.hash.impl.stage.query.SearchAllocatedChunks;
import net.openhft.chronicle.hash.serialization.DataAccess;
import net.openhft.chronicle.map.ExternalMapQueryContext;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapContext;
import net.openhft.chronicle.map.MapEntry;
import net.openhft.chronicle.map.impl.MapAbsentEntryHolder;
import net.openhft.chronicle.map.impl.QueryContextInterface;
import net.openhft.chronicle.map.impl.VanillaChronicleMapHolder;
import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages;
import net.openhft.chronicle.map.impl.stage.ret.DefaultReturnValue;
import net.openhft.chronicle.map.impl.stage.ret.UsingReturnValue;
import net.openhft.chronicle.set.ExternalSetQueryContext;
import net.openhft.sg.Stage;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@@ -42,7 +40,7 @@ import static net.openhft.chronicle.hash.impl.stage.query.KeySearch.SearchState.
@Staged
public abstract class MapQuery<K, V, R> extends HashQuery<K>
implements MapEntry<K, V>, ExternalMapQueryContext<K, V, R>,
QueryContextInterface<K, V, R> {
ExternalSetQueryContext<K, R>, QueryContextInterface<K, V, R>, MapAndSetContext<K, V, R> {
@StageRef VanillaChronicleMapHolder<K, V, R> mh;
@StageRef MapEntryStages<K, V> e;
@@ -53,7 +51,7 @@ public abstract class MapQuery<K, V, R> extends HashQuery<K>
@StageRef public DefaultReturnValue<V> defaultReturnValue;
@StageRef public UsingReturnValue<V> usingReturnValue;
@StageRef public MapAbsentEntryHolder<K, V> absent;
@StageRef public MapAbsent<K, V> absent;
final DataAccess<V> innerInputValueDataAccess = mh.m().valueDataAccess.copy();
@@ -76,16 +74,16 @@ public abstract class MapQuery<K, V, R> extends HashQuery<K>
}
@Override
public MapEntry<K, V> entry() {
public MapQuery<K, V, R> entry() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return entryPresent() ? this : null;
}
@Nullable
@Override
public MapAbsentEntry<K, V> absentEntry() {
public Absent<K, V> absentEntry() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return entryPresent() ? null : absent.absent();
return entryPresent() ? null : absent;
}
protected void putPrefix() {
@@ -120,7 +118,7 @@ public abstract class MapQuery<K, V, R> extends HashQuery<K>
@NotNull
@Override
public MapContext<K, V, ?> context() {
public MapQuery<K, V, R> context() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return this;
}
@@ -17,23 +17,26 @@
package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.MapContext;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.NotNull;
@Staged
public class ReplicatedMapAbsentDelegating<K, V> implements MapAbsentEntry<K, V> {
public class ReplicatedMapAbsentDelegating<K, V> implements Absent<K, V> {
@StageRef ReplicatedMapAbsent<K, V> delegate;
@NotNull
@Override
public MapContext<K, V, ?> context() {
public MapQuery<K, V, ?> context() {
return delegate.context();
}
@Override
public void doInsert() {
delegate.doInsert();
}
@Override
public void doInsert(Data<V> value) {
delegate.doInsert(value);
@@ -1,33 +0,0 @@
/*
* 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.impl.stage.query;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.impl.MapAbsentEntryHolder;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
@Staged
public class ReplicatedMapAbsentHolder<K, V> implements MapAbsentEntryHolder<K, V> {
@StageRef ReplicatedMapAbsent<K, V> ab;
@Override
public MapAbsentEntry<K, V> absent() {
return ab;
}
}
@@ -18,19 +18,21 @@ package net.openhft.chronicle.map.impl.stage.query;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.replication.ReplicableEntry;
import net.openhft.chronicle.map.MapAbsentEntry;
import net.openhft.chronicle.map.impl.stage.data.DummyValueZeroData;
import net.openhft.chronicle.map.impl.stage.entry.ReplicatedMapEntryStages;
import net.openhft.chronicle.map.impl.stage.replication.ReplicationUpdate;
import net.openhft.chronicle.map.replication.MapRemoteQueryContext;
import net.openhft.chronicle.map.replication.MapReplicableEntry;
import net.openhft.chronicle.set.replication.SetRemoteQueryContext;
import net.openhft.chronicle.set.replication.SetReplicableEntry;
import net.openhft.sg.StageRef;
import net.openhft.sg.Staged;
import org.jetbrains.annotations.Nullable;
@Staged
public abstract class ReplicatedMapQuery<K, V, R> extends MapQuery<K, V, R>
implements MapRemoteQueryContext<K, V, R>, ReplicableEntry {
implements MapRemoteQueryContext<K, V, R>, SetRemoteQueryContext<K, R>,
ReplicableEntry, MapReplicableEntry<K, V>, SetReplicableEntry<K> {
@StageRef ReplicatedMapEntryStages<K, V> e;
@StageRef ReplicationUpdate ru;
@@ -39,7 +41,7 @@ public abstract class ReplicatedMapQuery<K, V, R> extends MapQuery<K, V, R>
@Nullable
@Override
public MapAbsentEntry<K, V> absentEntry() {
public Absent<K, V> absentEntry() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
if (entryPresent()) {
return null;
@@ -48,7 +50,7 @@ public abstract class ReplicatedMapQuery<K, V, R> extends MapQuery<K, V, R>
return absentDelegating;
} else {
assert e.entryDeleted();
return absent.absent();
return absent;
}
}
}
@@ -61,8 +63,9 @@ public abstract class ReplicatedMapQuery<K, V, R> extends MapQuery<K, V, R>
@StageRef DummyValueZeroData<V> dummyValue;
@Override
public MapReplicableEntry<K, V> entry() {
return (MapReplicableEntry<K, V>) super.entry();
public ReplicatedMapQuery<K, V, R> entry() {
checkOnEachPublicOperation.checkOnEachPublicOperation();
return entryPresent() ? this : null;
}
@Override
@@ -18,6 +18,7 @@ package net.openhft.chronicle.map.replication;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.hash.replication.RemoteOperationContext;
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.ChronicleMapBuilder;
import net.openhft.chronicle.map.MapEntryOperations;
@@ -40,7 +41,7 @@ public interface MapRemoteQueryContext<K, V, R> extends MapQueryContext<K, V, R>
/**
* The value used as a tombstone, for removed entries, to save space. This value has {@linkplain
* SizeMarshaller#minEncodableSize() minimum possible size} for {@linkplain
* SizeMarshaller#minStorableSize()} minimum possible size} for {@linkplain
* ChronicleMapBuilder#valueSizeMarshaller(SizeMarshaller) the configured value size
* marshaller}.
*
@@ -19,12 +19,16 @@ 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.Data;
import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication;
import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
import net.openhft.chronicle.hash.replication.TimeProvider;
import net.openhft.chronicle.hash.serialization.*;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.ChronicleMapBuilder;
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;
@@ -287,6 +291,38 @@ public final class ChronicleSetBuilder<K>
return this;
}
public ChronicleSetBuilder<K> entryOperations(SetEntryOperations<K, ?> entryOperations) {
chronicleMapBuilder.entryOperations(new MapEntryOperations<K, DummyValue, Object>() {
@Override
public Object remove(@NotNull MapEntry<K, DummyValue> entry) {
return entryOperations.remove((SetEntry<K>) entry);
}
@Override
public Object insert(
@NotNull MapAbsentEntry<K, DummyValue> absentEntry, Data<DummyValue> value) {
return entryOperations.insert((SetAbsentEntry<K>) absentEntry);
}
});
return this;
}
public ChronicleSetBuilder<K> remoteOperations(SetRemoteOperations<K, ?> remoteOperations) {
chronicleMapBuilder.remoteOperations(new MapRemoteOperations<K, DummyValue, Object>() {
@Override
public void remove(MapRemoteQueryContext<K, DummyValue, Object> q) {
remoteOperations.remove((SetRemoteQueryContext) q);
}
@Override
public void put(
MapRemoteQueryContext<K, DummyValue, Object> q, Data<DummyValue> newValue) {
remoteOperations.put((SetRemoteQueryContext) q);
}
});
return this;
}
@Override
public ChronicleHashInstanceBuilder<ChronicleSet<K>> instance() {
return new SetInstanceBuilder<>(chronicleMapBuilder.instance());
@@ -295,13 +331,13 @@ public final class ChronicleSetBuilder<K>
@Override
public ChronicleSet<K> create() {
final ChronicleMap<K, DummyValue> map = chronicleMapBuilder.create();
return new SetFromMap<>(map);
return new SetFromMap<>((VanillaChronicleMap<K, DummyValue, ?>) map);
}
@Override
public ChronicleSet<K> createPersistedTo(File file) throws IOException {
ChronicleMap<K, DummyValue> map = chronicleMapBuilder.createPersistedTo(file);
return new SetFromMap<>(map);
return new SetFromMap<>((VanillaChronicleMap<K, DummyValue, ?>) map);
}
/**
@@ -21,9 +21,9 @@ import net.openhft.chronicle.hash.AbstractData;
import net.openhft.chronicle.map.impl.stage.data.ZeroBytesStore;
import org.jetbrains.annotations.Nullable;
class DummyValueData extends AbstractData<DummyValue> {
public class DummyValueData extends AbstractData<DummyValue> {
static final DummyValueData INSTANCE = new DummyValueData();
public static final DummyValueData INSTANCE = new DummyValueData();
private DummyValueData() {}
@@ -17,6 +17,7 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.HashAbsentEntry;
import org.jetbrains.annotations.NotNull;
/**
* Low-level operational context for the situations, when the new key is going to be inserted
@@ -28,6 +29,7 @@ import net.openhft.chronicle.hash.HashAbsentEntry;
* @see SetQueryContext#absentEntry()
*/
public interface SetAbsentEntry<K> extends HashAbsentEntry<K> {
@NotNull
@Override
SetContext<K, ?> context();
@@ -16,6 +16,7 @@
package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.ChronicleHash;
import net.openhft.chronicle.hash.HashContext;
/**
@@ -32,9 +33,7 @@ public interface SetContext<K, R> extends HashContext<K>, SetEntryOperations<K,
* Returns the accessed {@code ChronicleSet}. Synonym to {@link #set()}.
*/
@Override
default ChronicleSet<K> hash() {
return set();
}
ChronicleHash<K, ?, ?, ?> hash();
/**
* Returns the accessed {@code ChronicleSet}. Synonym to {@link #hash()}.
@@ -18,6 +18,7 @@ package net.openhft.chronicle.set;
import net.openhft.chronicle.hash.Data;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.VanillaChronicleMap;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -32,14 +33,20 @@ import java.util.function.Predicate;
import static net.openhft.chronicle.set.DummyValue.DUMMY_VALUE;
/**
* ChronicleSet is implemented through ChronicleMap, with dummy 0-bytes values. This solution
* trades correctness of abstractions for simplicity and minimizing changes before production 3.x
* release.
*/
class SetFromMap<E> extends AbstractSet<E>
implements ChronicleSet<E>, Serializable {
private final ChronicleMap<E, DummyValue> m; // The backing map
private transient Set<E> s; // Its keySet
SetFromMap(ChronicleMap<E, DummyValue> map) {
SetFromMap(VanillaChronicleMap<E, DummyValue, ?> map) {
m = map;
map.chronicleSet = this;
s = map.keySet();
}
@@ -21,6 +21,7 @@ import net.openhft.chronicle.hash.replication.ReplicationChannel;
import net.openhft.chronicle.hash.replication.SingleChronicleHashReplication;
import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig;
import net.openhft.chronicle.map.ChronicleMap;
import net.openhft.chronicle.map.VanillaChronicleMap;
import java.io.File;
import java.io.IOException;
@@ -69,7 +70,7 @@ final class SetInstanceBuilder<E> implements ChronicleHashInstanceBuilder<Chroni
@Override
public synchronized ChronicleSet<E> create() throws IOException {
try {
return new SetFromMap<>(mapBuilder.create());
return new SetFromMap<>((VanillaChronicleMap<E, DummyValue, ?>) mapBuilder.create());
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("A ChronicleMap")) {
throw new IllegalStateException(
@@ -55,7 +55,7 @@ public interface SetRemoteOperations<K, R> {
}
}
default void insert(SetRemoteQueryContext<K, R> q) {
default void put(SetRemoteQueryContext<K, R> q) {
SetReplicableEntry<K> entry = q.entry();
if (entry != null) {
if (decideOnRemoteModification(entry, q) == ACCEPT) {