ignite-db - refactor
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6c9e05d0 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6c9e05d0 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6c9e05d0 Branch: refs/heads/ignite-db-x-10884 Commit: 6c9e05d067c0dae91c557e74c4980bedcd2969e1 Parents: 843f680 Author: S.Vladykin <[email protected]> Authored: Wed Apr 13 08:33:16 2016 +0300 Committer: S.Vladykin <[email protected]> Committed: Wed Apr 13 08:33:16 2016 +0300 ---------------------------------------------------------------------- .../cache/database/tree/BPlusTree.java | 31 +- .../cache/database/tree/io/BPlusIO.java | 14 +- .../database/IgniteCacheH2DatabaseManager.java | 4 +- .../query/h2/database/BPlusTreeIndex.java | 282 ------------------- .../query/h2/database/H2RowStore.java | 16 +- .../processors/query/h2/database/H2Tree.java | 100 +++++++ .../query/h2/database/H2TreeIndex.java | 222 +++++++++++++++ .../query/h2/database/PageMemoryIndex.java | 50 ---- .../query/h2/database/io/H2InnerIO.java | 11 + .../query/h2/database/io/H2LeafIO.java | 11 + 10 files changed, 376 insertions(+), 365 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java index 6319621..33547bc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java @@ -457,30 +457,32 @@ public abstract class BPlusTree<L, T extends L> { /** * @param metaPageId Meta page ID. - * @param initNew Initialize new index. * @throws IgniteCheckedException If failed. */ - public BPlusTree(FullPageId metaPageId, boolean initNew) throws IgniteCheckedException { + public BPlusTree(FullPageId metaPageId) throws IgniteCheckedException { // TODO make configurable: 0 <= minFill <= maxFill <= 1 minFill = 0f; // Testing worst case when merge happens only on empty page. maxFill = 0f; // Avoiding random effects on testing. this.metaPageId = metaPageId.pageId(); + } - if (initNew) { // Init new index. - try (Page meta = page(this.metaPageId)) { - ByteBuffer buf = meta.getForInitialWrite(); + /** + * @throws IgniteCheckedException If failed. + */ + protected void initNew() throws IgniteCheckedException { + try (Page meta = page(metaPageId)) { + ByteBuffer buf = meta.getForInitialWrite(); - BPlusMetaIO io = BPlusMetaIO.VERSIONS.latest(); + BPlusMetaIO io = BPlusMetaIO.VERSIONS.latest(); - io.initNewPage(buf, metaPageId.pageId()); + io.initNewPage(buf, metaPageId); - try (Page root = allocatePage()) { - latestLeafIO().initNewPage(root.getForInitialWrite(), root.id()); + try (Page root = allocatePage()) { + latestLeafIO().initNewPage(root.getForInitialWrite(), root.id()); - io.setLevelsCount(buf, 1); - io.setLeftmostPageId(buf, 0, root.id()); - } + io.setLevelsCount(buf, 1); + io.setLeftmostPageId(buf, 0, root.id()); } } } @@ -1294,8 +1296,7 @@ public abstract class BPlusTree<L, T extends L> { // Do move up. cnt = io.getCount(buf); - assert io.canGetRow(); // TODO refactor to use io.store for move up, this assert is wrong in general case - T moveUpRow = getRow(io, buf, cnt - 1); // Last item from backward row goes up. + L moveUpRow = io.getLookupRow(this, buf, cnt - 1); // Last item from backward row goes up. if (!io.isLeaf()) // Leaf pages must contain all the links, inner pages remove moveUpLink. io.setCount(buf, cnt - 1); @@ -1315,7 +1316,7 @@ public abstract class BPlusTree<L, T extends L> { io.setCount(newRootBuf, 1); inner(io).setLeft(newRootBuf, 0, PageIO.getPageId(buf)); - io.store(newRootBuf, 0, moveUpRow); // TODO refactor + io.store(newRootBuf, 0, moveUpRow); inner(io).setRight(newRootBuf, 0, fwd.id()); } http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java index 65dc2c2..33a8a69 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.processors.cache.database.tree.io; import java.nio.ByteBuffer; +import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; /** @@ -133,7 +134,7 @@ public abstract class BPlusIO<L> extends PageIO { } /** - * @return {@code true} If we can get the whole row from this page using + * @return {@code true} If we can get the full row from this page using * method {@link BPlusTree#getRow(BPlusIO, ByteBuffer, int)}. * Must always be {@code true} for leaf pages. */ @@ -164,6 +165,17 @@ public abstract class BPlusIO<L> extends PageIO { public abstract void store(ByteBuffer buf, int idx, L row); /** + * Get lookup row. + * + * @param tree Tree. + * @param buf Buffer. + * @param idx Index. + * @return Lookup row. + * @throws IgniteCheckedException If failed. + */ + public abstract L getLookupRow(BPlusTree<L, ?> tree, ByteBuffer buf, int idx) throws IgniteCheckedException; + + /** * Copy items from source buffer to destination buffer. Both pages must be of the same type. * * @param src Source buffer. http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheH2DatabaseManager.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheH2DatabaseManager.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheH2DatabaseManager.java index 421ebef..d910ff2 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheH2DatabaseManager.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheH2DatabaseManager.java @@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.cache.database; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.pagemem.FullPageId; import org.apache.ignite.internal.processors.cache.GridCacheManagerAdapter; -import org.apache.ignite.internal.processors.query.h2.database.BPlusTreeIndex; +import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex; import org.apache.ignite.internal.processors.query.h2.database.H2RowStore; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; import org.apache.ignite.lang.IgniteBiTuple; @@ -64,7 +64,7 @@ public class IgniteCacheH2DatabaseManager extends GridCacheManagerAdapter implem log.info("Creating cache index [cacheId=" + cctx.cacheId() + ", idxName=" + name + ", rootPageId=" + page.get1() + ", allocated=" + page.get2() + ']'); - Index idx = new BPlusTreeIndex( + Index idx = new H2TreeIndex( cctx, dbMgr.pageMemory(), page.get1(), http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/BPlusTreeIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/BPlusTreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/BPlusTreeIndex.java deleted file mode 100644 index 583d771..0000000 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/BPlusTreeIndex.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.query.h2.database; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.pagemem.FullPageId; -import org.apache.ignite.internal.pagemem.Page; -import org.apache.ignite.internal.pagemem.PageIdAllocator; -import org.apache.ignite.internal.pagemem.PageMemory; -import org.apache.ignite.internal.processors.cache.GridCacheContext; -import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; -import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusIO; -import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusInnerIO; -import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusLeafIO; -import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO; -import org.apache.ignite.internal.processors.query.h2.database.io.H2InnerIO; -import org.apache.ignite.internal.processors.query.h2.database.io.H2LeafIO; -import org.apache.ignite.internal.processors.query.h2.database.io.H2RowLinkIO; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; -import org.apache.ignite.internal.util.lang.GridCursor; -import org.h2.engine.Session; -import org.h2.index.Cursor; -import org.h2.index.IndexType; -import org.h2.message.DbException; -import org.h2.result.Row; -import org.h2.result.SearchRow; -import org.h2.result.SortOrder; -import org.h2.table.IndexColumn; -import org.h2.table.TableFilter; - -/** - * H2 Index over {@link BPlusTree}. - */ -public class BPlusTreeIndex extends PageMemoryIndex { - /** */ - private GridCacheContext<?,?> cctx; - - /** */ - private PageMemory pageMem; - - /** */ - private H2BPlusTree tree; - - /** - * @param cctx Cache context. - * @param pageMem Page memory. - * @param metaPageId Meta page ID. - * @param initNew Initialize new index. - * @param keyCol Key column. - * @param valCol Value column. - * @param tbl Table. - * @param name Index name. - * @param pk Primary key. - * @param cols Index columns. - * @throws IgniteCheckedException If failed. - */ - public BPlusTreeIndex( - GridCacheContext<?,?> cctx, - PageMemory pageMem, - FullPageId metaPageId, - boolean initNew, - int keyCol, - int valCol, - GridH2Table tbl, - String name, - boolean pk, - IndexColumn[] cols - ) throws IgniteCheckedException { - super(keyCol, valCol); - - assert cctx.cacheId() == metaPageId.cacheId(); - - if (!pk) { - // For other indexes we add primary key at the end to avoid conflicts. - cols = Arrays.copyOf(cols, cols.length + 1); - - cols[cols.length - 1] = tbl.indexColumn(keyCol, SortOrder.ASCENDING); - } - - this.pageMem = pageMem; - this.cctx = cctx; - - initBaseIndex(tbl, 0, name, cols, - pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false)); - - tree = new H2BPlusTree(tbl.rowStore(), metaPageId, initNew); - } - - /** {@inheritDoc} */ - @Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) { - try { - return new H2Cursor(tree.find(lower, upper)); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public GridH2Row findOne(GridH2Row row) { - try { - return tree.findOne(row); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @SuppressWarnings("StatementWithEmptyBody") - @Override public GridH2Row put(GridH2Row row) { - try { - return tree.put(row); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public GridH2Row remove(SearchRow row) { - try { - return tree.remove(row); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public double getCost(Session ses, int[] masks, TableFilter filter, SortOrder sortOrder) { - return getCostRangeIndex(masks, getRowCountApproximation(), filter, sortOrder); - } - - /** {@inheritDoc} */ - @Override public long getRowCount(Session ses) { - Cursor cursor = find(ses, null, null); - - long res = 0; - - while (cursor.next()) - res++; - - return res; - } - - /** {@inheritDoc} */ - @Override public long getRowCountApproximation() { - return 10_000; // TODO - } - - /** - * Cursor. - */ - private static class H2Cursor implements Cursor { - /** */ - final GridCursor<GridH2Row> cursor; - - /** - * @param cursor Cursor. - */ - private H2Cursor(GridCursor<GridH2Row> cursor) { - assert cursor != null; - - this.cursor = cursor; - } - - /** {@inheritDoc} */ - @Override public Row get() { - try { - return cursor.get(); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public SearchRow getSearchRow() { - return get(); - } - - /** {@inheritDoc} */ - @Override public boolean next() { - try { - return cursor.next(); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public boolean previous() { - throw DbException.getUnsupportedException("previous"); - } - } - - /** - * Specialization of {@link BPlusTree} for H2 index. - */ - private class H2BPlusTree extends BPlusTree<SearchRow, GridH2Row> { - /** */ - private final H2RowStore rowStore; - - /** - * @param rowStore Row data store. - * @param metaPageId Meta page ID. - * @param initNew Initialize new index. - * @throws IgniteCheckedException If failed. - */ - public H2BPlusTree(H2RowStore rowStore, FullPageId metaPageId, boolean initNew) - throws IgniteCheckedException { - super(metaPageId, initNew); - - assert rowStore != null; - - this.rowStore = rowStore; - } - - /** {@inheritDoc} */ - @Override protected Page page(long pageId) throws IgniteCheckedException { - return pageMem.page(new FullPageId(pageId, cctx.cacheId())); - } - - /** {@inheritDoc} */ - @Override protected Page allocatePage() throws IgniteCheckedException { - FullPageId pageId = pageMem.allocatePage(cctx.cacheId(), -1, PageIdAllocator.FLAG_IDX); - - return pageMem.page(pageId); - } - - /** {@inheritDoc} */ - @Override protected BPlusIO<SearchRow> io(int type, int ver) { - if (type == PageIO.T_H2_REF_INNER) - return H2InnerIO.VERSIONS.forVersion(ver); - - assert type == PageIO.T_H2_REF_LEAF: type; - - return H2LeafIO.VERSIONS.forVersion(ver); - } - - /** {@inheritDoc} */ - @Override protected BPlusInnerIO<SearchRow> latestInnerIO() { - return H2InnerIO.VERSIONS.latest(); - } - - /** {@inheritDoc} */ - @Override protected BPlusLeafIO<SearchRow> latestLeafIO() { - return H2LeafIO.VERSIONS.latest(); - } - - /** {@inheritDoc} */ - @Override protected int compare(BPlusIO<SearchRow> io, ByteBuffer buf, int idx, SearchRow row) - throws IgniteCheckedException { - return compareRows(getRow(io, buf, idx), row); - } - - /** {@inheritDoc} */ - @Override protected GridH2Row getRow(BPlusIO<SearchRow> io, ByteBuffer buf, int idx) throws IgniteCheckedException { - return rowStore.getRow((H2RowLinkIO)io, buf, idx); - } - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowStore.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowStore.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowStore.java index 7697eb4..376ffdd 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowStore.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowStore.java @@ -31,7 +31,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO; import org.apache.ignite.internal.processors.cache.database.tree.util.PageHandler; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.processors.query.h2.database.io.H2RowLinkIO; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; @@ -89,19 +88,6 @@ public class H2RowStore { } /** - * @param io IO. - * @param buf Buffer. - * @param idx Index. - * @return Row. - * @throws IgniteCheckedException If failed. - */ - public GridH2Row getRow(H2RowLinkIO io, ByteBuffer buf, int idx) throws IgniteCheckedException { - long link = io.getLink(buf, idx); - - return getRow(link); - } - - /** * @param pageId Page ID. * @return Page. * @throws IgniteCheckedException If failed. @@ -129,7 +115,7 @@ public class H2RowStore { * @param link Link. * @return Row. */ - private GridH2Row getRow(long link) throws IgniteCheckedException { + public GridH2Row getRow(long link) throws IgniteCheckedException { try (Page page = page(pageId(link))) { ByteBuffer buf = page.getForRead(); http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..474b4b5 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java @@ -0,0 +1,100 @@ +package org.apache.ignite.internal.processors.query.h2.database; + +import java.nio.ByteBuffer; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.FullPageId; +import org.apache.ignite.internal.pagemem.Page; +import org.apache.ignite.internal.pagemem.PageIdAllocator; +import org.apache.ignite.internal.pagemem.PageMemory; +import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusInnerIO; +import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusLeafIO; +import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO; +import org.apache.ignite.internal.processors.query.h2.database.io.H2InnerIO; +import org.apache.ignite.internal.processors.query.h2.database.io.H2LeafIO; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.h2.result.SearchRow; + +/** + */ +public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { + /** */ + private final int cacheId; + + /** */ + private final H2RowStore rowStore; + + /** */ + private final PageMemory pageMem; + + /** + * @param cacheId Cache ID. + * @param pageMem Page memory. + * @param rowStore Row data store. + * @param metaPageId Meta page ID. + * @param initNew Initialize new index. + * @throws IgniteCheckedException If failed. + */ + public H2Tree(int cacheId, PageMemory pageMem, H2RowStore rowStore, FullPageId metaPageId, boolean initNew) + throws IgniteCheckedException { + super(metaPageId); + + assert pageMem != null; + assert rowStore != null; + + this.cacheId = cacheId; + this.pageMem = pageMem; + this.rowStore = rowStore; + + if (initNew) + initNew(); + } + + /** + * @return Row store. + */ + public H2RowStore getRowStore() { + return rowStore; + } + + /** {@inheritDoc} */ + @Override protected Page page(long pageId) throws IgniteCheckedException { + return pageMem.page(new FullPageId(pageId, cacheId)); + } + + /** {@inheritDoc} */ + @Override protected Page allocatePage() throws IgniteCheckedException { + FullPageId pageId = pageMem.allocatePage(cacheId, -1, PageIdAllocator.FLAG_IDX); + + return pageMem.page(pageId); + } + + /** {@inheritDoc} */ + @Override protected BPlusIO<SearchRow> io(int type, int ver) { + if (type == PageIO.T_H2_REF_INNER) + return H2InnerIO.VERSIONS.forVersion(ver); + + assert type == PageIO.T_H2_REF_LEAF: type; + + return H2LeafIO.VERSIONS.forVersion(ver); + } + + /** {@inheritDoc} */ + @Override protected BPlusInnerIO<SearchRow> latestInnerIO() { + return H2InnerIO.VERSIONS.latest(); + } + + /** {@inheritDoc} */ + @Override protected BPlusLeafIO<SearchRow> latestLeafIO() { + return H2LeafIO.VERSIONS.latest(); + } + + /** {@inheritDoc} */ + @Override protected GridH2Row getRow(BPlusIO<SearchRow> io, ByteBuffer buf, int idx) + throws IgniteCheckedException { + return (GridH2Row)io.getLookupRow(this, buf, idx); + } +} + + http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java new file mode 100644 index 0000000..6867789 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java @@ -0,0 +1,222 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.query.h2.database; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.FullPageId; +import org.apache.ignite.internal.pagemem.PageMemory; +import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; +import org.apache.ignite.internal.util.lang.GridCursor; +import org.h2.engine.Session; +import org.h2.index.Cursor; +import org.h2.index.IndexType; +import org.h2.message.DbException; +import org.h2.result.Row; +import org.h2.result.SearchRow; +import org.h2.result.SortOrder; +import org.h2.table.IndexColumn; +import org.h2.table.TableFilter; + +/** + * H2 Index over {@link BPlusTree}. + */ +public class H2TreeIndex extends GridH2IndexBase { + /** */ + private final H2Tree tree; + + /** + * @param cctx Cache context. + * @param pageMem Page memory. + * @param metaPageId Meta page ID. + * @param initNew Initialize new index. + * @param keyCol Key column. + * @param valCol Value column. + * @param tbl Table. + * @param name Index name. + * @param pk Primary key. + * @param cols Index columns. + * @throws IgniteCheckedException If failed. + */ + public H2TreeIndex( + GridCacheContext<?,?> cctx, + PageMemory pageMem, + FullPageId metaPageId, + boolean initNew, + int keyCol, + int valCol, + GridH2Table tbl, + String name, + boolean pk, + IndexColumn[] cols + ) throws IgniteCheckedException { + super(keyCol, valCol); + + assert pageMem != null; + + assert cctx.cacheId() == metaPageId.cacheId(); + + if (!pk) { + // For other indexes we add primary key at the end to avoid conflicts. + cols = Arrays.copyOf(cols, cols.length + 1); + + cols[cols.length - 1] = tbl.indexColumn(keyCol, SortOrder.ASCENDING); + } + + initBaseIndex(tbl, 0, name, cols, + pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false)); + + tree = new H2Tree(cctx.cacheId(), pageMem, tbl.rowStore(), metaPageId, initNew) { + @Override protected int compare(BPlusIO<SearchRow> io, ByteBuffer buf, int idx, SearchRow row) + throws IgniteCheckedException { + return compareRows(getRow(io, buf, idx), row); + } + }; + } + + /** {@inheritDoc} */ + @Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) { + try { + return new H2Cursor(tree.find(lower, upper)); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public GridH2Row findOne(GridH2Row row) { + try { + return tree.findOne(row); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @SuppressWarnings("StatementWithEmptyBody") + @Override public GridH2Row put(GridH2Row row) { + try { + return tree.put(row); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public GridH2Row remove(SearchRow row) { + try { + return tree.remove(row); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public double getCost(Session ses, int[] masks, TableFilter filter, SortOrder sortOrder) { + return getCostRangeIndex(masks, getRowCountApproximation(), filter, sortOrder); + } + + /** {@inheritDoc} */ + @Override public long getRowCount(Session ses) { + Cursor cursor = find(ses, null, null); + + long res = 0; + + while (cursor.next()) + res++; + + return res; + } + + /** {@inheritDoc} */ + @Override public long getRowCountApproximation() { + return 10_000; // TODO + } + + /** {@inheritDoc} */ + @Override public boolean canGetFirstOrLast() { + return false; + } + + /** {@inheritDoc} */ + @Override public Cursor findFirstOrLast(Session session, boolean b) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void close(Session ses) { + // No-op. + } + + /** + * Cursor. + */ + private static class H2Cursor implements Cursor { + /** */ + final GridCursor<GridH2Row> cursor; + + /** + * @param cursor Cursor. + */ + private H2Cursor(GridCursor<GridH2Row> cursor) { + assert cursor != null; + + this.cursor = cursor; + } + + /** {@inheritDoc} */ + @Override public Row get() { + try { + return cursor.get(); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public SearchRow getSearchRow() { + return get(); + } + + /** {@inheritDoc} */ + @Override public boolean next() { + try { + return cursor.next(); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public boolean previous() { + throw DbException.getUnsupportedException("previous"); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/PageMemoryIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/PageMemoryIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/PageMemoryIndex.java deleted file mode 100644 index cc667d5..0000000 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/PageMemoryIndex.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.query.h2.database; - -import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; -import org.h2.engine.Session; -import org.h2.index.Cursor; - -/** - * - */ -public abstract class PageMemoryIndex extends GridH2IndexBase { - /** - * @param keyCol Key column. - * @param valCol Value column. - */ - protected PageMemoryIndex(int keyCol, int valCol) { - super(keyCol, valCol); - } - - /** {@inheritDoc} */ - @Override public boolean canGetFirstOrLast() { - return false; - } - - /** {@inheritDoc} */ - @Override public Cursor findFirstOrLast(Session session, boolean b) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override public void close(Session ses) { - // No-op. - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2InnerIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2InnerIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2InnerIO.java index 1e39599..937a91c 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2InnerIO.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2InnerIO.java @@ -18,9 +18,12 @@ package org.apache.ignite.internal.processors.query.h2.database.io; import java.nio.ByteBuffer; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusIO; import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusInnerIO; import org.apache.ignite.internal.processors.cache.database.tree.io.IOVersions; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.h2.result.SearchRow; @@ -50,6 +53,14 @@ public class H2InnerIO extends BPlusInnerIO<SearchRow> implements H2RowLinkIO { } /** {@inheritDoc} */ + @Override public SearchRow getLookupRow(BPlusTree<SearchRow,?> tree, ByteBuffer buf, int idx) + throws IgniteCheckedException { + long link = getLink(buf, idx); + + return ((H2Tree)tree).getRowStore().getRow(link); + } + + /** {@inheritDoc} */ @Override public void store(ByteBuffer dst, int dstIdx, BPlusIO<SearchRow> srcIo, ByteBuffer src, int srcIdx) { long link = ((H2RowLinkIO)srcIo).getLink(src, srcIdx); http://git-wip-us.apache.org/repos/asf/ignite/blob/6c9e05d0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2LeafIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2LeafIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2LeafIO.java index d1bade8..b3d3ae0 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2LeafIO.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2LeafIO.java @@ -18,8 +18,11 @@ package org.apache.ignite.internal.processors.query.h2.database.io; import java.nio.ByteBuffer; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree; import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusLeafIO; import org.apache.ignite.internal.processors.cache.database.tree.io.IOVersions; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.h2.result.SearchRow; @@ -49,6 +52,14 @@ public class H2LeafIO extends BPlusLeafIO<SearchRow> implements H2RowLinkIO { } /** {@inheritDoc} */ + @Override public SearchRow getLookupRow(BPlusTree<SearchRow,?> tree, ByteBuffer buf, int idx) + throws IgniteCheckedException { + long link = getLink(buf, idx); + + return ((H2Tree)tree).getRowStore().getRow(link); + } + + /** {@inheritDoc} */ @Override public long getLink(ByteBuffer buf, int idx) { assert idx < getCount(buf): idx;
