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]

Reply via email to