Skip to content

Commit bc7061e

Browse files
authored
IGNITE-24135 BPlusTree reuses lastRow from rowFilter closure to fill buffer (#11816)
1 parent 20ca13c commit bc7061e

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/ExpiredEntriesIntegrationTest.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import org.apache.ignite.IgniteCache;
2424
import org.apache.ignite.cache.query.annotations.QuerySqlField;
2525
import org.apache.ignite.configuration.CacheConfiguration;
26+
import org.apache.ignite.internal.metric.IoStatisticsHolder;
27+
import org.apache.ignite.internal.processors.query.calcite.QueryChecker;
28+
import org.apache.ignite.internal.util.typedef.F;
2629
import org.apache.ignite.testframework.GridTestUtils;
2730
import org.junit.Test;
2831

@@ -35,23 +38,29 @@
3538
*/
3639
public class ExpiredEntriesIntegrationTest extends AbstractBasicIntegrationTest {
3740
/** */
38-
@Test
39-
public void testExpiration() throws Exception {
41+
@Override protected void beforeTest() throws Exception {
4042
CacheConfiguration<Integer, Developer> cacheCfg = new CacheConfiguration<Integer, Developer>()
4143
.setIndexedTypes(Integer.class, Developer.class)
4244
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MILLISECONDS, 1)));
4345

44-
IgniteCache<Integer, Developer> cache1 = client.getOrCreateCache(new CacheConfiguration<>(cacheCfg)
46+
client.createCache(new CacheConfiguration<>(cacheCfg)
4547
.setName("CACHE1")
4648
.setEagerTtl(false)
4749
);
4850

49-
IgniteCache<Integer, Developer> cache2 = client.getOrCreateCache(new CacheConfiguration<>(cacheCfg)
51+
client.createCache(new CacheConfiguration<>(cacheCfg)
5052
.setName("CACHE2")
5153
.setEagerTtl(true)
5254
);
5355

5456
awaitPartitionMapExchange();
57+
}
58+
59+
/** */
60+
@Test
61+
public void testExpiration() throws Exception {
62+
IgniteCache<Integer, Developer> cache1 = client.cache("CACHE1");
63+
IgniteCache<Integer, Developer> cache2 = client.cache("CACHE2");
5564

5665
for (int i = 0; i < 100; i++) {
5766
cache1.put(i, new Developer("dev" + i, i));
@@ -71,6 +80,30 @@ public void testExpiration() throws Exception {
7180
checkExpiration("CACHE2", true);
7281
}
7382

83+
/** Validate that check of expiry policy doesn't require additional page read. */
84+
@Test
85+
public void testIndexScanReadPageOnce() {
86+
for (String cacheName: F.asList("CACHE1", "CACHE2")) {
87+
IgniteCache<Integer, Developer> cache = client.cache(cacheName);
88+
89+
ExpiryPolicy expPlc = new CreatedExpiryPolicy(new Duration(TimeUnit.DAYS, 1));
90+
91+
int key = primaryKey(grid(0).cache(cacheName));
92+
93+
cache.withExpiryPolicy(expPlc).put(key, new Developer("dev0", 0));
94+
95+
IoStatisticsHolder statHld = grid(0).cachex(cacheName).context().group().statisticsHolderData();
96+
97+
long before = statHld.logicalReads();
98+
99+
assertQuery("SELECT /*+ FORCE_INDEX(DEVELOPER_DEPID_IDX) */ name, depId FROM " + cacheName + ".DEVELOPER where depId=0")
100+
.matches(QueryChecker.containsIndexScan(cacheName, "DEVELOPER", "DEVELOPER_DEPID_IDX"))
101+
.check();
102+
103+
assertEquals(1, statHld.logicalReads() - before);
104+
}
105+
}
106+
74107
/** */
75108
private void checkExpiration(String schema, boolean eagerTtl) {
76109
assertQuery("SELECT depId, name FROM " + schema + ".DEVELOPER WHERE name IS NOT NULL")

modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineTreeFilterClosure.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO;
2626
import org.apache.ignite.internal.util.typedef.internal.S;
2727
import org.apache.ignite.spi.indexing.IndexingQueryCacheFilter;
28+
import org.jetbrains.annotations.Nullable;
2829

2930
import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId;
3031

@@ -38,6 +39,9 @@ public class InlineTreeFilterClosure implements BPlusTree.TreeRowClosure<IndexRo
3839
/** */
3940
private final BPlusTree.TreeRowClosure<IndexRow, IndexRow> rowFilter;
4041

42+
/** Last index row analyzed by {@link #rowFilter}. */
43+
private @Nullable IndexRow lastRow;
44+
4145
/** Constructor. */
4246
public InlineTreeFilterClosure(IndexingQueryCacheFilter cacheFilter,
4347
BPlusTree.TreeRowClosure<IndexRow, IndexRow> rowFilter) {
@@ -53,15 +57,22 @@ public InlineTreeFilterClosure(IndexingQueryCacheFilter cacheFilter,
5357

5458
boolean val = cacheFilter == null || applyFilter((InlineIO)io, pageAddr, idx);
5559

56-
if (!val)
57-
return false;
58-
59-
if (rowFilter != null)
60+
if (val && rowFilter != null) {
6061
val = rowFilter.apply(tree, io, pageAddr, idx);
6162

63+
lastRow = rowFilter.lastRow();
64+
}
65+
else
66+
lastRow = null;
67+
6268
return val;
6369
}
6470

71+
/** {@inheritDoc} */
72+
@Override public @Nullable IndexRow lastRow() {
73+
return lastRow;
74+
}
75+
6576
/**
6677
* @param io Row IO.
6778
* @param pageAddr Page address.

modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5724,8 +5724,19 @@ private final class ForwardCursor extends AbstractForwardCursor implements GridC
57245724

57255725
for (int idx = startIdx; idx < cnt; idx++) {
57265726
if (c == null || c.apply(BPlusTree.this, io, pageAddr, idx)) {
5727-
rows = GridArrays.set(rows, resCnt++, rowFactory == null ? getRow(io, pageAddr, idx, x) :
5728-
rowFactory.create(BPlusTree.this, io, pageAddr, idx));
5727+
T row = null;
5728+
5729+
if (rowFactory != null)
5730+
row = rowFactory.create(BPlusTree.this, io, pageAddr, idx);
5731+
else {
5732+
if (c != null)
5733+
row = c.lastRow();
5734+
5735+
if (row == null)
5736+
row = getRow(io, pageAddr, idx, x);
5737+
}
5738+
5739+
rows = GridArrays.set(rows, resCnt++, row);
57295740
}
57305741
}
57315742

@@ -5938,7 +5949,7 @@ public boolean apply(BPlusTree<L, T> tree, BPlusIO<L> io, long pageAddr, int idx
59385949
*
59395950
* @return Last row that was analyzed or {@code null}.
59405951
*/
5941-
public default L lastRow() {
5952+
public default T lastRow() {
59425953
return null;
59435954
}
59445955
}

0 commit comments

Comments
 (0)