Skip to content

Commit dcc13e3

Browse files
committed
Ensure that DataIndexes produced by a RegionedColumnSourceManager are retained by the DataIndexer
1 parent c2e715c commit dcc13e3

File tree

4 files changed

+51
-9
lines changed

4 files changed

+51
-9
lines changed

engine/table/src/main/java/io/deephaven/engine/table/impl/dataindex/RemappedDataIndex.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.deephaven.engine.table.ColumnSource;
88
import io.deephaven.engine.table.DataIndex;
99
import io.deephaven.engine.table.Table;
10+
import io.deephaven.engine.table.impl.indexer.DataIndexer;
1011
import org.jetbrains.annotations.NotNull;
1112

1213
import java.util.*;
@@ -17,7 +18,7 @@
1718
* A {@link AbstractDataIndex} that remaps the key columns of another {@link AbstractDataIndex}. Used to implement
1819
* {@link io.deephaven.engine.table.DataIndex#remapKeyColumns(Map)}.
1920
*/
20-
public class RemappedDataIndex extends AbstractDataIndex {
21+
public class RemappedDataIndex extends AbstractDataIndex implements DataIndexer.RetainableDataIndex {
2122

2223
private final AbstractDataIndex sourceIndex;
2324
private final Map<ColumnSource<?>, ColumnSource<?>> oldToNewColumnMap;
@@ -109,4 +110,9 @@ public boolean isRefreshing() {
109110
public boolean isValid() {
110111
return sourceIndex.isValid();
111112
}
113+
114+
@Override
115+
public boolean shouldRetain() {
116+
return DataIndexer.RetainableDataIndex.shouldRetain(sourceIndex);
117+
}
112118
}

engine/table/src/main/java/io/deephaven/engine/table/impl/indexer/DataIndexer.java

+30-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
package io.deephaven.engine.table.impl.indexer;
55

66
import com.google.common.collect.Sets;
7+
import io.deephaven.base.reference.HardSimpleReference;
8+
import io.deephaven.base.reference.SimpleReference;
9+
import io.deephaven.base.reference.WeakSimpleReference;
710
import io.deephaven.base.verify.Require;
811
import io.deephaven.engine.liveness.LivenessScopeStack;
912
import io.deephaven.engine.rowset.RowSet;
@@ -20,8 +23,6 @@
2023
import org.jetbrains.annotations.NotNull;
2124
import org.jetbrains.annotations.Nullable;
2225

23-
import java.lang.ref.Reference;
24-
import java.lang.ref.WeakReference;
2526
import java.util.*;
2627
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
2728
import java.util.function.Predicate;
@@ -390,6 +391,27 @@ private static DataIndex validateAndManageCachedDataIndex(@Nullable final DataIn
390391
return dataIndex;
391392
}
392393

394+
/**
395+
* Interface for {@link DataIndex} implementations that may opt into strong reachability within the DataIndexer's
396+
* cache.
397+
*/
398+
public interface RetainableDataIndex extends DataIndex {
399+
400+
/**
401+
* @return Whether {@code this} should be strongly held (if {@link #addDataIndex(DataIndex) added}) to maintain
402+
* reachability
403+
*/
404+
boolean shouldRetain();
405+
406+
/**
407+
* @return Whether {@code dataIndex} should be strongly held (if {@link #addDataIndex(DataIndex) added}) to
408+
* maintain reachability
409+
*/
410+
static boolean shouldRetain(@NotNull final DataIndex dataIndex) {
411+
return dataIndex instanceof RetainableDataIndex && ((RetainableDataIndex) dataIndex).shouldRetain();
412+
}
413+
}
414+
393415
/**
394416
* Node structure for our multi-level cache of indexes.
395417
*/
@@ -399,14 +421,14 @@ private static class DataIndexCache {
399421
@SuppressWarnings("rawtypes")
400422
private static final AtomicReferenceFieldUpdater<DataIndexCache, Map> DESCENDANT_CACHES_UPDATER =
401423
AtomicReferenceFieldUpdater.newUpdater(DataIndexCache.class, Map.class, "descendantCaches");
402-
private static final Reference<DataIndex> MISSING_INDEX_REFERENCE = new WeakReference<>(null);
424+
private static final SimpleReference<DataIndex> MISSING_INDEX_REFERENCE = new WeakSimpleReference<>(null);
403425

404426
/** The sub-indexes below this level. */
405427
@SuppressWarnings("FieldMayBeFinal")
406428
private volatile Map<ColumnSource<?>, DataIndexCache> descendantCaches = EMPTY_DESCENDANT_CACHES;
407429

408430
/** A reference to the index at this level. Note that there will never be an index at the "root" level. */
409-
private volatile Reference<DataIndex> dataIndexReference = MISSING_INDEX_REFERENCE;
431+
private volatile SimpleReference<DataIndex> dataIndexReference = MISSING_INDEX_REFERENCE;
410432

411433
private DataIndexCache() {}
412434

@@ -509,7 +531,9 @@ private boolean add(@NotNull final List<ColumnSource<?>> keyColumns, @NotNull fi
509531
// noinspection SynchronizationOnLocalVariableOrMethodParameter
510532
synchronized (cache) {
511533
if (!isValidAndLive(cache.dataIndexReference.get())) {
512-
cache.dataIndexReference = new WeakReference<>(dataIndex);
534+
cache.dataIndexReference = RetainableDataIndex.shouldRetain(dataIndex)
535+
? new HardSimpleReference<>(dataIndex)
536+
: new WeakSimpleReference<>(dataIndex);
513537
return true;
514538
}
515539
}
@@ -544,7 +568,7 @@ private DataIndex computeIfAbsent(
544568
// managed by the appropriate scope for the caller's own use. Further validation is deferred
545569
// as in add.
546570
dataIndex = dataIndexFactory.get();
547-
cache.dataIndexReference = new WeakReference<>(dataIndex);
571+
cache.dataIndexReference = new WeakSimpleReference<>(dataIndex);
548572
}
549573
}
550574
}

engine/table/src/main/java/io/deephaven/engine/table/impl/sources/regioned/MergedDataIndex.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.deephaven.engine.table.impl.by.AggregationProcessor;
2020
import io.deephaven.engine.table.impl.by.AggregationRowLookup;
2121
import io.deephaven.engine.table.impl.dataindex.AbstractDataIndex;
22+
import io.deephaven.engine.table.impl.indexer.DataIndexer;
2223
import io.deephaven.engine.table.impl.locations.TableLocation;
2324
import io.deephaven.engine.table.impl.perf.QueryPerformanceRecorder;
2425
import io.deephaven.engine.table.impl.select.FunctionalColumn;
@@ -43,7 +44,7 @@
4344
* source table".
4445
*/
4546
@InternalUseOnly
46-
class MergedDataIndex extends AbstractDataIndex {
47+
class MergedDataIndex extends AbstractDataIndex implements DataIndexer.RetainableDataIndex {
4748

4849
private static final String LOCATION_DATA_INDEX_TABLE_COLUMN_NAME = "__DataIndexTable";
4950

@@ -239,4 +240,9 @@ public boolean isValid() {
239240
}
240241
return isValid = true;
241242
}
243+
244+
@Override
245+
public boolean shouldRetain() {
246+
return true;
247+
}
242248
}

engine/table/src/main/java/io/deephaven/engine/table/impl/sources/regioned/PartitioningColumnDataIndex.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.deephaven.engine.table.impl.QueryTable;
1818
import io.deephaven.engine.table.impl.TableUpdateImpl;
1919
import io.deephaven.engine.table.impl.dataindex.AbstractDataIndex;
20+
import io.deephaven.engine.table.impl.indexer.DataIndexer;
2021
import io.deephaven.engine.table.impl.sources.ArrayBackedColumnSource;
2122
import io.deephaven.engine.table.impl.sources.ObjectArraySource;
2223
import io.deephaven.engine.table.impl.sources.ReinterpretUtils;
@@ -30,7 +31,7 @@
3031
/**
3132
* DataIndex over a partitioning column of a {@link Table} backed by a {@link RegionedColumnSourceManager}.
3233
*/
33-
class PartitioningColumnDataIndex<KEY_TYPE> extends AbstractDataIndex {
34+
class PartitioningColumnDataIndex<KEY_TYPE> extends AbstractDataIndex implements DataIndexer.RetainableDataIndex {
3435

3536
private static final int KEY_NOT_FOUND = (int) RowSequence.NULL_ROW_KEY;
3637

@@ -318,4 +319,9 @@ public boolean isRefreshing() {
318319
public boolean isValid() {
319320
return true;
320321
}
322+
323+
@Override
324+
public boolean shouldRetain() {
325+
return true;
326+
}
321327
}

0 commit comments

Comments
 (0)