From 9fe1dab477b4cefeec2fc72529f38f142753008e Mon Sep 17 00:00:00 2001 From: leventov Date: Fri, 24 Jul 2015 20:11:58 +0300 Subject: [PATCH] HCOLL-352 Changed garbage-free Chronicle-Map iterations API from old to new Contexts; Add SegmentContexts API --- .../openhft/chronicle/hash/ChronicleHash.java | 6 +- .../chronicle/hash/ChronicleHashBuilder.java | 2 +- .../openhft/chronicle/hash/HashContext.java | 2 +- .../chronicle/hash/HashSegmentContext.java | 33 +++++ .../hash/impl/ChronicleHashBuilderImpl.java | 2 +- .../hash/impl/VanillaChronicleHash.java | 9 +- .../hash/impl/VanillaChronicleHashHolder.java | 2 +- .../hash/impl/stage/entry/SegmentStages.java | 4 +- .../impl/stage/iter/HashSegmentIteration.java | 10 +- .../chronicle/map/AbstractChronicleMap.java | 28 ++-- .../openhft/chronicle/map/ChronicleMap.java | 7 +- .../chronicle/map/ChronicleMapIterator.java | 35 +++-- .../chronicle/map/MapSegmentContext.java | 25 ++++ .../chronicle/map/ReplicatedChronicleMap.java | 3 +- .../chronicle/map/StatelessChronicleMap.java | 9 +- .../chronicle/map/VanillaChronicleMap.java | 15 +- .../map/impl/IterationContextInterface.java | 16 +-- .../map/impl/MapIterationContext.java | 3 - .../ReplicatedIterationContextInterface.java | 3 +- .../impl/ReplicatedMapIterationContext.java | 3 - .../map/impl/VanillaChronicleMapHolder.java | 2 +- .../DeprecatedMapKeyContextOnIteration.java | 128 ------------------ .../IterationCheckOnEachPublicOperation.java | 2 +- .../impl/stage/iter/MapSegmentIteration.java | 5 +- .../iter/ReplicatedMapSegmentIteration.java | 4 +- .../openhft/chronicle/set/ChronicleSet.java | 3 +- .../net/openhft/chronicle/set/SetFromMap.java | 13 +- .../chronicle/set/SetSegmentContext.java | 25 ++++ .../VanillaChronicleMapConverter.java | 6 +- .../chronicle/map/ReplicationCheckingMap.java | 9 +- .../SimpleMapOperationsListeningTest.java | 4 +- .../jsr166/map/StatelessChronicleMapTest.java | 9 +- 32 files changed, 196 insertions(+), 231 deletions(-) create mode 100644 src/main/java/net/openhft/chronicle/hash/HashSegmentContext.java create mode 100644 src/main/java/net/openhft/chronicle/map/MapSegmentContext.java delete mode 100644 src/main/java/net/openhft/chronicle/map/impl/stage/iter/DeprecatedMapKeyContextOnIteration.java create mode 100644 src/main/java/net/openhft/chronicle/set/SetSegmentContext.java diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHash.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHash.java index 9aa567076..2620b1f07 100644 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHash.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHash.java @@ -33,8 +33,8 @@ import java.util.function.Predicate; * This interface defines common {@link ChronicleMap} and {@link ChronicleSet}, related to off-heap * memory management and file-mapping. Not usable by itself. */ -public interface ChronicleHash, EQC extends ExternalHashQueryContext> - extends Closeable { +public interface ChronicleHash, SC extends HashSegmentContext, + EQC extends ExternalHashQueryContext> extends Closeable { /** * Returns the file this hash container mapped to, i. e. when it is created by * {@link ChronicleHashBuilder#create()} call, or {@code null} if it is purely in-memory, @@ -81,6 +81,8 @@ public interface ChronicleHash, EQC extends ExternalH * @return the context to perform operations with the key */ @NotNull EQC queryContext(Data key); + + SC segmentContext(int segmentIndex); /** * Checks the given predicate on each entry in this {@code ChronicleHash} until all entries diff --git a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java index 9342a98ed..a05e245f7 100755 --- a/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java +++ b/src/main/java/net/openhft/chronicle/hash/ChronicleHashBuilder.java @@ -65,7 +65,7 @@ import java.util.concurrent.TimeUnit; * @param the concrete builder type, i. e. {@link ChronicleMapBuilder} * or {@link ChronicleSetBuilder} */ -public interface ChronicleHashBuilder, +public interface ChronicleHashBuilder, B extends ChronicleHashBuilder> extends Cloneable { /** diff --git a/src/main/java/net/openhft/chronicle/hash/HashContext.java b/src/main/java/net/openhft/chronicle/hash/HashContext.java index a16fcc126..26d6d6445 100644 --- a/src/main/java/net/openhft/chronicle/hash/HashContext.java +++ b/src/main/java/net/openhft/chronicle/hash/HashContext.java @@ -27,5 +27,5 @@ public interface HashContext { /** * Returns the accessed {@code ChronicleHash}. */ - ChronicleHash hash(); + ChronicleHash hash(); } diff --git a/src/main/java/net/openhft/chronicle/hash/HashSegmentContext.java b/src/main/java/net/openhft/chronicle/hash/HashSegmentContext.java new file mode 100644 index 000000000..2773df55d --- /dev/null +++ b/src/main/java/net/openhft/chronicle/hash/HashSegmentContext.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015 Higher Frequency Trading + * + * http://www.higherfrequencytrading.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.chronicle.hash; + +import net.openhft.chronicle.core.io.Closeable; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +public interface HashSegmentContext> extends HashContext, Closeable { + + void forEachSegmentEntry(Consumer action); + + boolean forEachSegmentEntryWhile(Predicate predicate); + + long size(); +} diff --git a/src/main/java/net/openhft/chronicle/hash/impl/ChronicleHashBuilderImpl.java b/src/main/java/net/openhft/chronicle/hash/impl/ChronicleHashBuilderImpl.java index 99578b897..ac3da6e26 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/ChronicleHashBuilderImpl.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/ChronicleHashBuilderImpl.java @@ -22,7 +22,7 @@ import net.openhft.chronicle.hash.ChronicleHashBuilder; import net.openhft.chronicle.hash.serialization.internal.SerializationBuilder; //TODO remove this temporary interface -public interface ChronicleHashBuilderImpl, +public interface ChronicleHashBuilderImpl, B extends ChronicleHashBuilder> extends ChronicleHashBuilder { SerializationBuilder keyBuilder(); 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 e2f488c33..9ae4fff09 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHash.java @@ -16,9 +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.KeyContext; +import net.openhft.chronicle.hash.*; import net.openhft.chronicle.hash.impl.hashlookup.HashLookup; import net.openhft.chronicle.hash.impl.util.BuildVersion; import net.openhft.chronicle.hash.serialization.BytesReader; @@ -44,8 +42,9 @@ import static java.lang.Math.max; import static net.openhft.lang.MemoryUnit.*; public abstract class VanillaChronicleHash, - C extends KeyContext, ECQ extends ExternalHashQueryContext> - implements ChronicleHash, Serializable { + C extends HashEntry, SC extends HashSegmentContext, + ECQ extends ExternalHashQueryContext> + implements ChronicleHash, Serializable { private static final long serialVersionUID = 0L; diff --git a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHashHolder.java b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHashHolder.java index d46d9c137..e5189a4b4 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHashHolder.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/VanillaChronicleHashHolder.java @@ -21,5 +21,5 @@ package net.openhft.chronicle.hash.impl; import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop; public interface VanillaChronicleHashHolder> { - VanillaChronicleHash h(); + VanillaChronicleHash h(); } diff --git a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java index b97e77f41..74dd9f98d 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/stage/entry/SegmentStages.java @@ -360,7 +360,7 @@ public abstract class SegmentStages implements SegmentLock { } void initSegment() { - VanillaChronicleHash h = hh.h(); + VanillaChronicleHash h = hh.h(); long hashLookupOffset = h.segmentOffset(segmentIndex); long freeListOffset = hashLookupOffset + h.segmentHashLookupOuterSize; freeListBytes.storePositionAndSize(h.ms, freeListOffset, h.segmentFreeListInnerSize); @@ -375,7 +375,7 @@ public abstract class SegmentStages implements SegmentLock { //TODO refactor/optimize public long alloc(int chunks) { - VanillaChronicleHash h = hh.h(); + VanillaChronicleHash h = hh.h(); if (chunks > h.maxChunksPerEntry) throw new IllegalArgumentException("Entry is too large: requires " + chunks + " entry size chucks, " + h.maxChunksPerEntry + " is maximum."); diff --git a/src/main/java/net/openhft/chronicle/hash/impl/stage/iter/HashSegmentIteration.java b/src/main/java/net/openhft/chronicle/hash/impl/stage/iter/HashSegmentIteration.java index 5d902c17e..5a008d9c9 100644 --- a/src/main/java/net/openhft/chronicle/hash/impl/stage/iter/HashSegmentIteration.java +++ b/src/main/java/net/openhft/chronicle/hash/impl/stage/iter/HashSegmentIteration.java @@ -27,6 +27,7 @@ import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation; import net.openhft.sg.StageRef; import net.openhft.sg.Staged; +import java.util.function.Consumer; import java.util.function.Predicate; @Staged @@ -50,7 +51,7 @@ public abstract class HashSegmentIteration> implements this.entryRemovedOnThisIteration = entryRemovedOnThisIteration; } - public boolean forEachRemoving(Predicate action) { + public boolean forEachSegmentEntryWhile(Predicate action) { s.innerUpdateLock.lock(); try { long size = s.size(); @@ -86,6 +87,13 @@ public abstract class HashSegmentIteration> implements initEntryRemovedOnThisIteration(false); } } + + public void forEachSegmentEntry(Consumer action) { + forEachSegmentEntryWhile(e -> { + action.accept(e); + return true; + }); + } public void checkEntryNotRemovedOnThisIteration() { if (entryRemovedOnThisIterationInit()) diff --git a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java index dc7f9e481..ef6e135c6 100644 --- a/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/AbstractChronicleMap.java @@ -80,7 +80,7 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { @Override default boolean containsValue(Object value) { - return !forEachEntryWhile(c -> !c.valueEqualTo((V) value)); + return !forEachEntryWhile(c -> !c.value().equals(c.context().wrapValueAsData((V) value))); } @Override @@ -90,7 +90,7 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { @Override default void forEach(BiConsumer action) { - forEachEntry(c -> action.accept(c.key(), c.get())); + forEachEntry(c -> action.accept(c.key().get(), c.value().get())); } @Override @@ -147,7 +147,7 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { @Override public void forEach(java.util.function.Consumer action) { - AbstractChronicleMap.this.forEachEntry(c -> action.accept(c.get())); + AbstractChronicleMap.this.forEachEntry(c -> action.accept(c.value().get())); } }; } @@ -181,7 +181,7 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { @Override public void forEach(java.util.function.Consumer action) { - AbstractChronicleMap.this.forEachEntry(c -> action.accept(c.key())); + AbstractChronicleMap.this.forEachEntry(c -> action.accept(c.key().get())); } }; } @@ -198,9 +198,9 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { try { return forEachEntryWhile(c -> { - K k = c.key(); + K k = c.key().get(); V v = (V) m.get(k instanceof CharSequence ? k.toString() : k); - return v != null && c.valueEqualTo(v); + return v != null && c.value().equals(c.context().wrapValueAsData(v)); }); } catch (ClassCastException unused) { return false; @@ -247,25 +247,21 @@ interface AbstractChronicleMap extends ChronicleMap, Serializable { @Override - default void forEachEntry(final Consumer> action) { + default void forEachEntry(final Consumer> action) { forEachEntryWhile(c -> { action.accept(c); return true; }); } - - IterationContextInterface iterationContext(); @Override - default boolean forEachEntryWhile(final Predicate> action) { + default boolean forEachEntryWhile(final Predicate> action) { boolean interrupt = false; - iteration: - try (IterationContextInterface c = iterationContext()) { - for (int segmentIndex = actualSegments() - 1; segmentIndex >= 0; segmentIndex--) { - c.initTheSegmentIndex(segmentIndex); - if (!c.forEachRemoving(e -> action.test(c.deprecatedMapKeyContextOnIteration()))) { + for (int i = actualSegments() - 1; i >= 0; i--) { + try (MapSegmentContext c = segmentContext(i)) { + if (!c.forEachSegmentEntryWhile(action)) { interrupt = true; - break iteration; + break; } } } diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java index bbd8545b8..58222a338 100755 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMap.java @@ -30,7 +30,6 @@ import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.Serializable; -import java.lang.Object; import java.util.Map; import java.util.concurrent.ConcurrentMap; @@ -54,9 +53,9 @@ import java.util.concurrent.ConcurrentMap; * @param the map key type * @param the map value type */ -public interface ChronicleMap - extends ConcurrentMap, - ChronicleHash, ExternalMapQueryContext> { +public interface ChronicleMap extends ConcurrentMap, + ChronicleHash, MapSegmentContext, + ExternalMapQueryContext> { /** * Returns the value to which the specified key is mapped, or {@code null} if this map contains diff --git a/src/main/java/net/openhft/chronicle/map/ChronicleMapIterator.java b/src/main/java/net/openhft/chronicle/map/ChronicleMapIterator.java index 0e00a73bc..643d4f12d 100644 --- a/src/main/java/net/openhft/chronicle/map/ChronicleMapIterator.java +++ b/src/main/java/net/openhft/chronicle/map/ChronicleMapIterator.java @@ -16,24 +16,22 @@ package net.openhft.chronicle.map; -import net.openhft.chronicle.map.impl.IterationContextInterface; - import java.util.ArrayDeque; import java.util.Iterator; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Queue; +import java.util.function.Consumer; /** * Very inefficient (esp. if segments are large), but CORRECT implementation */ -abstract class ChronicleMapIterator implements Iterator { +abstract class ChronicleMapIterator implements Iterator, Consumer> { final AbstractChronicleMap map; private final Thread ownerThread = Thread.currentThread(); private final Queue entryBuffer = new ArrayDeque<>(); private int segmentIndex; - IterationContextInterface context; E returned; ChronicleMapIterator(AbstractChronicleMap map) { @@ -54,24 +52,23 @@ abstract class ChronicleMapIterator implements Iterator { while (true) { if (segmentIndex < 0) return; - try (IterationContextInterface c = map.iterationContext()) { - context = c; - c.initTheSegmentIndex(segmentIndex); + + try (MapSegmentContext c = map.segmentContext(segmentIndex)) { segmentIndex--; if (c.size() == 0) continue; - c.forEachRemoving(e -> { - entryBuffer.add(read()); - return true; - }); + c.forEachSegmentEntry(this); return; - } finally { - context = null; } } } - abstract E read(); + @Override + public void accept(MapEntry e) { + entryBuffer.add(read(e)); + } + + abstract E read(MapEntry entry); @Override public boolean hasNext() { @@ -108,9 +105,9 @@ abstract class ChronicleMapIterator implements Iterator { } @Override - Entry read() { - K key = context.key().getUsing(null); - V value = context.value().getUsing(null); + Entry read(MapEntry entry) { + K key = entry.key().getUsing(null); + V value = entry.value().getUsing(null); return new WriteThroughEntry<>(map, key, value); } @@ -127,8 +124,8 @@ abstract class ChronicleMapIterator implements Iterator { } @Override - K read() { - return context.key().getUsing(null); + K read(MapEntry entry) { + return entry.key().getUsing(null); } @Override diff --git a/src/main/java/net/openhft/chronicle/map/MapSegmentContext.java b/src/main/java/net/openhft/chronicle/map/MapSegmentContext.java new file mode 100644 index 000000000..7573ca786 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/map/MapSegmentContext.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Higher Frequency Trading + * + * http://www.higherfrequencytrading.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.chronicle.map; + +import net.openhft.chronicle.hash.HashSegmentContext; + +public interface MapSegmentContext + extends HashSegmentContext>, MapContext { +} diff --git a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java index bb2b8ea79..acfb10686 100644 --- a/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/ReplicatedChronicleMap.java @@ -18,7 +18,6 @@ package net.openhft.chronicle.map; -import net.openhft.chronicle.hash.KeyContext; import net.openhft.chronicle.hash.replication.AbstractReplication; import net.openhft.chronicle.hash.replication.ReplicableEntry; import net.openhft.chronicle.hash.replication.TimeProvider; @@ -218,7 +217,7 @@ public class ReplicatedChronicleMap c.context().remove(c)); } void addCloseable(Closeable closeable) { diff --git a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java index 3d6feeec5..52867dadb 100644 --- a/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/StatelessChronicleMap.java @@ -220,13 +220,13 @@ class StatelessChronicleMap implements ChronicleMap, Closeable, Clon } @Override - public boolean forEachEntryWhile(Predicate> predicate) { + public boolean forEachEntryWhile(Predicate> predicate) { // TODO implement! throw new UnsupportedOperationException(); } @Override - public void forEachEntry(Consumer> action) { + public void forEachEntry(Consumer> action) { // TODO implement! throw new UnsupportedOperationException(); } @@ -554,6 +554,11 @@ class StatelessChronicleMap implements ChronicleMap, Closeable, Clon throw new UnsupportedOperationException("Contexts are not supported by stateless clients"); } + @Override + public MapSegmentContext segmentContext(int segmentIndex) { + throw new UnsupportedOperationException(); + } + public V get(Object key) { return fetchObject(vClass, GET, (K) key); } diff --git a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java index c5d24879b..535c86406 100755 --- a/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java +++ b/src/main/java/net/openhft/chronicle/map/VanillaChronicleMap.java @@ -49,7 +49,7 @@ import static net.openhft.chronicle.map.ChronicleMapBuilder.greatestCommonDiviso public class VanillaChronicleMap, V, VI, MVI extends MetaBytesInterop, R> - extends VanillaChronicleHash, + extends VanillaChronicleHash, MapSegmentContext, ExternalMapQueryContext> implements AbstractChronicleMap { @@ -299,7 +299,6 @@ public class VanillaChronicleMap c.context().remove(c)); } public final long readValueSize(Bytes entry) { @@ -348,8 +347,7 @@ public class VanillaChronicleMap) iterCxt.get(); } - @Override - public IterationContextInterface iterationContext() { + public IterationContextInterface iterationContext() { CompiledMapIterationContext c = i().getContext(); c.initUsed(true); return c; @@ -373,6 +371,13 @@ public class VanillaChronicleMap segmentContext(int segmentIndex) { + IterationContextInterface c = iterationContext(); + c.initTheSegmentIndex(segmentIndex); + return c; + } + @Override public V get(Object key) { try (QueryContextInterface q = queryContext(key)) { diff --git a/src/main/java/net/openhft/chronicle/map/impl/IterationContextInterface.java b/src/main/java/net/openhft/chronicle/map/impl/IterationContextInterface.java index 57a401525..e132dee6f 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/IterationContextInterface.java +++ b/src/main/java/net/openhft/chronicle/map/impl/IterationContextInterface.java @@ -1,21 +1,11 @@ package net.openhft.chronicle.map.impl; import net.openhft.chronicle.map.MapEntry; -import net.openhft.chronicle.map.MapKeyContext; +import net.openhft.chronicle.map.MapSegmentContext; -import java.util.function.Predicate; - -public interface IterationContextInterface extends MapEntry, AutoCloseable { +public interface IterationContextInterface extends MapEntry, + MapSegmentContext { long pos(); void initTheSegmentIndex(int segmentIndex); - - MapKeyContext deprecatedMapKeyContextOnIteration(); - - boolean forEachRemoving(Predicate> action); - - @Override - void close(); - - long size(); } diff --git a/src/main/java/net/openhft/chronicle/map/impl/MapIterationContext.java b/src/main/java/net/openhft/chronicle/map/impl/MapIterationContext.java index 30818facf..032a2f42a 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/MapIterationContext.java +++ b/src/main/java/net/openhft/chronicle/map/impl/MapIterationContext.java @@ -26,7 +26,6 @@ import net.openhft.chronicle.hash.impl.stage.hash.ThreadLocalCopiesHolder; import net.openhft.chronicle.map.impl.stage.data.bytes.EntryValueBytesData; import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceData; import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages; -import net.openhft.chronicle.map.impl.stage.iter.DeprecatedMapKeyContextOnIteration; import net.openhft.chronicle.map.impl.stage.iter.IterationCheckOnEachPublicOperation; import net.openhft.chronicle.map.impl.stage.iter.MapSegmentIteration; import net.openhft.chronicle.map.impl.stage.map.MapEntryOperationsDelegation; @@ -65,8 +64,6 @@ import net.openhft.sg.Staged; EntryValueBytesData.class, WrappedValueInstanceData.class, - - DeprecatedMapKeyContextOnIteration.class, }) public class MapIterationContext { } diff --git a/src/main/java/net/openhft/chronicle/map/impl/ReplicatedIterationContextInterface.java b/src/main/java/net/openhft/chronicle/map/impl/ReplicatedIterationContextInterface.java index 79c77b46a..ae46832b2 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/ReplicatedIterationContextInterface.java +++ b/src/main/java/net/openhft/chronicle/map/impl/ReplicatedIterationContextInterface.java @@ -4,7 +4,8 @@ import net.openhft.chronicle.hash.replication.ReplicableEntry; import java.util.function.Consumer; -public interface ReplicatedIterationContextInterface extends IterationContextInterface { +public interface ReplicatedIterationContextInterface + extends IterationContextInterface { void forEachReplicableEntry(Consumer action); diff --git a/src/main/java/net/openhft/chronicle/map/impl/ReplicatedMapIterationContext.java b/src/main/java/net/openhft/chronicle/map/impl/ReplicatedMapIterationContext.java index 47a5c9791..4160d08c0 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/ReplicatedMapIterationContext.java +++ b/src/main/java/net/openhft/chronicle/map/impl/ReplicatedMapIterationContext.java @@ -27,7 +27,6 @@ import net.openhft.chronicle.map.impl.stage.data.DummyValueZeroData; import net.openhft.chronicle.map.impl.stage.data.bytes.EntryValueBytesData; import net.openhft.chronicle.map.impl.stage.data.instance.WrappedValueInstanceData; import net.openhft.chronicle.map.impl.stage.entry.ReplicatedMapEntryStages; -import net.openhft.chronicle.map.impl.stage.iter.DeprecatedMapKeyContextOnIteration; import net.openhft.chronicle.map.impl.stage.iter.IterationCheckOnEachPublicOperation; import net.openhft.chronicle.map.impl.stage.iter.ReplicatedMapSegmentIteration; import net.openhft.chronicle.map.impl.stage.map.MapEntryOperationsDelegation; @@ -70,8 +69,6 @@ import net.openhft.sg.Staged; WrappedValueInstanceData.class, - DeprecatedMapKeyContextOnIteration.class, - DummyValueZeroData.class, }) public class ReplicatedMapIterationContext { diff --git a/src/main/java/net/openhft/chronicle/map/impl/VanillaChronicleMapHolder.java b/src/main/java/net/openhft/chronicle/map/impl/VanillaChronicleMapHolder.java index 7c58132fe..417c3e0e8 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/VanillaChronicleMapHolder.java +++ b/src/main/java/net/openhft/chronicle/map/impl/VanillaChronicleMapHolder.java @@ -31,7 +31,7 @@ public interface VanillaChronicleMapHolder m(); @Override - default VanillaChronicleHash h() { + default VanillaChronicleHash h() { return m(); } diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/DeprecatedMapKeyContextOnIteration.java b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/DeprecatedMapKeyContextOnIteration.java deleted file mode 100644 index 6d7a23970..000000000 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/DeprecatedMapKeyContextOnIteration.java +++ /dev/null @@ -1,128 +0,0 @@ -package net.openhft.chronicle.map.impl.stage.iter; - -import net.openhft.chronicle.hash.Data; -import net.openhft.chronicle.hash.impl.stage.entry.SegmentStages; -import net.openhft.chronicle.hash.impl.stage.hash.CheckOnEachPublicOperation; -import net.openhft.chronicle.hash.locks.InterProcessLock; -import net.openhft.chronicle.map.MapKeyContext; -import net.openhft.chronicle.map.impl.stage.entry.MapEntryStages; -import net.openhft.chronicle.map.impl.stage.map.MapEntryOperationsDelegation; -import net.openhft.lang.io.Bytes; -import net.openhft.sg.StageRef; -import net.openhft.sg.Staged; -import org.jetbrains.annotations.NotNull; - -@Staged -public class DeprecatedMapKeyContextOnIteration implements MapKeyContext { - - @StageRef CheckOnEachPublicOperation checkOnEachPublicOperation; - @StageRef SegmentStages s; - @StageRef MapSegmentIteration it; - @StageRef MapEntryOperationsDelegation ops; - @StageRef MapEntryStages e; - - @Override - public long valueOffset() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return e.valueOffset; - } - - @Override - public long valueSize() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return e.valueSize; - } - - @Override - public boolean valueEqualTo(V value) { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return Data.bytesEquivalent(e.entryValue, it.context().wrapValueAsData(value)); - } - - @Override - public V get() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return it.value().get(); - } - - @Override - public V getUsing(V usingValue) { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return it.value().getUsing(usingValue); - } - - @Override - public boolean put(V newValue) { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - ops.replaceValue(it, it.context().wrapValueAsData(newValue)); - return true; - } - - @NotNull - @Override - public K key() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return it.key().get(); - } - - @NotNull - @Override - public Bytes entry() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return e.entryBytes; - } - - @Override - public long keyOffset() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return e.keyOffset; - } - - @Override - public long keySize() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return e.keySize; - } - - @Override - public boolean containsKey() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - return true; - } - - @Override - public boolean remove() { - checkOnEachPublicOperation.checkOnEachPublicOperation(); - ops.remove(it); - return true; - } - - @Override - public void close() { - throw new UnsupportedOperationException("close() is not supported during iteration"); - } - - @NotNull - @Override - public InterProcessLock readLock() { - throw unsupportedLocks(); - } - - @NotNull - @Override - public InterProcessLock updateLock() { - throw unsupportedLocks(); - } - - @NotNull - @Override - public InterProcessLock writeLock() { - throw unsupportedLocks(); - } - - @NotNull - private UnsupportedOperationException unsupportedLocks() { - return new UnsupportedOperationException( - "Lock operations are not supported (and not needed!) during iteration"); - } -} diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/IterationCheckOnEachPublicOperation.java b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/IterationCheckOnEachPublicOperation.java index a994c6181..46dc48748 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/IterationCheckOnEachPublicOperation.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/IterationCheckOnEachPublicOperation.java @@ -25,7 +25,7 @@ import net.openhft.sg.Staged; @Staged public class IterationCheckOnEachPublicOperation extends CheckOnEachPublicOperation { - @StageRef MapSegmentIteration iteration; + @StageRef MapSegmentIteration iteration; @Override public void checkOnEachPublicOperation() { diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/MapSegmentIteration.java b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/MapSegmentIteration.java index 6e1a5a30d..98a6f17f4 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/MapSegmentIteration.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/MapSegmentIteration.java @@ -30,11 +30,10 @@ import net.openhft.sg.Staged; import org.jetbrains.annotations.NotNull; @Staged -public abstract class MapSegmentIteration extends HashSegmentIteration> - implements MapEntry, IterationContextInterface { +public abstract class MapSegmentIteration extends HashSegmentIteration> + implements MapEntry, IterationContextInterface { @StageRef MapEntryStages entry; - @StageRef public DeprecatedMapKeyContextOnIteration deprecatedMapKeyContextOnIteration; @StageRef WrappedValueInstanceValueHolder wrappedValueInstanceValueHolder; @Override diff --git a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/ReplicatedMapSegmentIteration.java b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/ReplicatedMapSegmentIteration.java index e8e2ac834..12d30e99d 100644 --- a/src/main/java/net/openhft/chronicle/map/impl/stage/iter/ReplicatedMapSegmentIteration.java +++ b/src/main/java/net/openhft/chronicle/map/impl/stage/iter/ReplicatedMapSegmentIteration.java @@ -12,8 +12,8 @@ import net.openhft.sg.Staged; import java.util.function.Consumer; @Staged -public abstract class ReplicatedMapSegmentIteration extends MapSegmentIteration - implements ReplicatedIterationContextInterface, ReplicableEntry { +public abstract class ReplicatedMapSegmentIteration extends MapSegmentIteration + implements ReplicatedIterationContextInterface, ReplicableEntry { @StageRef ReplicatedMapEntryStages e; @StageRef ReplicationUpdate ru; diff --git a/src/main/java/net/openhft/chronicle/set/ChronicleSet.java b/src/main/java/net/openhft/chronicle/set/ChronicleSet.java index fe7feb574..370a204fb 100644 --- a/src/main/java/net/openhft/chronicle/set/ChronicleSet.java +++ b/src/main/java/net/openhft/chronicle/set/ChronicleSet.java @@ -24,5 +24,6 @@ import net.openhft.chronicle.hash.KeyContext; import java.util.Set; public interface ChronicleSet - extends Set, ChronicleHash, ExternalSetQueryContext> { + extends Set, ChronicleHash, SetSegmentContext, + ExternalSetQueryContext> { } diff --git a/src/main/java/net/openhft/chronicle/set/SetFromMap.java b/src/main/java/net/openhft/chronicle/set/SetFromMap.java index 56d8d825b..e388f1e38 100644 --- a/src/main/java/net/openhft/chronicle/set/SetFromMap.java +++ b/src/main/java/net/openhft/chronicle/set/SetFromMap.java @@ -143,13 +143,18 @@ class SetFromMap extends AbstractSet } @Override - public boolean forEachEntryWhile(Predicate> predicate) { - return m.forEachEntryWhile(predicate); + public SetSegmentContext segmentContext(int segmentIndex) { + throw new UnsupportedOperationException(); } @Override - public void forEachEntry(Consumer> action) { - m.forEachEntry(action); + public boolean forEachEntryWhile(Predicate> predicate) { + throw new UnsupportedOperationException(); + } + + @Override + public void forEachEntry(Consumer> action) { + throw new UnsupportedOperationException(); } @Override diff --git a/src/main/java/net/openhft/chronicle/set/SetSegmentContext.java b/src/main/java/net/openhft/chronicle/set/SetSegmentContext.java new file mode 100644 index 000000000..7f3264b70 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/set/SetSegmentContext.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Higher Frequency Trading + * + * http://www.higherfrequencytrading.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.openhft.chronicle.set; + +import net.openhft.chronicle.hash.HashSegmentContext; + +public interface SetSegmentContext + extends HashSegmentContext>, SetContext { +} diff --git a/src/main/java/net/openhft/xstream/converters/VanillaChronicleMapConverter.java b/src/main/java/net/openhft/xstream/converters/VanillaChronicleMapConverter.java index f3de71ca9..5594d7c85 100644 --- a/src/main/java/net/openhft/xstream/converters/VanillaChronicleMapConverter.java +++ b/src/main/java/net/openhft/xstream/converters/VanillaChronicleMapConverter.java @@ -36,15 +36,15 @@ public class VanillaChronicleMapConverter extends AbstractChronicleMapConv @Override public void marshal(Object o, final HierarchicalStreamWriter writer, final MarshallingContext marshallingContext) { - ((ChronicleMap) o).forEachEntry(c -> { + ((ChronicleMap) o).forEachEntry(e -> { writer.startNode("entry"); { - final Object key = c.key(); + final Object key = e.key().get(); writer.startNode(key.getClass().getName()); marshallingContext.convertAnother(key); writer.endNode(); - Object value = c.get(); + Object value = e.value().get(); writer.startNode(value.getClass().getName()); marshallingContext.convertAnother(value); writer.endNode(); diff --git a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java index d6ff2051f..f6c350b38 100644 --- a/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java +++ b/src/test/java/net/openhft/chronicle/map/ReplicationCheckingMap.java @@ -257,12 +257,12 @@ public class ReplicationCheckingMap implements ChronicleMap { } @Override - public boolean forEachEntryWhile(Predicate> predicate) { + public boolean forEachEntryWhile(Predicate> predicate) { return map1.forEachEntryWhile(predicate); } @Override - public void forEachEntry(Consumer> action) { + public void forEachEntry(Consumer> action) { map1.forEachEntry(action); } @@ -295,6 +295,11 @@ public class ReplicationCheckingMap implements ChronicleMap { throw new UnsupportedOperationException(); } + @Override + public MapSegmentContext segmentContext(int segmentIndex) { + throw new UnsupportedOperationException(); + } + @Override public File file() { throw new UnsupportedOperationException(); diff --git a/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java b/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java index 5c8c66f69..8bfd8303a 100644 --- a/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java +++ b/src/test/java/net/openhft/chronicle/map/example/SimpleMapOperationsListeningTest.java @@ -68,8 +68,8 @@ public class SimpleMapOperationsListeningTest { map.acquireUsing(3, value).addAtomicValue(1); IntValue value2 = DataValueClasses.newDirectInstance(IntValue.class); value2.setValue(5); - map.forEachEntry(c -> c.put(value2)); - map.forEachEntry(c -> c.remove()); + map.forEachEntry(e -> e.context().replaceValue(e, e.context().wrapValueAsData(value2))); + map.forEachEntry(e -> e.context().remove(e)); } } diff --git a/src/test/java/net/openhft/chronicle/map/jsr166/map/StatelessChronicleMapTest.java b/src/test/java/net/openhft/chronicle/map/jsr166/map/StatelessChronicleMapTest.java index 25eae8320..5ebc0db3a 100755 --- a/src/test/java/net/openhft/chronicle/map/jsr166/map/StatelessChronicleMapTest.java +++ b/src/test/java/net/openhft/chronicle/map/jsr166/map/StatelessChronicleMapTest.java @@ -128,6 +128,11 @@ public class StatelessChronicleMapTest extends JSR166TestCase { return d.queryContext(key); } + @Override + public MapSegmentContext segmentContext(int segmentIndex) { + return d.segmentContext(segmentIndex); + } + @Override public V get(Object key) { return d.get(key); @@ -217,12 +222,12 @@ public class StatelessChronicleMapTest extends JSR166TestCase { } @Override - public boolean forEachEntryWhile(Predicate> predicate) { + public boolean forEachEntryWhile(Predicate> predicate) { return d.forEachEntryWhile(predicate); } @Override - public void forEachEntry(Consumer> action) { + public void forEachEntry(Consumer> action) { d.forEachEntry(action); }