This is an automated email from the ASF dual-hosted git repository. marcuse pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit eb0c77ae1ecd1cdc96ce64d91a36e5c4993af691 Author: Marcus Eriksson <[email protected]> AuthorDate: Fri Apr 4 08:16:24 2025 +0200 Fix TreeMap race in CollectionVirtualTableAdapter causing us to lose rows in the virtual table Patch by marcuse; reviewed by Sam Tunnicliffe for CASSANDRA-20524 --- CHANGES.txt | 1 + .../db/virtual/CollectionVirtualTableAdapter.java | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f74d385e83..ba71e542b4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * Fix TreeMap race in CollectionVirtualTableAdapter causing us to lose rows in the virtual table (CASSANDRA-20524) * Improve metadata log catch up with inter-DC mutation forwarding (CASSANDRA-20523) * Support topology-safe changes to Datacenter & Rack for live nodes (CASSANDRA-20528) * Add SSTableIntervalTree latency metric (CASSANDRA-20502) diff --git a/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java b/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java index 47aa3bd5c4..cc311e1a26 100644 --- a/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java +++ b/src/java/org/apache/cassandra/db/virtual/CollectionVirtualTableAdapter.java @@ -31,7 +31,6 @@ import java.util.Objects; import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; import java.util.function.Function; @@ -366,14 +365,16 @@ public class CollectionVirtualTableAdapter<R> implements VirtualTable private Iterator<? extends UnfilteredRowIterator> buildDataRangeIterator(DataRange dataRange, ColumnFilter columnFilter) { - NavigableMap<DecoratedKey, NavigableMap<Clustering<?>, Row>> partitionMap = new ConcurrentSkipListMap<>(DecoratedKey.comparator); - StreamSupport.stream(data.spliterator(), true) - .map(row -> makeRow(row, columnFilter)) - .filter(cr -> dataRange.keyRange().contains(cr.key.get())) - .forEach(cr -> partitionMap.computeIfAbsent(cr.key.get(), - key -> new TreeMap<>(metadata.comparator)) - .put(cr.clustering, cr.rowSup.get())); - + NavigableMap<DecoratedKey, NavigableMap<Clustering<?>, Row>> partitionMap = new TreeMap<>(DecoratedKey.comparator); + for (R row : data) + { + CollectionRow cr = makeRow(row, columnFilter); + if (dataRange.keyRange().contains(cr.key.get())) + { + partitionMap.computeIfAbsent(cr.key.get(), + key -> new TreeMap<>(metadata.comparator)).put(cr.clustering, cr.rowSup.get()); + } + } return partitionMap.entrySet().stream().map( e -> new DataRowUnfilteredIterator(e.getKey(), dataRange.clusteringIndexFilter(e.getKey()), columnFilter, e.getValue())).iterator(); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
