From 17c11ddbbf3e3d0e0e41e03d04050c1ac27340c7 Mon Sep 17 00:00:00 2001 From: devozerov Date: Thu, 24 May 2018 11:22:29 +0300 Subject: [PATCH] IGNITE-8591: Done. --- .../cache/persistence/tree/BPlusTree.java | 38 ++++++++++++++----- .../processors/query/h2/database/H2Tree.java | 38 +++++++++++++++++++ 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java index e30de5a101d1b..f03e331f5b77d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java @@ -4494,6 +4494,33 @@ protected final T getRow(BPlusIO io, long pageAddr, int idx) throws IgniteChe */ protected abstract T getRow(BPlusIO io, long pageAddr, int idx, Object x) throws IgniteCheckedException; + /** + * Get multiple rows from the given index. + * + * @param io IO. + * @param pageAddr Page address. + * @param startIdx Start index. + * @param cnt Count. + * @param x Implementation specific argument, {@code null} always means that we need to return full + * detached data row. + * @param out Output buffer. + * @return How many rows were filled. + * @throws IgniteCheckedException If failed. + */ + protected int getRows(BPlusIO io, long pageAddr, int startIdx, int cnt, Object x, Object[] out) + throws IgniteCheckedException { + int foundCnt = 0; + + for (int i = 0; i < cnt; i++) { + T r = getRow(io, pageAddr, startIdx + i, x); + + if (r != null) + out[foundCnt++] = r; + } + + return foundCnt; + } + /** * Forward cursor. */ @@ -4651,17 +4678,10 @@ private boolean fillFromBuffer(long pageAddr, BPlusIO io, int startIdx, int c if (cnt == 0) return false; - if (rows == EMPTY) + if (rows.length < cnt) rows = (T[])new Object[cnt]; - int foundCnt = 0; - - for (int i = 0; i < cnt; i++) { - T r = getRow(io, pageAddr, startIdx + i, x); - - if (r != null) - rows = GridArrays.set(rows, foundCnt++, r); - } + int foundCnt = getRows(io, pageAddr, startIdx, cnt, x, rows); if (foundCnt == 0) { rows = (T[])EMPTY; diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java index 8da3b05966c1d..ee2547bb58c80 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java @@ -19,6 +19,8 @@ import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import java.util.concurrent.atomic.AtomicLong; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.pagemem.PageIdUtils; @@ -167,6 +169,42 @@ public GridH2Row createRowFromLink(long link) throws IgniteCheckedException { return (GridH2Row)io.getLookupRow(this, pageAddr, idx); } + /** {@inheritDoc} */ + @Override protected int getRows(BPlusIO io, long pageAddr, int startIdx, int cnt, Object filter, + Object[] out) throws IgniteCheckedException { + int foundCnt = 0; + + IndexingQueryCacheFilter filter0 = (IndexingQueryCacheFilter)filter; + + // Pre-sort links. + TreeMap sortedLinks = new TreeMap<>(); + + for (int i = 0; i < cnt; i++) { + int idx = startIdx + i; + + long link = ((H2RowLinkIO)io).getLink(pageAddr, idx); + + int part = PageIdUtils.partId(PageIdUtils.pageId(link)); + + if (filter0 != null && !filter0.applyPartition(part)) + continue; + + sortedLinks.put(link, foundCnt++); + } + + // Initialize rows from sorted links. + for (Map.Entry entry : sortedLinks.entrySet()) { + long link = entry.getKey(); + int idx = entry.getValue(); + + GridH2Row row = createRowFromLink(link); + + out[idx] = row; + } + + return foundCnt; + } + /** * @return Inline size. */