iamaleksey commented on code in PR #2982:
URL: https://github.com/apache/cassandra/pull/2982#discussion_r1450540304
##########
src/java/org/apache/cassandra/journal/Segments.java:
##########
@@ -17,123 +17,92 @@
*/
package org.apache.cassandra.journal;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
import accord.utils.Invariants;
+import org.agrona.collections.Long2ObjectHashMap;
+import org.apache.cassandra.utils.concurrent.Ref;
import org.apache.cassandra.utils.concurrent.Refs;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.emptyMap;
-
/**
* Consistent, immutable view of active + static segments
* <p/>
- * TODO: an interval/range structure for StaticSegment lookup based on min/max
key bounds
+ * TODO (performance, expected): an interval/range structure for StaticSegment
lookup based on min/max key bounds
*/
-class Segments<K>
+class Segments<K, V>
{
- // active segments, containing unflushed data; the tail of this queue is
the one we allocate writes from
- private final List<ActiveSegment<K>> activeSegments;
-
- // finalised segments, no longer written to
- private final Map<Descriptor, StaticSegment<K>> staticSegments;
+ private final Long2ObjectHashMap<Segment<K, V>> segments;
- // cached Iterable of concatenated active and static segments
- private final Iterable<Segment<K>> allSegments;
-
- Segments(List<ActiveSegment<K>> activeSegments, Map<Descriptor,
StaticSegment<K>> staticSegments)
+ Segments(Long2ObjectHashMap<Segment<K, V>> segments)
{
- this.activeSegments = activeSegments;
- this.staticSegments = staticSegments;
- this.allSegments = Iterables.concat(onlyActive(), onlyStatic());
+ this.segments = segments;
}
- static <K> Segments<K> ofStatic(Collection<StaticSegment<K>> segments)
+ static <K, V> Segments<K, V> of(Collection<Segment<K, V>> segments)
{
- HashMap<Descriptor, StaticSegment<K>> staticSegments =
- Maps.newHashMapWithExpectedSize(segments.size());
- for (StaticSegment<K> segment : segments)
- staticSegments.put(segment.descriptor, segment);
- return new Segments<>(new ArrayList<>(), staticSegments);
+ Long2ObjectHashMap<Segment<K, V>> newSegments =
newMap(segments.size());
+ for (Segment<K, V> segment : segments)
+ newSegments.put(segment.descriptor.timestamp, segment);
+ return new Segments<>(newSegments);
}
- static <K> Segments<K> none()
+ static <K, V> Segments<K, V> none()
{
- return new Segments<>(Collections.emptyList(), Collections.emptyMap());
+ return new Segments<>(emptyMap());
}
- Segments<K> withNewActiveSegment(ActiveSegment<K> activeSegment)
+ Segments<K, V> withNewActiveSegment(ActiveSegment<K, V> activeSegment)
{
- ArrayList<ActiveSegment<K>> newActiveSegments =
- new ArrayList<>(activeSegments.size() + 1);
- newActiveSegments.addAll(activeSegments);
- newActiveSegments.add(activeSegment);
- return new Segments<>(newActiveSegments, staticSegments);
+ Long2ObjectHashMap<Segment<K, V>> newSegments = new
Long2ObjectHashMap<>(segments);
+ Segment<K, V> oldValue =
newSegments.put(activeSegment.descriptor.timestamp, activeSegment);
+ Invariants.checkState(oldValue == null);
+ return new Segments<>(newSegments);
}
- Segments<K> withCompletedSegment(ActiveSegment<K> activeSegment,
StaticSegment<K> staticSegment)
+ Segments<K, V> withCompletedSegment(ActiveSegment<K, V> activeSegment,
StaticSegment<K, V> staticSegment)
{
Invariants.checkArgument(activeSegment.descriptor.equals(staticSegment.descriptor));
-
- ArrayList<ActiveSegment<K>> newActiveSegments =
- new ArrayList<>(activeSegments.size() - 1);
- for (ActiveSegment<K> segment : activeSegments)
- if (segment != activeSegment)
- newActiveSegments.add(segment);
- Invariants.checkState(newActiveSegments.size() ==
activeSegments.size() - 1);
-
- HashMap<Descriptor, StaticSegment<K>> newStaticSegments =
- Maps.newHashMapWithExpectedSize(staticSegments.size() + 1);
- newStaticSegments.putAll(staticSegments);
- if (newStaticSegments.put(staticSegment.descriptor, staticSegment) !=
null)
- throw new IllegalStateException();
-
- return new Segments<>(newActiveSegments, newStaticSegments);
+ Long2ObjectHashMap<Segment<K, V>> newSegments = new
Long2ObjectHashMap<>(segments);
+ Segment<K, V> oldValue =
newSegments.put(staticSegment.descriptor.timestamp, staticSegment);
+ Invariants.checkState(oldValue == activeSegment);
+ return new Segments<>(newSegments);
}
- Segments<K> withCompactedSegment(StaticSegment<K> oldSegment,
StaticSegment<K> newSegment)
+ Segments<K, V> withCompactedSegment(StaticSegment<K, V> oldSegment,
StaticSegment<K, V> newSegment)
{
Invariants.checkArgument(oldSegment.descriptor.timestamp ==
newSegment.descriptor.timestamp);
Invariants.checkArgument(oldSegment.descriptor.generation <
newSegment.descriptor.generation);
-
- HashMap<Descriptor, StaticSegment<K>> newStaticSegments = new
HashMap<>(staticSegments);
- if (!newStaticSegments.remove(oldSegment.descriptor, oldSegment))
- throw new IllegalStateException();
- if (null != newStaticSegments.put(newSegment.descriptor, newSegment))
- throw new IllegalStateException();
-
- return new Segments<>(activeSegments, newStaticSegments);
+ Long2ObjectHashMap<Segment<K, V>> newSegments = new
Long2ObjectHashMap<>(segments);
+ Segment<K, V> oldValue =
newSegments.put(newSegment.descriptor.timestamp, newSegment);
+ Invariants.checkState(oldValue == oldSegment);
+ return new Segments<>(newSegments);
}
- Segments<K> withoutInvalidatedSegment(StaticSegment<K> staticSegment)
+ Segments<K, V> withoutInvalidatedSegment(StaticSegment<K, V> staticSegment)
{
- HashMap<Descriptor, StaticSegment<K>> newStaticSegments = new
HashMap<>(staticSegments);
- if (!newStaticSegments.remove(staticSegment.descriptor, staticSegment))
+ Long2ObjectHashMap<Segment<K, V>> newSegments = new
Long2ObjectHashMap<>(segments);
+ if (!newSegments.remove(staticSegment.descriptor.timestamp,
staticSegment))
throw new IllegalStateException();
- return new Segments<>(activeSegments, newStaticSegments);
+ return new Segments<>(newSegments);
}
- Iterable<Segment<K>> all()
+ Iterable<Segment<K, V>> all()
{
- return allSegments;
+ return segments.values();
}
- Collection<ActiveSegment<K>> onlyActive()
+ void selectActive(long maxTimestamp, Collection<ActiveSegment<K, V>> into)
Review Comment:
I reuse that list in `Flusher` so as to not generate more garbage than
necessary. I believe it's a good pattern in general, though, for methods like
this to take an input collection - it's something Matin Thompson tends to
advocate for in his talks.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]