Fix TreeMap race in CollectionVirtualTableAdapter causing us to lose rows in the virtual table

Patch by marcuse; reviewed by Sam Tunnicliffe for CASSANDRA-20524
This commit is contained in:
Marcus Eriksson 2025-04-04 08:16:24 +02:00
parent 6f79207c34
commit eb0c77ae1e
2 changed files with 11 additions and 9 deletions

View File

@ -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)

View File

@ -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();