You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2018/08/30 11:53:32 UTC
[10/38] ignite git commit: IGNITE-4191: MVCC and transactional SQL
support. Joint multi-man-years efforts of Semen Boikov, Igor Seliverstov,
Alexander Paschenko, Igor Sapego, Sergey Kalashnikov, Roman Kondakov,
Pavel Kuznetsov, Ivan Pavlukhin, Andrey Mas
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/PreparedStatementExImpl.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/PreparedStatementExImpl.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/PreparedStatementExImpl.java
new file mode 100644
index 0000000..922c1ab
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/PreparedStatementExImpl.java
@@ -0,0 +1,648 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLType;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Calendar;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * PreparedStatement with extended capability to store additional meta information.
+ */
+@SuppressWarnings("unchecked")
+final class PreparedStatementExImpl implements PreparedStatementEx {
+ /** */
+ private final PreparedStatement delegate;
+
+ /** */
+ private Object[] meta = null;
+
+ /**
+ * @param delegate Wrapped statement.
+ */
+ public PreparedStatementExImpl(PreparedStatement delegate) {
+ this.delegate = delegate;
+ }
+
+ /** {@inheritDoc} */
+ @Override public ResultSet executeQuery() throws SQLException {
+ return delegate.executeQuery();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int executeUpdate() throws SQLException {
+ return delegate.executeUpdate();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ delegate.setNull(parameterIndex, sqlType);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ delegate.setBoolean(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setByte(int parameterIndex, byte x) throws SQLException {
+ delegate.setByte(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setShort(int parameterIndex, short x) throws SQLException {
+ delegate.setShort(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setInt(int parameterIndex, int x) throws SQLException {
+ delegate.setInt(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setLong(int parameterIndex, long x) throws SQLException {
+ delegate.setLong(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setFloat(int parameterIndex, float x) throws SQLException {
+ delegate.setFloat(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setDouble(int parameterIndex, double x) throws SQLException {
+ delegate.setDouble(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ delegate.setBigDecimal(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setString(int parameterIndex, String x) throws SQLException {
+ delegate.setString(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+ delegate.setBytes(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setDate(int parameterIndex, Date x) throws SQLException {
+ delegate.setDate(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setTime(int parameterIndex, Time x) throws SQLException {
+ delegate.setTime(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ delegate.setTimestamp(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ delegate.setAsciiStream(parameterIndex, x, length);
+ }
+
+ /** {@inheritDoc} */
+ @Deprecated
+ @Override public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ delegate.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ delegate.setBinaryStream(parameterIndex, x, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void clearParameters() throws SQLException {
+ delegate.clearParameters();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ delegate.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setObject(int parameterIndex, Object x) throws SQLException {
+ delegate.setObject(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean execute() throws SQLException {
+ return delegate.execute();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addBatch() throws SQLException {
+ delegate.addBatch();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ delegate.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setRef(int parameterIndex, Ref x) throws SQLException {
+ delegate.setRef(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ delegate.setBlob(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setClob(int parameterIndex, Clob x) throws SQLException {
+ delegate.setClob(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setArray(int parameterIndex, Array x) throws SQLException {
+ delegate.setArray(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ResultSetMetaData getMetaData() throws SQLException {
+ return delegate.getMetaData();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ delegate.setDate(parameterIndex, x, cal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ delegate.setTime(parameterIndex, x, cal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ delegate.setTimestamp(parameterIndex, x, cal);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ delegate.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setURL(int parameterIndex, URL x) throws SQLException {
+ delegate.setURL(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ParameterMetaData getParameterMetaData() throws SQLException {
+ return delegate.getParameterMetaData();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ delegate.setRowId(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNString(int parameterIndex, String value) throws SQLException {
+ delegate.setNString(parameterIndex, value);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ delegate.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ delegate.setNClob(parameterIndex, value);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ delegate.setClob(parameterIndex, reader, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ delegate.setBlob(parameterIndex, inputStream, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ delegate.setNClob(parameterIndex, reader, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ delegate.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ @Override
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ delegate.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ delegate.setAsciiStream(parameterIndex, x, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ delegate.setBinaryStream(parameterIndex, x, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ delegate.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ delegate.setAsciiStream(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ delegate.setBinaryStream(parameterIndex, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ delegate.setCharacterStream(parameterIndex, reader);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ delegate.setNCharacterStream(parameterIndex, value);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ delegate.setClob(parameterIndex, reader);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ delegate.setBlob(parameterIndex, inputStream);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ delegate.setNClob(parameterIndex, reader);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException {
+ delegate.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throws SQLException {
+ delegate.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long executeLargeUpdate() throws SQLException {
+ return delegate.executeLargeUpdate();
+ }
+
+ /** {@inheritDoc} */
+ @Override public ResultSet executeQuery(String sql) throws SQLException {
+ return delegate.executeQuery(sql);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int executeUpdate(String sql) throws SQLException {
+ return delegate.executeUpdate(sql);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void close() throws SQLException {
+ delegate.close();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getMaxFieldSize() throws SQLException {
+ return delegate.getMaxFieldSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setMaxFieldSize(int max) throws SQLException {
+ delegate.setMaxFieldSize(max);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getMaxRows() throws SQLException {
+ return delegate.getMaxRows();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setMaxRows(int max) throws SQLException {
+ delegate.setMaxRows(max);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setEscapeProcessing(boolean enable) throws SQLException {
+ delegate.setEscapeProcessing(enable);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getQueryTimeout() throws SQLException {
+ return delegate.getQueryTimeout();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setQueryTimeout(int seconds) throws SQLException {
+ delegate.setQueryTimeout(seconds);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void cancel() throws SQLException {
+ delegate.cancel();
+ }
+
+ /** {@inheritDoc} */
+ @Override public SQLWarning getWarnings() throws SQLException {
+ return delegate.getWarnings();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void clearWarnings() throws SQLException {
+ delegate.clearWarnings();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setCursorName(String name) throws SQLException {
+ delegate.setCursorName(name);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean execute(String sql) throws SQLException {
+ return delegate.execute(sql);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ResultSet getResultSet() throws SQLException {
+ return delegate.getResultSet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getUpdateCount() throws SQLException {
+ return delegate.getUpdateCount();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean getMoreResults() throws SQLException {
+ return delegate.getMoreResults();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getFetchDirection() throws SQLException {
+ return delegate.getFetchDirection();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setFetchDirection(int direction) throws SQLException {
+ delegate.setFetchDirection(direction);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getFetchSize() throws SQLException {
+ return delegate.getFetchSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setFetchSize(int rows) throws SQLException {
+ delegate.setFetchSize(rows);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getResultSetConcurrency() throws SQLException {
+ return delegate.getResultSetConcurrency();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getResultSetType() throws SQLException {
+ return delegate.getResultSetType();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addBatch(String sql) throws SQLException {
+ delegate.addBatch(sql);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void clearBatch() throws SQLException {
+ delegate.clearBatch();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int[] executeBatch() throws SQLException {
+ return delegate.executeBatch();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Connection getConnection() throws SQLException {
+ return delegate.getConnection();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean getMoreResults(int current) throws SQLException {
+ return delegate.getMoreResults(current);
+ }
+
+ /** {@inheritDoc} */
+ @Override public ResultSet getGeneratedKeys() throws SQLException {
+ return delegate.getGeneratedKeys();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ return delegate.executeUpdate(sql, autoGeneratedKeys);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+ return delegate.executeUpdate(sql, columnIndexes);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+ return delegate.executeUpdate(sql, columnNames);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ return delegate.execute(sql, autoGeneratedKeys);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+ return delegate.execute(sql, columnIndexes);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean execute(String sql, String[] columnNames) throws SQLException {
+ return delegate.execute(sql, columnNames);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int getResultSetHoldability() throws SQLException {
+ return delegate.getResultSetHoldability();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isClosed() throws SQLException {
+ return delegate.isClosed();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isPoolable() throws SQLException {
+ return delegate.isPoolable();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setPoolable(boolean poolable) throws SQLException {
+ delegate.setPoolable(poolable);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void closeOnCompletion() throws SQLException {
+ delegate.closeOnCompletion();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isCloseOnCompletion() throws SQLException {
+ return delegate.isCloseOnCompletion();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLargeUpdateCount() throws SQLException {
+ return delegate.getLargeUpdateCount();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long getLargeMaxRows() throws SQLException {
+ return delegate.getLargeMaxRows();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setLargeMaxRows(long max) throws SQLException {
+ delegate.setLargeMaxRows(max);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long[] executeLargeBatch() throws SQLException {
+ return delegate.executeLargeBatch();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long executeLargeUpdate(String sql) throws SQLException {
+ return delegate.executeLargeUpdate(sql);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ return delegate.executeLargeUpdate(sql, autoGeneratedKeys);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
+ return delegate.executeLargeUpdate(sql, columnIndexes);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
+ return delegate.executeLargeUpdate(sql, columnNames);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <T> T unwrap(Class<T> iface) throws SQLException {
+ if (iface == PreparedStatementExImpl.class || iface == PreparedStatementEx.class)
+ return (T)this;
+
+ return delegate.unwrap(iface);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean isWrapperFor(Class<?> iface) throws SQLException {
+ return iface == PreparedStatementExImpl.class
+ || iface == PreparedStatementEx.class
+ || delegate.isWrapperFor(iface);
+ }
+
+ /** {@inheritDoc} */
+ @Override public @Nullable <T> T meta(int id) {
+ return meta != null && id < meta.length ? (T)meta[id] : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void putMeta(int id, Object metaObj) {
+ if (meta == null)
+ meta = new Object[id + 1];
+ else if (meta.length <= id)
+ meta = Arrays.copyOf(meta, id + 1);
+
+ meta[id] = metaObj;
+ }
+
+ /**
+ *
+ * @param stmt Prepared statement to wrap.
+ * @return Wrapped statement.
+ */
+ public static PreparedStatement wrap(@NotNull PreparedStatement stmt) {
+ if (stmt.getClass() == PreparedStatementExImpl.class)
+ return stmt;
+
+ return new PreparedStatementExImpl(stmt);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/RebuildIndexFromHashClosure.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/RebuildIndexFromHashClosure.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/RebuildIndexFromHashClosure.java
new file mode 100644
index 0000000..b635eac
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/RebuildIndexFromHashClosure.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
+import org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager;
+import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure;
+
+/** */
+class RebuildIndexFromHashClosure implements SchemaIndexCacheVisitorClosure {
+ /** */
+ private final GridCacheQueryManager qryMgr;
+
+ /** MVCC status flag. */
+ private final boolean mvccEnabled;
+
+ /**
+ * @param qryMgr Query manager.
+ * @param mvccEnabled MVCC status flag.
+ */
+ RebuildIndexFromHashClosure(GridCacheQueryManager qryMgr, boolean mvccEnabled) {
+ this.qryMgr = qryMgr;
+ this.mvccEnabled = mvccEnabled;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void apply(CacheDataRow row) throws IgniteCheckedException {
+ // prevRowAvailable is always true with MVCC on, and always false *on index rebuild* with MVCC off.
+ qryMgr.store(row, null, mvccEnabled);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ResultSetEnlistFuture.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ResultSetEnlistFuture.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ResultSetEnlistFuture.java
new file mode 100644
index 0000000..ee1c0fa
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ResultSetEnlistFuture.java
@@ -0,0 +1,136 @@
+/*
+ * 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;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.DhtLockFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxLocalAdapter;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
+import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.processors.query.EnlistOperation;
+import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.UpdateSourceIterator;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Future to process whole local result set of SELECT FOR UPDATE query.
+ */
+public interface ResultSetEnlistFuture extends DhtLockFuture<Long> {
+ /**
+ * @param rs Result set.
+ * @return Update source.
+ */
+ static UpdateSourceIterator<?> createIterator(ResultSet rs) {
+ return new ResultSetUpdateSourceIteratorWrapper(rs);
+ }
+
+ /** */
+ void init();
+
+ /**
+ *
+ * @param nearNodeId Near node ID.
+ * @param nearLockVer Near lock version.
+ * @param mvccSnapshot Mvcc snapshot.
+ * @param threadId Thread ID.
+ * @param nearFutId Near future id.
+ * @param nearMiniId Near mini future id.
+ * @param parts Partitions.
+ * @param tx Transaction.
+ * @param timeout Lock acquisition timeout.
+ * @param cctx Cache context.
+ * @param rs Result set to process.
+ * @return Result set enlist future.
+ */
+ static ResultSetEnlistFuture future(UUID nearNodeId, GridCacheVersion nearLockVer,
+ MvccSnapshot mvccSnapshot, long threadId, IgniteUuid nearFutId, int nearMiniId, @Nullable int[] parts,
+ GridDhtTxLocalAdapter tx, long timeout, GridCacheContext<?, ?> cctx, ResultSet rs) {
+
+ if (tx.near())
+ return new NearResultSetEnlistFuture(nearNodeId, nearLockVer, mvccSnapshot, threadId, nearFutId, nearMiniId, parts, tx, timeout, cctx, rs);
+ else
+ return new DhtResultSetEnlistFuture(nearNodeId, nearLockVer, mvccSnapshot, threadId, nearFutId, nearMiniId, parts, tx, timeout, cctx, rs);
+ }
+
+ /**
+ *
+ */
+ public static class ResultSetUpdateSourceIteratorWrapper implements UpdateSourceIterator<Object> {
+ /** */
+ private static final long serialVersionUID = -8745196216234843471L;
+
+ /** */
+ private final ResultSet rs;
+
+ /** */
+ private Boolean hasNext;
+
+ /** */
+ private int keyColIdx;
+
+ /**
+ * @param rs Result set.
+ */
+ public ResultSetUpdateSourceIteratorWrapper(ResultSet rs) {
+ this.rs = rs;
+ keyColIdx = -1;
+ }
+
+ /** {@inheritDoc} */
+ @Override public EnlistOperation operation() {
+ return EnlistOperation.LOCK;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNextX() {
+ try {
+ if (hasNext == null)
+ hasNext = rs.next();
+
+ return hasNext;
+ }
+ catch (SQLException e) {
+ throw new IgniteSQLException(e);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object nextX() {
+ if (!hasNextX())
+ throw new NoSuchElementException();
+
+ try {
+ if (keyColIdx == -1)
+ keyColIdx = rs.getMetaData().getColumnCount();
+
+ return rs.getObject(keyColIdx);
+ }
+ catch (SQLException e) {
+ throw new IgniteSQLException(e);
+ }
+ finally {
+ hasNext = null;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ThreadLocalObjectPool.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ThreadLocalObjectPool.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ThreadLocalObjectPool.java
new file mode 100644
index 0000000..25daa23
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/ThreadLocalObjectPool.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.function.Supplier;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ * Special pool for managing limited number objects for further reuse.
+ * This pool maintains separate object bag for each thread by means of {@link ThreadLocal}.
+ * <p>
+ * If object is borrowed on one thread and recycled on different then it will be returned to
+ * recycling thread bag. For thread-safe use either pooled objects should be thread-safe or
+ * <i>happens-before</i> should be established between borrowing object and subsequent recycling.
+ *
+ * @param <E> pooled objects type
+ */
+public final class ThreadLocalObjectPool<E extends AutoCloseable> {
+ /**
+ * Wrapper for a pooled object with capability to return the object to a pool.
+ *
+ * @param <T> enclosed object type
+ */
+ public static class Reusable<T extends AutoCloseable> {
+ /** */
+ private final ThreadLocalObjectPool<T> pool;
+ /** */
+ private final T object;
+
+ /** */
+ private Reusable(ThreadLocalObjectPool<T> pool, T object) {
+ this.pool = pool;
+ this.object = object;
+ }
+
+ /**
+ * @return enclosed object
+ */
+ public T object() {
+ return object;
+ }
+
+ /**
+ * Returns an object to a pool or closes it if the pool is already full.
+ */
+ public void recycle() {
+ Queue<Reusable<T>> bag = pool.bag.get();
+ if (bag.size() < pool.poolSize)
+ bag.add(this);
+ else
+ U.closeQuiet(object);
+ }
+ }
+
+ /** */
+ private final Supplier<E> objectFactory;
+ /** */
+ private final ThreadLocal<Queue<Reusable<E>>> bag = ThreadLocal.withInitial(LinkedList::new);
+ /** */
+ private final int poolSize;
+
+ /**
+ * @param objectFactory factory used for new objects creation
+ * @param poolSize number of objects which pool can contain
+ */
+ public ThreadLocalObjectPool(Supplier<E> objectFactory, int poolSize) {
+ this.objectFactory = objectFactory;
+ this.poolSize = poolSize;
+ }
+
+ /**
+ * Picks an object from the pool if one is present or creates new one otherwise.
+ * Returns an object wrapper which could be returned to the pool.
+ *
+ * @return reusable object wrapper
+ */
+ public Reusable<E> borrow() {
+ Reusable<E> pooled = bag.get().poll();
+ return pooled != null ? pooled : new Reusable<>(this, objectFactory.get());
+ }
+
+ /** Visible for test */
+ int bagSize() {
+ return bag.get().size();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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 546f5bb..5d877cd 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
@@ -19,6 +19,7 @@
package org.apache.ignite.internal.processors.query.h2.database;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -26,9 +27,12 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
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.GridH2RowDescriptor;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
import org.apache.ignite.internal.util.lang.GridCursor;
import org.apache.ignite.spi.indexing.IndexingQueryCacheFilter;
@@ -84,31 +88,30 @@ public class H2PkHashIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public Cursor find(Session ses, final SearchRow lower, final SearchRow upper) {
- IndexingQueryFilter f = threadLocalFilter();
- IndexingQueryCacheFilter p = null;
+ IndexingQueryCacheFilter filter = null;
+ MvccSnapshot mvccSnapshot = null;
- if (f != null) {
- String cacheName = getTable().cacheName();
+ GridH2QueryContext qctx = GridH2QueryContext.get();
- p = f.forCache(cacheName);
+ if (qctx != null) {
+ IndexingQueryFilter f = qctx.filter();
+ filter = f != null ? f.forCache(getTable().cacheName()) : null;
+ mvccSnapshot = qctx.mvccSnapshot();
}
- KeyCacheObject lowerObj = null;
- KeyCacheObject upperObj = null;
+ assert !cctx.mvccEnabled() || mvccSnapshot != null;
- if (lower != null)
- lowerObj = cctx.toCacheKeyObject(lower.getValue(0).getObject());
-
- if (upper != null)
- upperObj = cctx.toCacheKeyObject(upper.getValue(0).getObject());
+ KeyCacheObject lowerObj = lower != null ? cctx.toCacheKeyObject(lower.getValue(0).getObject()) : null;
+ KeyCacheObject upperObj = upper != null ? cctx.toCacheKeyObject(upper.getValue(0).getObject()) : null;
try {
- List<GridCursor<? extends CacheDataRow>> cursors = new ArrayList<>();
+ Collection<GridCursor<? extends CacheDataRow>> cursors = new ArrayList<>();
for (IgniteCacheOffheapManager.CacheDataStore store : cctx.offheap().cacheDataStores())
- cursors.add(store.cursor(cctx.cacheId(), lowerObj, upperObj));
+ if (filter == null || filter.applyPartition(store.partId()))
+ cursors.add(store.cursor(cctx.cacheId(), lowerObj, upperObj, null, mvccSnapshot));
- return new H2Cursor(new CompositeGridCursor<>(cursors.iterator()), p);
+ return new H2Cursor(cursors.iterator());
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -124,7 +127,6 @@ 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");
@@ -192,28 +194,29 @@ public class H2PkHashIndex extends GridH2IndexBase {
*/
private class H2Cursor implements Cursor {
/** */
- final GridCursor<? extends CacheDataRow> cursor;
+ private final GridH2RowDescriptor desc;
/** */
- final IndexingQueryCacheFilter filter;
+ private final Iterator<GridCursor<? extends CacheDataRow>> iter;
+
+ /** */
+ private GridCursor<? extends CacheDataRow> curr;
/**
- * @param cursor Cursor.
- * @param filter Filter.
+ * @param iter Cursors iterator.
*/
- private H2Cursor(GridCursor<? extends CacheDataRow> cursor, IndexingQueryCacheFilter filter) {
- assert cursor != null;
+ private H2Cursor(Iterator<GridCursor<? extends CacheDataRow>> iter) {
+ assert iter != null;
- this.cursor = cursor;
- this.filter = filter;
+ this.iter = iter;
+
+ desc = tbl.rowDescriptor();
}
/** {@inheritDoc} */
@Override public Row get() {
try {
- CacheDataRow dataRow = cursor.get();
-
- return tbl.rowDescriptor().createRow(dataRow);
+ return desc.createRow(curr.get());
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -228,13 +231,13 @@ public class H2PkHashIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public boolean next() {
try {
- while (cursor.next()) {
- if (filter == null)
- return true;
+ if (curr != null && curr.next())
+ return true;
- CacheDataRow dataRow = cursor.get();
+ while (iter.hasNext()) {
+ curr = iter.next();
- if (filter.applyPartition(dataRow.partition()))
+ if (curr.next())
return true;
}
@@ -250,45 +253,4 @@ public class H2PkHashIndex extends GridH2IndexBase {
throw DbException.getUnsupportedException("previous");
}
}
-
- /**
- *
- */
- private static class CompositeGridCursor<T> implements GridCursor<T> {
- /** */
- private final Iterator<GridCursor<? extends T>> iter;
-
- /** */
- private GridCursor<? extends T> curr;
-
- /**
- *
- */
- public CompositeGridCursor(Iterator<GridCursor<? extends T>> iter) {
- this.iter = iter;
-
- if (iter.hasNext())
- curr = iter.next();
- }
-
- /** {@inheritDoc} */
- @Override public boolean next() throws IgniteCheckedException {
- if (curr.next())
- return true;
-
- while (iter.hasNext()) {
- curr = iter.next();
-
- if (curr.next())
- return true;
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public T get() throws IgniteCheckedException {
- return curr.get();
- }
- }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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..724de7e 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,10 @@
package org.apache.ignite.internal.processors.query.h2.database;
import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.pagemem.PageIdUtils;
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.mvcc.data.MvccDataRow;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
@@ -60,17 +61,23 @@ 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);
assert row.version() != null;
return row;
}
+
+ /**
+ * @param link Link.
+ * @param mvccCrdVer Mvcc coordinator version.
+ * @param mvccCntr Mvcc counter.
+ * @param mvccOpCntr Mvcc operation counter.
+ * @return Row.
+ * @throws IgniteCheckedException If failed.
+ */
+ public GridH2Row getMvccRow(long link, long mvccCrdVer, long mvccCntr, int mvccOpCntr) throws IgniteCheckedException {
+ return rowDesc.createRow(new MvccDataRow(cctx.group(),0, link,
+ PageIdUtils.partId(PageIdUtils.pageId(link)),null, mvccCrdVer, mvccCntr, mvccOpCntr));
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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 424969e..ce40df0 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
@@ -21,9 +21,9 @@ import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.pagemem.PageMemory;
import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
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.BPlusMetaIO;
@@ -35,8 +35,9 @@ 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.GridH2KeyValueRowOnheap;
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.apache.ignite.spi.indexing.IndexingQueryCacheFilter;
import org.h2.result.SearchRow;
import org.h2.table.IndexColumn;
import org.h2.value.Value;
@@ -44,7 +45,7 @@ import org.jetbrains.annotations.Nullable;
/**
*/
-public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
+public abstract class H2Tree extends BPlusTree<GridH2SearchRow, GridH2Row> {
/** */
private final H2RowFactory rowStore;
@@ -61,6 +62,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);
@@ -82,6 +86,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
* @param metaPageId Meta page ID.
* @param initNew Initialize new index.
* @param rowCache Row cache.
+ * @param mvccEnabled Mvcc flag.
* @param failureProcessor if the tree is corrupted.
* @throws IgniteCheckedException If failed.
*/
@@ -98,6 +103,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
IndexColumn[] cols,
List<InlineIndexHelper> inlineIdxs,
int inlineSize,
+ boolean mvccEnabled,
@Nullable H2RowCache rowCache,
@Nullable FailureProcessor failureProcessor
) throws IgniteCheckedException {
@@ -109,6 +115,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
}
this.inlineSize = inlineSize;
+ this.mvccEnabled = mvccEnabled;
assert rowStore != null;
@@ -121,9 +128,9 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
for (int i = 0; i < cols.length; i++)
columnIds[i] = cols[i].column.getColumnId();
- this.rowCache = rowCache;
+ setIos(H2ExtrasInnerIO.getVersions(inlineSize, mvccEnabled), H2ExtrasLeafIO.getVersions(inlineSize, mvccEnabled));
- setIos(H2ExtrasInnerIO.getVersions(inlineSize), H2ExtrasLeafIO.getVersions(inlineSize));
+ this.rowCache = rowCache;
initTree(initNew, inlineSize);
}
@@ -152,21 +159,34 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
return rowStore.getRow(link);
}
- /** {@inheritDoc} */
- @Override protected GridH2Row getRow(BPlusIO<SearchRow> io, long pageAddr, int idx, Object filter)
- throws IgniteCheckedException {
- if (filter != null) {
- // Filter out not interesting partitions without deserializing the row.
- IndexingQueryCacheFilter filter0 = (IndexingQueryCacheFilter)filter;
+ /**
+ * Create row from link.
+ *
+ * @param link Link.
+ * @param mvccOpCntr
+ * @return Row.
+ * @throws IgniteCheckedException if failed.
+ */
+ public GridH2Row createRowFromLink(long link, long mvccCrdVer, long mvccCntr, int mvccOpCntr) throws IgniteCheckedException {
+ if (rowCache != null) {
+ GridH2Row row = rowCache.get(link);
- long link = ((H2RowLinkIO)io).getLink(pageAddr, idx);
+ if (row == null) {
+ row = rowStore.getMvccRow(link, mvccCrdVer, mvccCntr, mvccOpCntr);
- int part = PageIdUtils.partId(PageIdUtils.pageId(link));
+ if (row instanceof GridH2KeyValueRowOnheap)
+ rowCache.put((GridH2KeyValueRowOnheap)row);
+ }
- if (!filter0.applyPartition(part))
- return null;
+ return row;
}
+ else
+ return rowStore.getMvccRow(link, mvccCrdVer, mvccCntr, mvccOpCntr);
+ }
+ /** {@inheritDoc} */
+ @Override public GridH2Row getRow(BPlusIO<GridH2SearchRow> io, long pageAddr, int idx, Object ignore)
+ throws IgniteCheckedException {
return (GridH2Row)io.getLookupRow(this, pageAddr, idx);
}
@@ -206,8 +226,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 {
@@ -242,7 +262,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);
@@ -254,7 +274,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);
@@ -265,7 +285,7 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
return InlineIndexHelper.fixSort(c, col.sortType);
}
- return 0;
+ return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
}
}
@@ -276,7 +296,8 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
* @param r2 Row 2.
* @return Compare result: see {@link Comparator#compare(Object, Object)} for values.
*/
- public int compareRows(SearchRow r1, SearchRow r2) {
+ public int compareRows(GridH2SearchRow r1, GridH2SearchRow r2) {
+ assert !mvccEnabled || r2.indexSearchRow() || MvccUtils.mvccVersionIsValid(r2.mvccCoordinatorVersion(), r2.mvccCounter()) : r2;
if (r1 == r2)
return 0;
@@ -288,7 +309,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);
@@ -297,7 +318,47 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
return InlineIndexHelper.fixSort(c, cols[i].sortType);
}
- return 0;
+ 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())
+ return 0;
+
+ long crd = io.getMvccCoordinatorVersion(pageAddr, idx);
+ long cntr = io.getMvccCounter(pageAddr, idx);
+ int opCntr = io.getMvccOperationCounter(pageAddr, idx);
+
+ assert MvccUtils.mvccVersionIsValid(crd, cntr, opCntr);
+
+ return -MvccUtils.compare(crd, cntr, opCntr, r2); // descending order
+ }
+
+ /**
+ * @param r1 First row.
+ * @param r2 Second row.
+ * @return Comparison result.
+ */
+ private int mvccCompare(GridH2SearchRow r1, GridH2SearchRow r2) {
+ if (!mvccEnabled || r2.indexSearchRow())
+ return 0;
+
+ long crdVer1 = r1.mvccCoordinatorVersion();
+ long crdVer2 = r2.mvccCoordinatorVersion();
+
+ int c = -Long.compare(crdVer1, crdVer2);
+
+ if (c != 0)
+ return c;
+
+ return -Long.compare(r1.mvccCounter(), r2.mvccCounter());
}
/**
@@ -306,4 +367,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/00bb4d4d/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeFilterClosure.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeFilterClosure.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeFilterClosure.java
new file mode 100644
index 0000000..e583546
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeFilterClosure.java
@@ -0,0 +1,109 @@
+/*
+ * 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.pagemem.PageIdUtils;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
+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.transactions.IgniteTxMvccVersionCheckedException;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.spi.indexing.IndexingQueryCacheFilter;
+
+import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId;
+import static org.apache.ignite.internal.processors.cache.mvcc.MvccUtils.isVisible;
+import static org.apache.ignite.internal.processors.cache.mvcc.MvccUtils.mvccVersionIsValid;
+
+/**
+ *
+ */
+public class H2TreeFilterClosure implements H2Tree.TreeRowClosure<GridH2SearchRow, GridH2Row> {
+ /** */
+ private final MvccSnapshot mvccSnapshot;
+
+ /** */
+ private final IndexingQueryCacheFilter filter;
+
+ /** */
+ private final GridCacheContext cctx;
+
+ /**
+ * @param filter Cache filter.
+ * @param mvccSnapshot MVCC snapshot.
+ * @param cctx Cache context.
+ */
+ public H2TreeFilterClosure(IndexingQueryCacheFilter filter, MvccSnapshot mvccSnapshot, GridCacheContext cctx) {
+ assert (filter != null || mvccSnapshot != null) && cctx != null ;
+
+ this.filter = filter;
+ this.mvccSnapshot = mvccSnapshot;
+ this.cctx = cctx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean apply(BPlusTree<GridH2SearchRow, GridH2Row> tree, BPlusIO<GridH2SearchRow> io,
+ long pageAddr, int idx) throws IgniteCheckedException {
+ return (filter == null || applyFilter((H2RowLinkIO)io, pageAddr, idx))
+ && (mvccSnapshot == null || applyMvcc((H2RowLinkIO)io, pageAddr, idx));
+ }
+
+ /**
+ * @param io Row IO.
+ * @param pageAddr Page address.
+ * @param idx Item index.
+ * @return {@code True} if row passes the filter.
+ */
+ private boolean applyFilter(H2RowLinkIO io, long pageAddr, int idx) {
+ assert filter != null;
+
+ return filter.applyPartition(PageIdUtils.partId(pageId(io.getLink(pageAddr, idx))));
+ }
+
+ /**
+ * @param io Row IO.
+ * @param pageAddr Page address.
+ * @param idx Item index.
+ * @return {@code True} if row passes the filter.
+ */
+ private boolean applyMvcc(H2RowLinkIO io, long pageAddr, int idx) throws IgniteCheckedException {
+ assert io.storeMvccInfo() : io;
+
+ long rowCrdVer = io.getMvccCoordinatorVersion(pageAddr, idx);
+ long rowCntr = io.getMvccCounter(pageAddr, idx);
+ int rowOpCntr = io.getMvccOperationCounter(pageAddr, idx);
+
+ assert mvccVersionIsValid(rowCrdVer, rowCntr, rowOpCntr);
+
+ try {
+ return isVisible(cctx, mvccSnapshot, rowCrdVer, rowCntr, rowOpCntr, io.getLink(pageAddr, idx));
+ }
+ catch (IgniteTxMvccVersionCheckedException ignored) {
+ return false; // The row is going to be removed.
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(H2TreeFilterClosure.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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 393ca3b..ab6f42a 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
@@ -20,36 +20,34 @@ package org.apache.ignite.internal.processors.query.h2.database;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
-import java.util.NoSuchElementException;
-
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteSystemProperties;
-import org.apache.ignite.internal.pagemem.PageIdUtils;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.mvcc.MvccSnapshot;
import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
import org.apache.ignite.internal.processors.cache.persistence.RootPage;
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.PageIO;
import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
import org.apache.ignite.internal.processors.query.h2.H2Cursor;
import org.apache.ignite.internal.processors.query.h2.H2RowCache;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2Cursor;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase;
-import org.apache.ignite.internal.processors.query.h2.database.io.H2RowLinkIO;
+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;
import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.spi.indexing.IndexingQueryFilter;
import org.apache.ignite.spi.indexing.IndexingQueryCacheFilter;
+import org.apache.ignite.spi.indexing.IndexingQueryFilter;
import org.h2.engine.Session;
import org.h2.index.Cursor;
import org.h2.index.IndexType;
import org.h2.index.SingleRowCursor;
import org.h2.message.DbException;
-import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.result.SortOrder;
import org.h2.table.Column;
@@ -139,6 +137,7 @@ public class H2TreeIndex extends GridH2IndexBase {
cols,
inlineIdxs,
computeInlineSize(inlineIdxs, inlineSize),
+ cctx.mvccEnabled(),
rowCache,
cctx.kernalContext().failure()) {
@Override public int compareValues(Value v1, Value v2) {
@@ -191,21 +190,22 @@ public class H2TreeIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) {
try {
- IndexingQueryCacheFilter filter = partitionFilter(threadLocalFilter());
+ assert lower == null || lower instanceof GridH2SearchRow : lower;
+ assert upper == null || upper instanceof GridH2SearchRow : upper;
int seg = threadLocalSegment();
H2Tree tree = treeForRead(seg);
- if (indexType.isPrimaryKey() && lower != null && upper != null && tree.compareRows(lower, upper) == 0) {
- GridH2Row row = tree.findOne(lower, filter);
+ if (!cctx.mvccEnabled() && indexType.isPrimaryKey() && lower != null && upper != null &&
+ tree.compareRows((GridH2SearchRow)lower, (GridH2SearchRow)upper) == 0) {
+ GridH2Row row = tree.findOne((GridH2SearchRow)lower, filter(GridH2QueryContext.get()), null);
- return (row == null) ? EMPTY_CURSOR : new SingleRowCursor(row);
+ return (row == null) ? GridH2Cursor.EMPTY : new SingleRowCursor(row);
}
else {
- GridCursor<GridH2Row> cursor = tree.find(lower, upper, filter);
-
- return new H2Cursor(cursor);
+ return new H2Cursor(tree.find((GridH2SearchRow)lower,
+ (GridH2SearchRow)upper, filter(GridH2QueryContext.get()), null));
}
}
catch (IgniteCheckedException e) {
@@ -257,6 +257,8 @@ public class H2TreeIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public GridH2Row remove(SearchRow row) {
+ assert row instanceof GridH2SearchRow : row;
+
try {
InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
@@ -266,7 +268,7 @@ public class H2TreeIndex extends GridH2IndexBase {
assert cctx.shared().database().checkpointLockIsHeldByThread();
- return tree.remove(row);
+ return tree.remove((GridH2SearchRow)row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -279,6 +281,8 @@ public class H2TreeIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public boolean removex(SearchRow row) {
try {
+ assert row instanceof GridH2SearchRow : row;
+
InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
int seg = segmentForRow(row);
@@ -287,7 +291,7 @@ public class H2TreeIndex extends GridH2IndexBase {
assert cctx.shared().database().checkpointLockIsHeldByThread();
- return tree.removex(row);
+ return tree.removex((GridH2SearchRow)row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -315,9 +319,9 @@ public class H2TreeIndex extends GridH2IndexBase {
H2Tree tree = treeForRead(seg);
- BPlusTree.TreeRowClosure<SearchRow, GridH2Row> filter = filterClosure();
+ GridH2QueryContext qctx = GridH2QueryContext.get();
- return tree.size(filter);
+ return tree.size(filter(qctx));
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -337,13 +341,10 @@ public class H2TreeIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public Cursor findFirstOrLast(Session session, boolean b) {
try {
- int seg = threadLocalSegment();
+ H2Tree tree = treeForRead(threadLocalSegment());
+ GridH2QueryContext qctx = GridH2QueryContext.get();
- H2Tree tree = treeForRead(seg);
-
- GridH2Row row = b ? tree.findFirst(): tree.findLast();
-
- return new SingleRowCursor(row);
+ return new SingleRowCursor(b ? tree.findFirst(filter(qctx)): tree.findLast(filter(qctx)));
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
@@ -382,16 +383,13 @@ public class H2TreeIndex extends GridH2IndexBase {
@Override protected H2Cursor doFind0(
IgniteTree t,
@Nullable SearchRow first,
- boolean includeFirst,
@Nullable SearchRow last,
- IndexingQueryFilter filter) {
+ BPlusTree.TreeRowClosure<GridH2SearchRow, GridH2Row> filter) {
try {
- IndexingQueryCacheFilter pf = partitionFilter(filter);
-
- GridCursor<GridH2Row> range = t.find(first, last, pf);
+ GridCursor<GridH2Row> range = ((BPlusTree)t).find(first, last, filter, null);
if (range == null)
- range = GridH2IndexBase.EMPTY_CURSOR;
+ range = EMPTY_CURSOR;
return new H2Cursor(range);
}
@@ -400,6 +398,26 @@ public class H2TreeIndex extends GridH2IndexBase {
}
}
+ /** {@inheritDoc} */
+ @Override protected BPlusTree.TreeRowClosure<GridH2SearchRow, GridH2Row> filter(GridH2QueryContext qctx) {
+ if (qctx == null) {
+ assert !cctx.mvccEnabled();
+
+ return null;
+ }
+
+ IndexingQueryFilter f = qctx.filter();
+ IndexingQueryCacheFilter p = f == null ? null : f.forCache(getTable().cacheName());
+ MvccSnapshot v = qctx.mvccSnapshot();
+
+ assert !cctx.mvccEnabled() || v != null;
+
+ if(p == null && v == null)
+ return null;
+
+ return new H2TreeFilterClosure(p, v, cctx);
+ }
+
/**
* @param inlineIdxs Inline index helpers.
* @param cfgInlineSize Inline size from cache config.
@@ -457,63 +475,6 @@ public class H2TreeIndex extends GridH2IndexBase {
cctx.offheap().dropRootPageForIndex(cctx.cacheId(), name + "%" + segIdx);
}
- /**
- * Returns a filter which returns true for entries belonging to a particular partition.
- *
- * @param qryFilter Factory that creates a predicate for filtering entries for a particular cache.
- * @return The filter or null if the filter is not needed (e.g., if the cache is not partitioned).
- */
- @Nullable private IndexingQueryCacheFilter partitionFilter(@Nullable IndexingQueryFilter qryFilter) {
- if (qryFilter == null)
- return null;
-
- String cacheName = getTable().cacheName();
-
- return qryFilter.forCache(cacheName);
- }
-
- /**
- * An adapter from {@link IndexingQueryCacheFilter} to {@link BPlusTree.TreeRowClosure} which
- * filters entries that belong to the current partition.
- */
- private static class PartitionFilterTreeRowClosure implements BPlusTree.TreeRowClosure<SearchRow, GridH2Row> {
- /** Filter. */
- private final IndexingQueryCacheFilter filter;
-
- /**
- * Creates a {@link BPlusTree.TreeRowClosure} adapter based on the given partition filter.
- *
- * @param filter The partition filter.
- */
- public PartitionFilterTreeRowClosure(IndexingQueryCacheFilter filter) {
- this.filter = filter;
- }
-
- /** {@inheritDoc} */
- @Override public boolean apply(BPlusTree<SearchRow, GridH2Row> tree,
- BPlusIO<SearchRow> io, long pageAddr, int idx) throws IgniteCheckedException {
-
- H2RowLinkIO h2io = (H2RowLinkIO)io;
-
- return filter.applyPartition(
- PageIdUtils.partId(
- PageIdUtils.pageId(
- h2io.getLink(pageAddr, idx))));
- }
- }
-
- /**
- * Returns a filter to apply to rows in the current index to obtain only the
- * ones owned by the this cache.
- *
- * @return The filter, which returns true for rows owned by this cache.
- */
- @Nullable private BPlusTree.TreeRowClosure<SearchRow, GridH2Row> filterClosure() {
- final IndexingQueryCacheFilter filter = partitionFilter(threadLocalFilter());
-
- return filter != null ? new PartitionFilterTreeRowClosure(filter) : null;
- }
-
/** {@inheritDoc} */
@Override public void refreshColumnIds() {
super.refreshColumnIds();
@@ -528,29 +489,4 @@ public class H2TreeIndex extends GridH2IndexBase {
for (int pos = 0; pos < inlineHelpers.size(); ++pos)
inlineIdxs.set(pos, inlineHelpers.get(pos));
}
-
- /**
- * Empty cursor.
- */
- public static final Cursor EMPTY_CURSOR = new Cursor() {
- /** {@inheritDoc} */
- @Override public Row get() {
- throw DbException.convert(new NoSuchElementException("Empty cursor"));
- }
-
- /** {@inheritDoc} */
- @Override public SearchRow getSearchRow() {
- throw DbException.convert(new NoSuchElementException("Empty cursor"));
- }
-
- /** {@inheritDoc} */
- @Override public boolean next() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public boolean previous() {
- return false;
- }
- };
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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..fbca917
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasInnerIO.java
@@ -0,0 +1,164 @@
+/*
+ * 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;
+
+/**
+ * Inner page for H2 row references.
+ */
+public abstract class AbstractH2ExtrasInnerIO extends BPlusInnerIO<GridH2SearchRow> implements H2RowLinkIO {
+ /** Payload size. */
+ protected 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);
+ int mvccOpCntr = getMvccOperationCounter(pageAddr, idx);
+
+ return ((H2Tree)tree).createRowFromLink(link, mvccCrdVer, mvccCntr, mvccOpCntr);
+ }
+
+ return ((H2Tree)tree).createRowFromLink(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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/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..9132795
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/AbstractH2ExtrasLeafIO.java
@@ -0,0 +1,161 @@
+/*
+ * 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;
+
+/**
+ * Leaf page for H2 row references.
+ */
+public abstract class AbstractH2ExtrasLeafIO extends BPlusLeafIO<GridH2SearchRow> implements H2RowLinkIO {
+ /** Payload size. */
+ protected 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);
+ int mvccOpCntr = getMvccOperationCounter(pageAddr, idx);
+
+ return ((H2Tree)tree).createRowFromLink(link, mvccCrdVer, mvccCntr, mvccOpCntr);
+ }
+
+ return ((H2Tree)tree).createRowFromLink(link);
+ }
+
+ /** {@inheritDoc} */
+ @Override public final long getLink(long pageAddr, int idx) {
+ return PageUtils.getLong(pageAddr, offset(idx) + payloadSize);
+ }
+}