http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccTransactionsTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccTransactionsTest.java index dbe4ce5..df9f21e 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccTransactionsTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/mvcc/CacheMvccTransactionsTest.java @@ -36,26 +36,24 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; +import javax.cache.expiry.Duration; +import javax.cache.expiry.TouchedExpiryPolicy; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteDataStreamer; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteTransactions; -import org.apache.ignite.cache.CacheMode; -import org.apache.ignite.cache.CacheWriteSynchronizationMode; import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.cluster.ClusterTopologyException; import org.apache.ignite.configuration.CacheConfiguration; -import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.configuration.MemoryConfiguration; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.IgniteKernal; import org.apache.ignite.internal.TestRecordingCommunicationSpi; import org.apache.ignite.internal.processors.cache.GridCacheContext; +import org.apache.ignite.internal.processors.cache.GridCacheMapEntry; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.distributed.TestCacheNodeExcludingFilter; import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest; @@ -275,6 +273,13 @@ public class CacheMvccTransactionsTest extends CacheMvccAbstractTest { /** * @throws Exception If failed. */ + public void testCacheRecreate() throws Exception { + cacheRecreate(null); + } + + /** + * @throws Exception If failed. + */ public void testActiveQueriesCleanup() throws Exception { activeQueriesCleanup(false); } @@ -3626,6 +3631,67 @@ public class CacheMvccTransactionsTest extends CacheMvccAbstractTest { checkRow(cctx, row, key0, vers.get(v + 1).get1()); } } + + KeyCacheObject key = cctx.toCacheKeyObject(KEYS); + + cache.put(key, 0); + + cache.remove(key); + + cctx.offheap().mvccRemoveAll((GridCacheMapEntry)cctx.cache().entryEx(key)); + } + + /** + * @throws Exception If failed. + */ + public void testExpiration() throws Exception { + final IgniteEx node = startGrid(0); + + IgniteCache cache = node.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, 64)); + + final IgniteCache expiryCache = + cache.withExpiryPolicy(new TouchedExpiryPolicy(new Duration(TimeUnit.SECONDS, 1))); + + for (int i = 0; i < 10; i++) + expiryCache.put(1, i); + + assertTrue("Failed to wait for expiration", GridTestUtils.waitForCondition(new GridAbsPredicate() { + @Override public boolean apply() { + return expiryCache.localPeek(1) == null; + } + }, 5000)); + + for (int i = 0; i < 11; i++) { + if (i % 2 == 0) + expiryCache.put(1, i); + else + expiryCache.remove(1); + } + + assertTrue("Failed to wait for expiration", GridTestUtils.waitForCondition(new GridAbsPredicate() { + @Override public boolean apply() { + return expiryCache.localPeek(1) == null; + } + }, 5000)); + + expiryCache.put(1, 1); + + assertTrue("Failed to wait for expiration", GridTestUtils.waitForCondition(new GridAbsPredicate() { + @Override public boolean apply() { + try { + GridCacheContext cctx = node.context().cache().context().cacheContext(CU.cacheId(DEFAULT_CACHE_NAME)); + + KeyCacheObject key = cctx.toCacheKeyObject(1); + + return cctx.offheap().read(cctx, key) == null; + } + catch (Exception e) { + fail(); + + return false; + } + } + }, 5000)); } /**
http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java index 27804d9..335279f 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java @@ -18,11 +18,14 @@ package org.apache.ignite.internal.processors.database; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; +import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ThreadLocalRandom; @@ -218,6 +221,53 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { /** * @throws IgniteCheckedException If failed. */ + public void testFindWithClosure() throws IgniteCheckedException { + TestTree tree = createTestTree(true); + TreeMap<Long, Long> map = new TreeMap<>(); + + long size = CNT * CNT; + + for (long i = 1; i <= size; i++) { + tree.put(i); + map.put(i, i); + } + + checkCursor(tree.find(null, null, new TestTreeFindFilteredClosure(Collections.<Long>emptySet()), null), + Collections.<Long>emptyList().iterator()); + + checkCursor(tree.find(null, null, new TestTreeFindFilteredClosure(map.keySet()), null), + map.values().iterator()); + + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + for (int i = 0; i < 100; i++) { + Long val = rnd.nextLong(size) + 1; + + checkCursor(tree.find(null, null, new TestTreeFindFilteredClosure(Collections.singleton(val)), null), + Collections.singleton(val).iterator()); + } + + for (int i = 0; i < 200; i++) { + long vals = rnd.nextLong(size) + 1; + + TreeSet<Long> exp = new TreeSet<>(); + + for (long k = 0; k < vals; k++) + exp.add(rnd.nextLong(size) + 1); + + checkCursor(tree.find(null, null, new TestTreeFindFilteredClosure(exp), null), exp.iterator()); + + checkCursor(tree.find(0L, null, new TestTreeFindFilteredClosure(exp), null), exp.iterator()); + + checkCursor(tree.find(0L, size, new TestTreeFindFilteredClosure(exp), null), exp.iterator()); + + checkCursor(tree.find(null, size, new TestTreeFindFilteredClosure(exp), null), exp.iterator()); + } + } + + /** + * @throws IgniteCheckedException If failed. + */ public void _testBenchInvoke() throws IgniteCheckedException { MAX_PER_PAGE = 10; @@ -625,12 +675,12 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { } /** - * @param tree - * @param lower - * @param upper - * @param exp - * @param expFound - * @throws IgniteCheckedException + * @param tree Tree. + * @param lower Lower bound. + * @param upper Upper bound. + * @param exp Value to find. + * @param expFound {@code True} if value should be found. + * @throws IgniteCheckedException If failed. */ private void checkIterate(TestTree tree, long lower, long upper, Long exp, boolean expFound) throws IgniteCheckedException { @@ -641,6 +691,14 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { assertEquals(expFound, c.found); } + /** + * @param tree Tree. + * @param lower Lower bound. + * @param upper Upper bound. + * @param c Closure. + * @param expFound {@code True} if value should be found. + * @throws IgniteCheckedException If failed. + */ private void checkIterateC(TestTree tree, long lower, long upper, TestTreeRowClosure c, boolean expFound) throws IgniteCheckedException { c.found = false; @@ -1307,7 +1365,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { * @throws Exception If failed. */ public void testIterateConcurrentPutRemove() throws Exception { - findOneBoundedConcurrentPutRemove(); + iterateConcurrentPutRemove(); } /** @@ -1316,7 +1374,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { public void testIterateConcurrentPutRemove_1() throws Exception { MAX_PER_PAGE = 1; - findOneBoundedConcurrentPutRemove(); + iterateConcurrentPutRemove(); } /** @@ -1325,7 +1383,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { public void testIterateConcurrentPutRemove_5() throws Exception { MAX_PER_PAGE = 5; - findOneBoundedConcurrentPutRemove(); + iterateConcurrentPutRemove(); } /** @@ -1334,13 +1392,13 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { public void testIteratePutRemove_10() throws Exception { MAX_PER_PAGE = 10; - findOneBoundedConcurrentPutRemove(); + iterateConcurrentPutRemove(); } /** * @throws Exception If failed. */ - private void findOneBoundedConcurrentPutRemove() throws Exception { + private void iterateConcurrentPutRemove() throws Exception { final TestTree tree = createTestTree(true); final int KEYS = 10_000; @@ -1474,7 +1532,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { } /** - * + * @throws Exception If failed. */ public void testConcurrentGrowDegenerateTreeAndConcurrentRemove() throws Exception { //calculate tree size when split happens @@ -2132,6 +2190,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { /** */ private Long val; + /** {@inheritDoc} */ @Override public boolean apply(BPlusTree<Long, Long> tree, BPlusIO<Long> io, long pageAddr, int idx) throws IgniteCheckedException { @@ -2142,4 +2201,27 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { return false; } } + + /** + * + */ + static class TestTreeFindFilteredClosure implements BPlusTree.TreeRowClosure<Long, Long> { + /** */ + private final Set<Long> vals; + + /** + * @param vals Values to allow in filter. + */ + TestTreeFindFilteredClosure(Set<Long> vals) { + this.vals = vals; + } + + /** {@inheritDoc} */ + @Override public boolean apply(BPlusTree<Long, Long> tree, BPlusIO<Long> io, long pageAddr, int idx) + throws IgniteCheckedException { + Long val = io.getLookupRow(tree, pageAddr, idx); + + return vals.contains(val); + } + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java ---------------------------------------------------------------------- diff --git a/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java b/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java index 2cd36b3..fce18f1 100644 --- a/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java +++ b/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java @@ -200,6 +200,11 @@ public class GridH2SpatialIndex extends GridH2IndexBase implements SpatialIndex } } + /** {@inheritDoc} */ + @Override public boolean putx(GridH2Row row) { + return put(row) != null; + } + /** * @param row Row. * @param rowId Row id. http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheTwoStepQuery.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheTwoStepQuery.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheTwoStepQuery.java index 4a93aaf..f5c5e60 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheTwoStepQuery.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/cache/query/GridCacheTwoStepQuery.java @@ -65,6 +65,9 @@ public class GridCacheTwoStepQuery { /** */ private CacheQueryPartitionInfo[] derivedPartitions; + /** */ + private boolean mvccEnabled; + /** * @param originalSql Original query SQL. * @param tbls Tables in query. @@ -241,6 +244,7 @@ public class GridCacheTwoStepQuery { cp.distributedJoins = distributedJoins; cp.derivedPartitions = derivedPartitions; cp.local = local; + cp.mvccEnabled = mvccEnabled; for (int i = 0; i < mapQrys.size(); i++) cp.mapQrys.add(mapQrys.get(i).copy()); @@ -262,6 +266,20 @@ public class GridCacheTwoStepQuery { return tbls; } + /** + * @return Mvcc flag. + */ + public boolean mvccEnabled() { + return mvccEnabled; + } + + /** + * @param mvccEnabled Mvcc flag. + */ + public void mvccEnabled(boolean mvccEnabled) { + this.mvccEnabled = mvccEnabled; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridCacheTwoStepQuery.class, this); http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index eed1f19..6dc93c4 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -71,6 +71,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.QueryCursorImpl; import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException; +import org.apache.ignite.internal.processors.cache.mvcc.MvccCoordinatorVersion; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; import org.apache.ignite.internal.processors.cache.query.CacheQueryPartitionInfo; @@ -98,6 +99,8 @@ import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasInnerI import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasLeafIO; 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.H2MvccInnerIO; +import org.apache.ignite.internal.processors.query.h2.database.io.H2MvccLeafIO; import org.apache.ignite.internal.processors.query.h2.ddl.DdlStatementsProcessor; import org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode; import org.apache.ignite.internal.processors.query.h2.opt.GridH2DefaultTableEngine; @@ -183,7 +186,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { * Register IO for indexes. */ static { - PageIO.registerH2(H2InnerIO.VERSIONS, H2LeafIO.VERSIONS); + PageIO.registerH2(H2InnerIO.VERSIONS, H2LeafIO.VERSIONS, H2MvccInnerIO.VERSIONS, H2MvccLeafIO.VERSIONS); H2ExtrasInnerIO.register(); H2ExtrasLeafIO.register(); @@ -537,8 +540,11 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** {@inheritDoc} */ - @Override public void store(GridCacheContext cctx, GridQueryTypeDescriptor type, CacheDataRow row) - throws IgniteCheckedException { + @Override public void store(GridCacheContext cctx, + GridQueryTypeDescriptor type, + CacheDataRow row, + @Nullable MvccCoordinatorVersion newVer) throws IgniteCheckedException + { String cacheName = cctx.name(); H2TableDescriptor tbl = tableDescriptor(schema(cacheName), cacheName, type.name()); @@ -546,7 +552,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (tbl == null) return; // Type was rejected. - tbl.table().update(row, false); + tbl.table().update(row, newVer, false); if (tbl.luceneIndex() != null) { long expireTime = row.expireTime(); @@ -575,7 +581,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (tbl == null) return; - if (tbl.table().update(row, true)) { + if (tbl.table().update(row, null, true)) { if (tbl.luceneIndex() != null) tbl.luceneIndex().remove(row.key()); } @@ -671,7 +677,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { SchemaIndexCacheVisitorClosure clo = new SchemaIndexCacheVisitorClosure() { @Override public void apply(CacheDataRow row) throws IgniteCheckedException { - GridH2Row h2Row = rowDesc.createRow(row); + GridH2Row h2Row = rowDesc.createRow(row, null); h2Idx.put(h2Row); } @@ -1546,7 +1552,8 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (partitions == null && twoStepQry.derivedPartitions() != null) { try { partitions = calculateQueryPartitions(twoStepQry.derivedPartitions(), args); - } catch (IgniteCheckedException e) { + } + catch (IgniteCheckedException e) { throw new CacheException("Failed to calculate derived partitions: [qry=" + sqlQry + ", params=" + Arrays.deepToString(args) + "]", e); } @@ -1585,9 +1592,11 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** + * @param cacheIds Cache IDs. + * @param twoStepQry Query. * @throws IllegalStateException if segmented indices used with non-segmented indices. */ - private void checkCacheIndexSegmentation(List<Integer> cacheIds) { + private void processCaches(List<Integer> cacheIds, GridCacheTwoStepQuery twoStepQry) { if (cacheIds.isEmpty()) return; // Nothing to check @@ -1595,11 +1604,21 @@ public class IgniteH2Indexing implements GridQueryIndexing { int expectedParallelism = 0; - for (Integer cacheId : cacheIds) { + boolean mvccEnabled = false; + + for (int i = 0; i < cacheIds.size(); i++) { + Integer cacheId = cacheIds.get(i); + GridCacheContext cctx = sharedCtx.cacheContext(cacheId); assert cctx != null; + if (i == 0) + mvccEnabled = cctx.mvccEnabled(); + else if (cctx.mvccEnabled() != mvccEnabled) + throw new IllegalStateException("Using caches with different mvcc settings in same query is " + + "forbidden."); + if (!cctx.isPartitioned()) continue; @@ -1610,6 +1629,8 @@ public class IgniteH2Indexing implements GridQueryIndexing { "forbidden."); } } + + twoStepQry.mvccEnabled(mvccEnabled); } /** @@ -2522,7 +2543,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { //Prohibit usage indices with different numbers of segments in same query. List<Integer> cacheIds = new ArrayList<>(caches0); - checkCacheIndexSegmentation(cacheIds); + processCaches(cacheIds, twoStepQry); return cacheIds; } http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java index 59bf153..9a99c62 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java @@ -124,13 +124,20 @@ public class H2PkHashIndex extends GridH2IndexBase { @SuppressWarnings("StatementWithEmptyBody") @Override public GridH2Row put(GridH2Row row) { // Should not be called directly. Rows are inserted into underlying cache data stores. - assert false; throw DbException.getUnsupportedException("put"); } /** {@inheritDoc} */ + @Override public boolean putx(GridH2Row row) { + // Should not be called directly. Rows are inserted into underlying cache data stores. + assert false; + + throw DbException.getUnsupportedException("putx"); + } + + /** {@inheritDoc} */ @Override public GridH2Row remove(SearchRow row) { // Should not be called directly. Rows are removed from underlying cache data stores. @@ -197,7 +204,7 @@ public class H2PkHashIndex extends GridH2IndexBase { try { CacheDataRow dataRow = cursor.get(); - return tbl.rowDescriptor().createRow(dataRow); + return tbl.rowDescriptor().createRow(dataRow, null); } catch (IgniteCheckedException e) { throw DbException.convert(e); http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowFactory.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowFactory.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowFactory.java index 40b9b0a..e9ec9e6 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowFactory.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2RowFactory.java @@ -18,9 +18,9 @@ package org.apache.ignite.internal.processors.query.h2.database; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter; +import org.apache.ignite.internal.processors.cache.tree.MvccDataRow; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; @@ -60,17 +60,29 @@ public class H2RowFactory { rowBuilder.initFromLink(cctx.group(), CacheDataRowAdapter.RowData.FULL); - GridH2Row row; - - try { - row = rowDesc.createRow(rowBuilder); - } - catch (IgniteCheckedException e) { - throw new IgniteException(e); - } + GridH2Row row = rowDesc.createRow(rowBuilder, null); assert row.version() != null; return row; } + + /** + * @param link Link. + * @param mvccCrdVer Mvcc coordinator version. + * @param mvccCntr Mvcc counter. + * @return Row. + * @throws IgniteCheckedException If failed. + */ + public GridH2Row getMvccRow(long link, long mvccCrdVer, long mvccCntr) throws IgniteCheckedException { + MvccDataRow row = new MvccDataRow(cctx.group(), + 0, + link, + -1, // TODO IGNITE-3478: get partition from link. + null, + mvccCrdVer, + mvccCntr); + + return rowDesc.createRow(row, null); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/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 index fcfeb16..df77f7a 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 @@ -29,15 +29,22 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusMeta import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList; import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasInnerIO; import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasLeafIO; +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.GridH2SearchRow; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.h2.result.SearchRow; import org.h2.table.IndexColumn; import org.h2.value.Value; +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.MVCC_COUNTER_NA; +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.assertMvccVersionValid; +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.unmaskCoordinatorVersion; + /** */ -public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { +public abstract class H2Tree extends BPlusTree<GridH2SearchRow, GridH2Row> { /** */ private final H2RowFactory rowStore; @@ -54,6 +61,9 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { private final int[] columnIds; /** */ + private final boolean mvccEnabled; + + /** */ private final Comparator<Value> comp = new Comparator<Value>() { @Override public int compare(Value o1, Value o2) { return compareValues(o1, o2); @@ -69,9 +79,10 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { * @param rowStore Row data store. * @param metaPageId Meta page ID. * @param initNew Initialize new index. + * @param mvccEnabled Mvcc flag. * @throws IgniteCheckedException If failed. */ - protected H2Tree( + H2Tree( String name, ReuseList reuseList, int grpId, @@ -83,7 +94,8 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { boolean initNew, IndexColumn[] cols, List<InlineIndexHelper> inlineIdxs, - int inlineSize + int inlineSize, + boolean mvccEnabled ) throws IgniteCheckedException { super(name, grpId, pageMem, wal, globalRmvId, metaPageId, reuseList); @@ -93,6 +105,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { } this.inlineSize = inlineSize; + this.mvccEnabled = mvccEnabled; assert rowStore != null; @@ -105,7 +118,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { for (int i = 0; i < cols.length; i++) columnIds[i] = cols[i].column.getColumnId(); - setIos(H2ExtrasInnerIO.getVersions(inlineSize), H2ExtrasLeafIO.getVersions(inlineSize)); + setIos(H2ExtrasInnerIO.getVersions(inlineSize, mvccEnabled), H2ExtrasLeafIO.getVersions(inlineSize, mvccEnabled)); initTree(initNew, inlineSize); } @@ -118,7 +131,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { } /** {@inheritDoc} */ - @Override protected GridH2Row getRow(BPlusIO<SearchRow> io, long pageAddr, int idx, Object ignore) + @Override protected GridH2Row getRow(BPlusIO<GridH2SearchRow> io, long pageAddr, int idx, Object ignore) throws IgniteCheckedException { return (GridH2Row)io.getLookupRow(this, pageAddr, idx); } @@ -159,8 +172,8 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { /** {@inheritDoc} */ @SuppressWarnings("ForLoopReplaceableByForEach") - @Override protected int compare(BPlusIO<SearchRow> io, long pageAddr, int idx, - SearchRow row) throws IgniteCheckedException { + @Override protected int compare(BPlusIO<GridH2SearchRow> io, long pageAddr, int idx, + GridH2SearchRow row) throws IgniteCheckedException { if (inlineSize() == 0) return compareRows(getRow(io, pageAddr, idx), row); else { @@ -195,7 +208,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { } if (lastIdxUsed == cols.length) - return 0; + return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row); SearchRow rowData = getRow(io, pageAddr, idx); @@ -207,7 +220,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { if (v2 == null) { // Can't compare further. - return 0; + return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row); } Value v1 = rowData.getValue(idx0); @@ -218,7 +231,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { return InlineIndexHelper.fixSort(c, col.sortType); } - return 0; + return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row); } } @@ -229,7 +242,9 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { * @param r2 Row 2. * @return Compare result. */ - private int compareRows(GridH2Row r1, SearchRow r2) { + private int compareRows(GridH2Row r1, GridH2SearchRow r2) { + assert !mvccEnabled || r2.indexSearchRow() || assertMvccVersionValid(r2.mvccCoordinatorVersion(), r2.mvccCounter()) : r2; + if (r1 == r2) return 0; @@ -241,7 +256,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { if (v1 == null || v2 == null) { // Can't compare further. - return 0; + return mvccCompare(r1, r2); } int c = compareValues(v1, v2); @@ -250,6 +265,64 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { return InlineIndexHelper.fixSort(c, cols[i].sortType); } + return mvccCompare(r1, r2); + } + + /** + * @param io IO. + * @param pageAddr Page address. + * @param idx Item index. + * @param r2 Search row. + * @return Comparison result. + */ + private int mvccCompare(H2RowLinkIO io, long pageAddr, int idx, GridH2SearchRow r2) { + if (mvccEnabled && !r2.indexSearchRow()) { + long crdVer1 = io.getMvccCoordinatorVersion(pageAddr, idx); + long crdVer2 = r2.mvccCoordinatorVersion(); + + assert crdVer1 != 0; + assert crdVer2 != 0 : r2; + + int c = Long.compare(unmaskCoordinatorVersion(crdVer1), unmaskCoordinatorVersion(crdVer2)); + + if (c != 0) + return c; + + long cntr = io.getMvccCounter(pageAddr, idx); + + assert cntr != MVCC_COUNTER_NA; + assert r2.mvccCounter() != MVCC_COUNTER_NA : r2; + + return Long.compare(cntr, r2.mvccCounter()); + } + + return 0; + } + + /** + * @param r1 First row. + * @param r2 Second row. + * @return Comparison result. + */ + private int mvccCompare(GridH2Row r1, GridH2SearchRow r2) { + if (mvccEnabled && !r2.indexSearchRow()) { + long crdVer1 = r1.mvccCoordinatorVersion(); + long crdVer2 = r2.mvccCoordinatorVersion(); + + assert crdVer1 != 0 : r1; + assert crdVer2 != 0 : r2; + + int c = Long.compare(unmaskCoordinatorVersion(crdVer1), unmaskCoordinatorVersion(crdVer2)); + + if (c != 0) + return c; + + assert r1.mvccCounter() != MVCC_COUNTER_NA : r1; + assert r2.mvccCounter() != MVCC_COUNTER_NA : r2; + + return Long.compare(r1.mvccCounter(), r2.mvccCounter()); + } + return 0; } @@ -259,4 +332,9 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> { * @return Comparison result. */ public abstract int compareValues(Value v1, Value v2); + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(H2Tree.class, this, "super", super.toString()); + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/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 index 3c0ab5e..87a6eca 100644 --- 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 @@ -29,7 +29,9 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; import org.apache.ignite.internal.processors.query.h2.H2Cursor; import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; import org.apache.ignite.internal.util.IgniteTree; import org.apache.ignite.internal.util.lang.GridCursor; @@ -118,7 +120,8 @@ public class H2TreeIndex extends GridH2IndexBase { page.isAllocated(), cols, inlineIdxs, - computeInlineSize(inlineIdxs, inlineSize)) { + computeInlineSize(inlineIdxs, inlineSize), + cctx.mvccEnabled()) { @Override public int compareValues(Value v1, Value v2) { return v1 == v2 ? 0 : table.compareTypeSafe(v1, v2); } @@ -165,20 +168,33 @@ public class H2TreeIndex extends GridH2IndexBase { /** {@inheritDoc} */ @Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) { try { - IndexingQueryFilter f = threadLocalFilter(); + assert lower == null || lower instanceof GridH2SearchRow : lower; + assert upper == null || upper instanceof GridH2SearchRow : upper; + IndexingQueryCacheFilter p = null; + H2TreeMvccFilterClosure mvccFilter = null; + + GridH2QueryContext qctx = GridH2QueryContext.get(); + + if (qctx != null) { + IndexingQueryFilter f = qctx.filter(); + + if (f != null) { + String cacheName = getTable().cacheName(); - if (f != null) { - String cacheName = getTable().cacheName(); + p = f.forCache(cacheName); + } - p = f.forCache(cacheName); + mvccFilter = qctx.mvccFilter(); } int seg = threadLocalSegment(); H2Tree tree = treeForRead(seg); - return new H2Cursor(tree.find(lower, upper), p); + assert !cctx.mvccEnabled() || mvccFilter != null; + + return new H2Cursor(tree.find((GridH2SearchRow)lower, (GridH2SearchRow)upper, mvccFilter, null), p); } catch (IgniteCheckedException e) { throw DbException.convert(e); @@ -205,7 +221,28 @@ public class H2TreeIndex extends GridH2IndexBase { } /** {@inheritDoc} */ + @Override public boolean putx(GridH2Row row) { + try { + InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs); + + int seg = segmentForRow(row); + + H2Tree tree = treeForRead(seg); + + return tree.putx(row); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + finally { + InlineIndexHelper.clearCurrentInlineIndexes(); + } + } + + /** {@inheritDoc} */ @Override public GridH2Row remove(SearchRow row) { + assert row instanceof GridH2SearchRow : row; + try { InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs); @@ -213,7 +250,7 @@ public class H2TreeIndex extends GridH2IndexBase { H2Tree tree = treeForRead(seg); - return tree.remove(row); + return tree.remove((GridH2SearchRow)row); } catch (IgniteCheckedException e) { throw DbException.convert(e); @@ -225,6 +262,8 @@ public class H2TreeIndex extends GridH2IndexBase { /** {@inheritDoc} */ @Override public void removex(SearchRow row) { + assert row instanceof GridH2SearchRow : row; + try { InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs); @@ -232,7 +271,7 @@ public class H2TreeIndex extends GridH2IndexBase { H2Tree tree = treeForRead(seg); - tree.removex(row); + tree.removex((GridH2SearchRow)row); } catch (IgniteCheckedException e) { throw DbException.convert(e); @@ -282,6 +321,17 @@ public class H2TreeIndex extends GridH2IndexBase { H2Tree tree = treeForRead(seg); + if (cctx.mvccEnabled()) { + GridH2QueryContext qctx = GridH2QueryContext.get(); + + assert qctx != null; + + H2TreeMvccFilterClosure mvccFilter = qctx.mvccFilter(); + + assert mvccFilter != null; + // TODO IGNITE-3478 (support filter for first/last) + } + GridH2Row row = b ? tree.findFirst(): tree.findLast(); return new SingleRowCursor(row); @@ -321,11 +371,13 @@ public class H2TreeIndex extends GridH2IndexBase { @Override protected GridCursor<GridH2Row> doFind0( IgniteTree t, @Nullable SearchRow first, - boolean includeFirst, @Nullable SearchRow last, - IndexingQueryFilter filter) { + IndexingQueryFilter filter, + H2TreeMvccFilterClosure mvccFilter) { try { - GridCursor<GridH2Row> range = t.find(first, last); + assert !cctx.mvccEnabled() || mvccFilter != null; + + GridCursor<GridH2Row> range = ((BPlusTree)t).find(first, last, mvccFilter, null); if (range == null) return EMPTY_CURSOR; http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeMvccFilterClosure.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeMvccFilterClosure.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeMvccFilterClosure.java new file mode 100644 index 0000000..6ae2312 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeMvccFilterClosure.java @@ -0,0 +1,106 @@ +/* + * 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.IgniteCheckedException; +import org.apache.ignite.internal.processors.cache.mvcc.MvccCoordinatorVersion; +import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +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.GridH2SearchRow; +import org.apache.ignite.internal.util.typedef.internal.S; + +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.assertMvccVersionValid; +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.unmaskCoordinatorVersion; + +/** + * + */ +public class H2TreeMvccFilterClosure implements H2Tree.TreeRowClosure<GridH2SearchRow, GridH2Row> { + /** */ + private final MvccCoordinatorVersion mvccVer; + + /** + * @param mvccVer Mvcc version. + */ + public H2TreeMvccFilterClosure(MvccCoordinatorVersion mvccVer) { + assert mvccVer != null; + + this.mvccVer = mvccVer; + } + + /** {@inheritDoc} */ + @Override public boolean apply(BPlusTree<GridH2SearchRow, GridH2Row> tree, + BPlusIO<GridH2SearchRow> io, + long pageAddr, + int idx) throws IgniteCheckedException { + H2RowLinkIO rowIo = (H2RowLinkIO)io; + + assert rowIo.storeMvccInfo() : rowIo; + + long rowCrdVer = rowIo.getMvccCoordinatorVersion(pageAddr, idx); + + assert unmaskCoordinatorVersion(rowCrdVer) == rowCrdVer : rowCrdVer; + assert rowCrdVer > 0 : rowCrdVer; + + int cmp = Long.compare(mvccVer.coordinatorVersion(), rowCrdVer); + + if (cmp == 0) { + long rowCntr = rowIo.getMvccCounter(pageAddr, idx); + + cmp = Long.compare(mvccVer.counter(), rowCntr); + + return cmp >= 0 && + !newVersionAvailable(rowIo, pageAddr, idx) && + !mvccVer.activeTransactions().contains(rowCntr); + } + else + return cmp > 0; + } + + /** + * @param rowIo Row IO. + * @param pageAddr Page address. + * @param idx Item index. + * @return {@code True} + */ + private boolean newVersionAvailable(H2RowLinkIO rowIo, long pageAddr, int idx) { + long newCrdVer = rowIo.getNewMvccCoordinatorVersion(pageAddr, idx); + + if (newCrdVer == 0) + return false; + + int cmp = Long.compare(mvccVer.coordinatorVersion(), newCrdVer); + + if (cmp == 0) { + long newCntr = rowIo.getNewMvccCounter(pageAddr, idx); + + assert assertMvccVersionValid(newCrdVer, newCntr); + + return newCntr <= mvccVer.counter() && !mvccVer.activeTransactions().contains(newCntr); + } + else + return cmp < 0; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(H2TreeMvccFilterClosure.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasInnerIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasInnerIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasInnerIO.java new file mode 100644 index 0000000..550aade --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasInnerIO.java @@ -0,0 +1,190 @@ +/* + * 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.io; + +import java.util.List; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageUtils; +import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusInnerIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; +import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; + +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.MVCC_COUNTER_NA; + +/** + * Inner page for H2 row references. + */ +public abstract class AbstractH2ExtrasInnerIO extends BPlusInnerIO<GridH2SearchRow> implements H2RowLinkIO { + /** Payload size. */ + private final int payloadSize; + + /** */ + public static void register() { + register(false); + + register(true); + } + + /** + * @param mvcc Mvcc flag. + */ + private static void register(boolean mvcc) { + short type = mvcc ? PageIO.T_H2_EX_REF_MVCC_INNER_START : PageIO.T_H2_EX_REF_INNER_START; + + for (short payload = 1; payload <= PageIO.MAX_PAYLOAD_SIZE; payload++) { + IOVersions<? extends AbstractH2ExtrasInnerIO> io = + getVersions((short)(type + payload - 1), payload, mvcc); + + PageIO.registerH2ExtraInner(io, mvcc); + } + } + + /** + * @param payload Payload size. + * @param mvccEnabled Mvcc flag. + * @return IOVersions for given payload. + */ + @SuppressWarnings("unchecked") + public static IOVersions<? extends BPlusInnerIO<GridH2SearchRow>> getVersions(int payload, boolean mvccEnabled) { + assert payload >= 0 && payload <= PageIO.MAX_PAYLOAD_SIZE; + + if (payload == 0) + return mvccEnabled ? H2MvccInnerIO.VERSIONS : H2InnerIO.VERSIONS; + else + return (IOVersions<BPlusInnerIO<GridH2SearchRow>>)PageIO.getInnerVersions((short)(payload - 1), mvccEnabled); + } + + /** + * @param type Type. + * @param payload Payload size. + * @param mvcc Mvcc flag. + * @return Instance of IO versions. + */ + private static IOVersions<? extends AbstractH2ExtrasInnerIO> getVersions(short type, short payload, boolean mvcc) { + return new IOVersions<>(mvcc ? new H2MvccExtrasInnerIO(type, 1, payload) : new H2ExtrasInnerIO(type, 1, payload)); + } + + /** + * @param type Page type. + * @param ver Page format version. + * @param itemSize Item size. + * @param payloadSize Payload size. + */ + AbstractH2ExtrasInnerIO(short type, int ver, int itemSize, int payloadSize) { + super(type, ver, true, itemSize + payloadSize); + + this.payloadSize = payloadSize; + } + + /** {@inheritDoc} */ + @SuppressWarnings("ForLoopReplaceableByForEach") + @Override public final void storeByOffset(long pageAddr, int off, GridH2SearchRow row) { + GridH2Row row0 = (GridH2Row)row; + + assert row0.link() != 0 : row0; + + List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes(); + + assert inlineIdxs != null : "no inline index helpers"; + + + int fieldOff = 0; + + for (int i = 0; i < inlineIdxs.size(); i++) { + InlineIndexHelper idx = inlineIdxs.get(i); + + int size = idx.put(pageAddr, off + fieldOff, row.getValue(idx.columnIndex()), payloadSize - fieldOff); + + if (size == 0) + break; + + fieldOff += size; + } + + H2IOUtils.storeRow(row0, pageAddr, off + payloadSize, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final GridH2SearchRow getLookupRow(BPlusTree<GridH2SearchRow, ?> tree, long pageAddr, int idx) + throws IgniteCheckedException { + long link = getLink(pageAddr, idx); + + assert link != 0; + + if (storeMvccInfo()) { + long mvccCrdVer = getMvccCoordinatorVersion(pageAddr, idx); + long mvccCntr = getMvccCounter(pageAddr, idx); + + return ((H2Tree)tree).getRowFactory().getMvccRow(link, mvccCrdVer, mvccCntr); + } + + return ((H2Tree)tree).getRowFactory().getRow(link); + } + + /** {@inheritDoc} */ + @Override public final void store(long dstPageAddr, int dstIdx, BPlusIO<GridH2SearchRow> srcIo, long srcPageAddr, int srcIdx) { + int srcOff = srcIo.offset(srcIdx); + + byte[] payload = PageUtils.getBytes(srcPageAddr, srcOff, payloadSize); + long link = PageUtils.getLong(srcPageAddr, srcOff + payloadSize); + + assert link != 0; + + int dstOff = offset(dstIdx); + + PageUtils.putBytes(dstPageAddr, dstOff, payload); + + H2IOUtils.store(dstPageAddr, dstOff + payloadSize, srcIo, srcPageAddr, srcIdx, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final long getLink(long pageAddr, int idx) { + return PageUtils.getLong(pageAddr, offset(idx) + payloadSize); + } + + /** {@inheritDoc} */ + @Override public long getMvccCoordinatorVersion(long pageAddr, int idx) { + return 0; + } + + /** {@inheritDoc} */ + @Override public long getMvccCounter(long pageAddr, int idx) { + return MVCC_COUNTER_NA; + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCoordinatorVersion(long pageAddr, int idx) { + return 0; + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCounter(long pageAddr, int idx) { + return MVCC_COUNTER_NA; + } + + /** {@inheritDoc} */ + @Override public boolean storeMvccInfo() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasLeafIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasLeafIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasLeafIO.java new file mode 100644 index 0000000..7beecf2 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasLeafIO.java @@ -0,0 +1,187 @@ +/* + * 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.io; + +import java.util.List; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageUtils; +import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusLeafIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; +import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; + +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.MVCC_COUNTER_NA; + +/** + * Leaf page for H2 row references. + */ +public class AbstractH2ExtrasLeafIO extends BPlusLeafIO<GridH2SearchRow> implements H2RowLinkIO { + /** Payload size. */ + private final int payloadSize; + + /** */ + public static void register() { + register(false); + + register(true); + } + + /** + * @param mvcc Mvcc flag. + */ + private static void register(boolean mvcc) { + short type = mvcc ? PageIO.T_H2_EX_REF_MVCC_LEAF_START : PageIO.T_H2_EX_REF_LEAF_START; + + for (short payload = 1; payload <= PageIO.MAX_PAYLOAD_SIZE; payload++) { + IOVersions<? extends AbstractH2ExtrasLeafIO> io = + getVersions((short)(type + payload - 1), payload, mvcc); + + PageIO.registerH2ExtraLeaf(io, mvcc); + } + } + + /** + * @param payload Payload size. + * @param mvccEnabled Mvcc flag. + * @return IOVersions for given payload. + */ + @SuppressWarnings("unchecked") + public static IOVersions<? extends BPlusLeafIO<GridH2SearchRow>> getVersions(int payload, boolean mvccEnabled) { + assert payload >= 0 && payload <= PageIO.MAX_PAYLOAD_SIZE; + + if (payload == 0) + return mvccEnabled ? H2MvccLeafIO.VERSIONS : H2LeafIO.VERSIONS; + else + return (IOVersions<BPlusLeafIO<GridH2SearchRow>>)PageIO.getLeafVersions((short)(payload - 1), mvccEnabled); + } + + /** + * @param type Type. + * @param payload Payload size. + * @param mvcc Mvcc flag. + * @return Versions. + */ + private static IOVersions<? extends AbstractH2ExtrasLeafIO> getVersions(short type, short payload, boolean mvcc) { + return new IOVersions<>(mvcc ? new H2MvccExtrasLeafIO(type, 1, payload) : new H2ExtrasLeafIO(type, 1, payload)); + } + + /** + * @param type Page type. + * @param ver Page format version. + * @param itemSize Item size. + * @param payloadSize Payload size. + */ + AbstractH2ExtrasLeafIO(short type, int ver, int itemSize, int payloadSize) { + super(type, ver, itemSize + payloadSize); + + this.payloadSize = payloadSize; + } + + /** {@inheritDoc} */ + @SuppressWarnings("ForLoopReplaceableByForEach") + @Override public final void storeByOffset(long pageAddr, int off, GridH2SearchRow row) { + GridH2Row row0 = (GridH2Row)row; + + assert row0.link() != 0; + + List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes(); + + assert inlineIdxs != null : "no inline index helpers"; + + int fieldOff = 0; + + for (int i = 0; i < inlineIdxs.size(); i++) { + InlineIndexHelper idx = inlineIdxs.get(i); + + int size = idx.put(pageAddr, off + fieldOff, row.getValue(idx.columnIndex()), payloadSize - fieldOff); + + if (size == 0) + break; + + fieldOff += size; + } + + H2IOUtils.storeRow(row0, pageAddr, off + payloadSize, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final void store(long dstPageAddr, int dstIdx, BPlusIO<GridH2SearchRow> srcIo, long srcPageAddr, int srcIdx) { + int srcOff = srcIo.offset(srcIdx); + + byte[] payload = PageUtils.getBytes(srcPageAddr, srcOff, payloadSize); + long link = PageUtils.getLong(srcPageAddr, srcOff + payloadSize); + + assert link != 0; + + int dstOff = offset(dstIdx); + + PageUtils.putBytes(dstPageAddr, dstOff, payload); + + H2IOUtils.store(dstPageAddr, dstOff + payloadSize, srcIo, srcPageAddr, srcIdx, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final GridH2SearchRow getLookupRow(BPlusTree<GridH2SearchRow, ?> tree, long pageAddr, int idx) + throws IgniteCheckedException { + long link = getLink(pageAddr, idx); + + if (storeMvccInfo()) { + long mvccCrdVer = getMvccCoordinatorVersion(pageAddr, idx); + long mvccCntr = getMvccCounter(pageAddr, idx); + + return ((H2Tree)tree).getRowFactory().getMvccRow(link, mvccCrdVer, mvccCntr); + } + + return ((H2Tree)tree).getRowFactory().getRow(link); + } + + /** {@inheritDoc} */ + @Override public final long getLink(long pageAddr, int idx) { + return PageUtils.getLong(pageAddr, offset(idx) + payloadSize); + } + + /** {@inheritDoc} */ + @Override public long getMvccCoordinatorVersion(long pageAddr, int idx) { + return 0; + } + + /** {@inheritDoc} */ + @Override public long getMvccCounter(long pageAddr, int idx) { + return MVCC_COUNTER_NA; + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCoordinatorVersion(long pageAddr, int idx) { + return 0; + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCounter(long pageAddr, int idx) { + return MVCC_COUNTER_NA; + } + + /** {@inheritDoc} */ + @Override public boolean storeMvccInfo() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2InnerIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2InnerIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2InnerIO.java new file mode 100644 index 0000000..2f12e75 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2InnerIO.java @@ -0,0 +1,106 @@ +/* + * 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.io; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageUtils; +import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusInnerIO; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; + +/** + * Inner page for H2 row references. + */ +public abstract class AbstractH2InnerIO extends BPlusInnerIO<GridH2SearchRow> implements H2RowLinkIO { + /** + * @param type Page type. + * @param ver Page format version. + * @param itemSize Single item size on page. + */ + AbstractH2InnerIO(int type, int ver, int itemSize) { + super(type, ver, true, itemSize); + } + + /** {@inheritDoc} */ + @Override public boolean storeMvccInfo() { + return false; + } + + /** {@inheritDoc} */ + @Override public void storeByOffset(long pageAddr, int off, GridH2SearchRow row) { + GridH2Row row0 = (GridH2Row)row; + + H2IOUtils.storeRow(row0, pageAddr, off, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public GridH2SearchRow getLookupRow(BPlusTree<GridH2SearchRow, ?> tree, long pageAddr, int idx) + throws IgniteCheckedException { + long link = getLink(pageAddr, idx); + + if (storeMvccInfo()) { + long mvccCrdVer = getMvccCoordinatorVersion(pageAddr, idx); + long mvccCntr = getMvccCounter(pageAddr, idx); + + return ((H2Tree)tree).getRowFactory().getMvccRow(link, mvccCrdVer, mvccCntr); + } + + return ((H2Tree)tree).getRowFactory().getRow(link); + } + + /** {@inheritDoc} */ + @Override public void store(long dstPageAddr, int dstIdx, BPlusIO<GridH2SearchRow> srcIo, long srcPageAddr, int srcIdx) { + H2IOUtils.store(dstPageAddr, offset(dstIdx), srcIo, srcPageAddr, srcIdx, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public long getLink(long pageAddr, int idx) { + return PageUtils.getLong(pageAddr, offset(idx)); + } + + /** {@inheritDoc} */ + @Override public long getMvccCoordinatorVersion(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 8); + } + + /** {@inheritDoc} */ + @Override public long getMvccCounter(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 16); + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCoordinatorVersion(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 24); + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCounter(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 32); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2LeafIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2LeafIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2LeafIO.java new file mode 100644 index 0000000..a5cf7c2 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2LeafIO.java @@ -0,0 +1,108 @@ +/* + * 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.io; + +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageUtils; +import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusLeafIO; +import org.apache.ignite.internal.processors.query.h2.database.H2Tree; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; + +/** + * Leaf page for H2 row references. + */ +public abstract class AbstractH2LeafIO extends BPlusLeafIO<GridH2SearchRow> implements H2RowLinkIO { + /** + * @param type Page type. + * @param ver Page format version. + * @param itemSize Single item size on page. + */ + AbstractH2LeafIO(int type, int ver, int itemSize) { + super(type, ver, itemSize); + } + + /** {@inheritDoc} */ + @Override public boolean storeMvccInfo() { + return false; + } + + /** {@inheritDoc} */ + @Override public final void storeByOffset(long pageAddr, int off, GridH2SearchRow row) { + GridH2Row row0 = (GridH2Row)row; + + H2IOUtils.storeRow(row0, pageAddr, off, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final void store(long dstPageAddr, int dstIdx, BPlusIO<GridH2SearchRow> srcIo, long srcPageAddr, int srcIdx) { + assert srcIo == this; + + H2IOUtils.store(dstPageAddr, offset(dstIdx), srcIo, srcPageAddr, srcIdx, storeMvccInfo()); + } + + /** {@inheritDoc} */ + @Override public final GridH2SearchRow getLookupRow(BPlusTree<GridH2SearchRow,?> tree, long pageAddr, int idx) + throws IgniteCheckedException { + long link = getLink(pageAddr, idx); + + if (storeMvccInfo()) { + long mvccCrdVer = getMvccCoordinatorVersion(pageAddr, idx); + long mvccCntr = getMvccCounter(pageAddr, idx); + + return ((H2Tree)tree).getRowFactory().getMvccRow(link, mvccCrdVer, mvccCntr); + } + + return ((H2Tree)tree).getRowFactory().getRow(link); + } + + /** {@inheritDoc} */ + @Override public long getLink(long pageAddr, int idx) { + return PageUtils.getLong(pageAddr, offset(idx)); + } + + /** {@inheritDoc} */ + @Override public long getMvccCoordinatorVersion(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 8); + } + + /** {@inheritDoc} */ + @Override public long getMvccCounter(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 16); + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCoordinatorVersion(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 24); + } + + /** {@inheritDoc} */ + @Override public long getNewMvccCounter(long pageAddr, int idx) { + assert storeMvccInfo(); + + return PageUtils.getLong(pageAddr, offset(idx) + 32); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java index b8877e9..8dc8c96 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java @@ -17,124 +17,17 @@ package org.apache.ignite.internal.processors.query.h2.database.io; -import java.util.List; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.pagemem.PageUtils; -import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusInnerIO; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; -import org.apache.ignite.internal.processors.query.h2.database.H2Tree; -import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; -import org.h2.result.SearchRow; - /** * Inner page for H2 row references. */ -public class H2ExtrasInnerIO extends BPlusInnerIO<SearchRow> { - /** Payload size. */ - private final int payloadSize; - - /** */ - public static void register() { - for (short payload = 1; payload <= PageIO.MAX_PAYLOAD_SIZE; payload++) - PageIO.registerH2ExtraInner(getVersions((short)(PageIO.T_H2_EX_REF_INNER_START + payload - 1), payload)); - } - - /** - * @param payload Payload size. - * @return IOVersions for given payload. - */ - @SuppressWarnings("unchecked") - public static IOVersions<? extends BPlusInnerIO<SearchRow>> getVersions(int payload) { - assert payload >= 0 && payload <= PageIO.MAX_PAYLOAD_SIZE; - - if (payload == 0) - return H2InnerIO.VERSIONS; - else - return (IOVersions<BPlusInnerIO<SearchRow>>)PageIO.getInnerVersions((short)(payload - 1)); - } - - /** - * @param type Type. - * @param payload Payload size. - * @return Instance of IO versions. - */ - private static IOVersions<H2ExtrasInnerIO> getVersions(short type, short payload) { - return new IOVersions<>(new H2ExtrasInnerIO(type, 1, payload)); - } - +public class H2ExtrasInnerIO extends AbstractH2ExtrasInnerIO implements H2RowLinkIO { /** * @param type Page type. * @param ver Page format version. * @param payloadSize Payload size. */ - private H2ExtrasInnerIO(short type, int ver, int payloadSize) { - super(type, ver, true, 8 + payloadSize); - this.payloadSize = payloadSize; - } - - /** {@inheritDoc} */ - @SuppressWarnings("ForLoopReplaceableByForEach") - @Override public void storeByOffset(long pageAddr, int off, SearchRow row) { - GridH2Row row0 = (GridH2Row)row; - - assert row0.link() != 0 : row0; - - List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes(); - - assert inlineIdxs != null : "no inline index helpers"; - - - int fieldOff = 0; - - for (int i = 0; i < inlineIdxs.size(); i++) { - InlineIndexHelper idx = inlineIdxs.get(i); - - int size = idx.put(pageAddr, off + fieldOff, row.getValue(idx.columnIndex()), payloadSize - fieldOff); - - if (size == 0) - break; - - fieldOff += size; - } - - PageUtils.putLong(pageAddr, off + payloadSize, row0.link()); - } - - /** {@inheritDoc} */ - @Override public SearchRow getLookupRow(BPlusTree<SearchRow, ?> tree, long pageAddr, int idx) - throws IgniteCheckedException { - long link = getLink(pageAddr, idx); - - assert link != 0; - - return ((H2Tree)tree).getRowFactory().getRow(link); - } - - /** {@inheritDoc} */ - @Override public void store(long dstPageAddr, int dstIdx, BPlusIO<SearchRow> srcIo, long srcPageAddr, int srcIdx) { - int srcOff = srcIo.offset(srcIdx); - - byte[] payload = PageUtils.getBytes(srcPageAddr, srcOff, payloadSize); - long link = PageUtils.getLong(srcPageAddr, srcOff + payloadSize); - - assert link != 0; - - int dstOff = offset(dstIdx); - - PageUtils.putBytes(dstPageAddr, dstOff, payload); - PageUtils.putLong(dstPageAddr, dstOff + payloadSize, link); - } - - /** - * @param pageAddr Page address. - * @param idx Index. - * @return Link to row. - */ - private long getLink(long pageAddr, int idx) { - return PageUtils.getLong(pageAddr, offset(idx) + payloadSize); + H2ExtrasInnerIO(short type, int ver, int payloadSize) { + super(type, ver, 8, payloadSize); } } + http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java index 6161f8d..085f98b 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java @@ -17,121 +17,16 @@ package org.apache.ignite.internal.processors.query.h2.database.io; -import java.util.List; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.pagemem.PageUtils; -import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusLeafIO; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.IOVersions; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; -import org.apache.ignite.internal.processors.query.h2.database.H2Tree; -import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; -import org.h2.result.SearchRow; - /** * Leaf page for H2 row references. */ -public class H2ExtrasLeafIO extends BPlusLeafIO<SearchRow> { - /** Payload size. */ - private final int payloadSize; - - /** */ - public static void register() { - for (short payload = 1; payload <= PageIO.MAX_PAYLOAD_SIZE; payload++) - PageIO.registerH2ExtraLeaf(getVersions((short)(PageIO.T_H2_EX_REF_LEAF_START + payload - 1), payload)); - } - - /** - * @param payload Payload size. - * @return IOVersions for given payload. - */ - @SuppressWarnings("unchecked") - public static IOVersions<? extends BPlusLeafIO<SearchRow>> getVersions(int payload) { - assert payload >= 0 && payload <= PageIO.MAX_PAYLOAD_SIZE; - - if (payload == 0) - return H2LeafIO.VERSIONS; - else - return (IOVersions<BPlusLeafIO<SearchRow>>)PageIO.getLeafVersions((short)(payload - 1)); - } - - /** - * @param type Type. - * @param payload Payload size. - * @return Versions. - */ - private static IOVersions<H2ExtrasLeafIO> getVersions(short type, short payload) { - return new IOVersions<>(new H2ExtrasLeafIO(type, 1, payload)); - } - +public class H2ExtrasLeafIO extends AbstractH2ExtrasLeafIO { /** * @param type Page type. * @param ver Page format version. * @param payloadSize Payload size. */ - private H2ExtrasLeafIO(short type, int ver, int payloadSize) { - super(type, ver, 8 + payloadSize); - this.payloadSize = payloadSize; - } - - /** {@inheritDoc} */ - @SuppressWarnings("ForLoopReplaceableByForEach") - @Override public void storeByOffset(long pageAddr, int off, SearchRow row) { - GridH2Row row0 = (GridH2Row)row; - - assert row0.link() != 0; - - List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes(); - - assert inlineIdxs != null : "no inline index helpers"; - - int fieldOff = 0; - - for (int i = 0; i < inlineIdxs.size(); i++) { - InlineIndexHelper idx = inlineIdxs.get(i); - - int size = idx.put(pageAddr, off + fieldOff, row.getValue(idx.columnIndex()), payloadSize - fieldOff); - - if (size == 0) - break; - - fieldOff += size; - } - - PageUtils.putLong(pageAddr, off + payloadSize, row0.link()); - } - - /** {@inheritDoc} */ - @Override public void store(long dstPageAddr, int dstIdx, BPlusIO<SearchRow> srcIo, long srcPageAddr, int srcIdx) { - int srcOff = srcIo.offset(srcIdx); - - byte[] payload = PageUtils.getBytes(srcPageAddr, srcOff, payloadSize); - long link = PageUtils.getLong(srcPageAddr, srcOff + payloadSize); - - assert link != 0; - - int dstOff = offset(dstIdx); - - PageUtils.putBytes(dstPageAddr, dstOff, payload); - PageUtils.putLong(dstPageAddr, dstOff + payloadSize, link); - } - - /** {@inheritDoc} */ - @Override public SearchRow getLookupRow(BPlusTree<SearchRow, ?> tree, long pageAddr, int idx) - throws IgniteCheckedException { - long link = getLink(pageAddr, idx); - - return ((H2Tree)tree).getRowFactory().getRow(link); - } - - /** - * @param pageAddr Page address. - * @param idx Index. - * @return Link to row. - */ - private long getLink(long pageAddr, int idx) { - return PageUtils.getLong(pageAddr, offset(idx) + payloadSize); + H2ExtrasLeafIO(short type, int ver, int payloadSize) { + super(type, ver, 8, payloadSize); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2IOUtils.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2IOUtils.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2IOUtils.java new file mode 100644 index 0000000..c0b2314 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2IOUtils.java @@ -0,0 +1,113 @@ +/* + * 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.io; + +import org.apache.ignite.internal.pagemem.PageUtils; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2SearchRow; + +import static org.apache.ignite.internal.processors.cache.mvcc.CacheCoordinatorsProcessor.assertMvccVersionValid; + +/** + * + */ +class H2IOUtils { + /** + * + */ + private H2IOUtils() {} + + /** + * @param row Row. + * @param pageAddr Page address. + * @param off Offset. + * @param storeMvcc {@code True} to store mvcc data. + */ + static void storeRow(GridH2Row row, long pageAddr, int off, boolean storeMvcc) { + assert row.link() != 0; + + PageUtils.putLong(pageAddr, off, row.link()); + + if (storeMvcc) { + long mvccCrdVer = row.mvccCoordinatorVersion(); + long mvccCntr = row.mvccCounter(); + + assert assertMvccVersionValid(mvccCrdVer, mvccCntr); + + PageUtils.putLong(pageAddr, off + 8, mvccCrdVer); + PageUtils.putLong(pageAddr, off + 16, mvccCntr); + + long newMvccCrdVer = row.newMvccCoordinatorVersion(); + + PageUtils.putLong(pageAddr, off + 24, newMvccCrdVer); + + if (newMvccCrdVer != 0) { + long newMvccCntr = row.newMvccCounter(); + + assert assertMvccVersionValid(newMvccCrdVer, newMvccCntr); + + PageUtils.putLong(pageAddr, off + 32, newMvccCntr); + } + } + } + + /** + * @param dstPageAddr Destination page address. + * @param dstOff Destination page offset. + * @param srcIo Source IO. + * @param srcPageAddr Source page address. + * @param srcIdx Source index. + * @param storeMvcc {@code True} to store mvcc data. + */ + static void store(long dstPageAddr, + int dstOff, + BPlusIO<GridH2SearchRow> srcIo, + long srcPageAddr, + int srcIdx, + boolean storeMvcc) + { + H2RowLinkIO rowIo = (H2RowLinkIO)srcIo; + + long link = rowIo.getLink(srcPageAddr, srcIdx); + + PageUtils.putLong(dstPageAddr, dstOff, link); + + if (storeMvcc) { + long mvccCrdVer = rowIo.getMvccCoordinatorVersion(srcPageAddr, srcIdx); + long mvccCntr = rowIo.getMvccCounter(srcPageAddr, srcIdx); + + assert assertMvccVersionValid(mvccCrdVer, mvccCntr); + + PageUtils.putLong(dstPageAddr, dstOff + 8, mvccCrdVer); + PageUtils.putLong(dstPageAddr, dstOff + 16, mvccCntr); + + long newMvccCrdVer = rowIo.getNewMvccCoordinatorVersion(srcPageAddr, srcIdx); + + PageUtils.putLong(dstPageAddr, dstOff + 24, newMvccCrdVer); + + if (newMvccCrdVer != 0) { + long newMvccCntr = rowIo.getNewMvccCounter(srcPageAddr, srcIdx); + + assertMvccVersionValid(newMvccCrdVer, newMvccCntr); + + PageUtils.putLong(dstPageAddr, dstOff + 32, newMvccCntr); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6150f3a0/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 a1f1ce9..9baff7a 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 @@ -17,20 +17,12 @@ package org.apache.ignite.internal.processors.query.h2.database.io; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.pagemem.PageUtils; -import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusIO; -import org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusInnerIO; import org.apache.ignite.internal.processors.cache.persistence.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; /** * Inner page for H2 row references. */ -public class H2InnerIO extends BPlusInnerIO<SearchRow> implements H2RowLinkIO { +public class H2InnerIO extends AbstractH2InnerIO { /** */ public static final IOVersions<H2InnerIO> VERSIONS = new IOVersions<>( new H2InnerIO(1) @@ -40,35 +32,6 @@ public class H2InnerIO extends BPlusInnerIO<SearchRow> implements H2RowLinkIO { * @param ver Page format version. */ private H2InnerIO(int ver) { - super(T_H2_REF_INNER, ver, true, 8); - } - - /** {@inheritDoc} */ - @Override public void storeByOffset(long pageAddr, int off, SearchRow row) { - GridH2Row row0 = (GridH2Row)row; - - assert row0.link() != 0; - - PageUtils.putLong(pageAddr, off, row0.link()); - } - - /** {@inheritDoc} */ - @Override public SearchRow getLookupRow(BPlusTree<SearchRow,?> tree, long pageAddr, int idx) - throws IgniteCheckedException { - long link = getLink(pageAddr, idx); - - return ((H2Tree)tree).getRowFactory().getRow(link); - } - - /** {@inheritDoc} */ - @Override public void store(long dstPageAddr, int dstIdx, BPlusIO<SearchRow> srcIo, long srcPageAddr, int srcIdx) { - long link = ((H2RowLinkIO)srcIo).getLink(srcPageAddr, srcIdx); - - PageUtils.putLong(dstPageAddr, offset(dstIdx), link); - } - - /** {@inheritDoc} */ - @Override public long getLink(long pageAddr, int idx) { - return PageUtils.getLong(pageAddr, offset(idx)); + super(T_H2_REF_INNER, ver, 8); } }
