You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by nt...@apache.org on 2017/08/15 18:00:02 UTC
[01/29] ignite git commit: IGNITE-4800: Lucene query may fails with
NPE. This closes #2315.
Repository: ignite
Updated Branches:
refs/heads/ignite-5947 [created] 49bc7fb41
IGNITE-4800: Lucene query may fails with NPE. This closes #2315.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1e08c3fb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1e08c3fb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1e08c3fb
Branch: refs/heads/ignite-5947
Commit: 1e08c3fb5c02ec8acafd71b50b6ad3b749259f1a
Parents: a07d7b9
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Jul 31 14:14:56 2017 +0300
Committer: Andrey V. Mashenkov <an...@gmail.com>
Committed: Mon Jul 31 17:24:26 2017 +0300
----------------------------------------------------------------------
.../query/h2/opt/GridLuceneDirectory.java | 64 +++++++++++---
.../processors/query/h2/opt/GridLuceneFile.java | 91 +++++++++++++++-----
.../query/h2/opt/GridLuceneIndex.java | 3 +-
.../query/h2/opt/GridLuceneInputStream.java | 42 ++++++---
.../query/h2/opt/GridLuceneOutputStream.java | 18 +++-
...teCacheFullTextQueryNodeJoiningSelfTest.java | 4 +
.../IgniteCacheQuerySelfTestSuite.java | 2 +
7 files changed, 178 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
index ff20987..3ac9641 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
@@ -21,22 +21,27 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.lucene.store.BaseDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.Accountables;
/**
* A memory-resident {@link Directory} implementation.
*/
-public class GridLuceneDirectory extends BaseDirectory {
+public class GridLuceneDirectory extends BaseDirectory implements Accountable {
/** */
protected final Map<String, GridLuceneFile> fileMap = new ConcurrentHashMap<>();
@@ -51,7 +56,7 @@ public class GridLuceneDirectory extends BaseDirectory {
*
* @param mem Memory.
*/
- public GridLuceneDirectory(GridUnsafeMemory mem) {
+ GridLuceneDirectory(GridUnsafeMemory mem) {
super(new GridLuceneLockFactory());
this.mem = mem;
@@ -64,10 +69,7 @@ public class GridLuceneDirectory extends BaseDirectory {
// and the code below is resilient to map changes during the array population.
Set<String> fileNames = fileMap.keySet();
- List<String> names = new ArrayList<>(fileNames.size());
-
- for (String name : fileNames)
- names.add(name);
+ List<String> names = new ArrayList<>(fileNames);
return names.toArray(new String[names.size()]);
}
@@ -82,6 +84,7 @@ public class GridLuceneDirectory extends BaseDirectory {
throw new FileNotFoundException(source);
fileMap.put(dest, file);
+
fileMap.remove(source);
}
@@ -101,21 +104,25 @@ public class GridLuceneDirectory extends BaseDirectory {
@Override public void deleteFile(String name) throws IOException {
ensureOpen();
- doDeleteFile(name);
+ doDeleteFile(name, false);
}
/**
* Deletes file.
*
* @param name File name.
+ * @param onClose If on close directory;
* @throws IOException If failed.
*/
- private void doDeleteFile(String name) throws IOException {
+ private void doDeleteFile(String name, boolean onClose) throws IOException {
GridLuceneFile file = fileMap.remove(name);
if (file != null) {
file.delete();
+ // All files should be closed when Directory is closing.
+ assert !onClose || !file.hasRefs() : "Possible memory leak, resource is not closed: " + file.toString();
+
sizeInBytes.addAndGet(-file.getSizeInBytes());
}
else
@@ -128,7 +135,10 @@ public class GridLuceneDirectory extends BaseDirectory {
GridLuceneFile file = newRAMFile();
- GridLuceneFile existing = fileMap.remove(name);
+ // Lock for using in stream. Will be unlocked on stream closing.
+ file.lockRef();
+
+ GridLuceneFile existing = fileMap.put(name, file);
if (existing != null) {
sizeInBytes.addAndGet(-existing.getSizeInBytes());
@@ -136,8 +146,6 @@ public class GridLuceneDirectory extends BaseDirectory {
existing.delete();
}
- fileMap.put(name, file);
-
return new GridLuceneOutputStream(file);
}
@@ -165,6 +173,16 @@ public class GridLuceneDirectory extends BaseDirectory {
if (file == null)
throw new FileNotFoundException(name);
+ // Lock for using in stream. Will be unlocked on stream closing.
+ file.lockRef();
+
+ if (!fileMap.containsKey(name)) {
+ // Unblock for deferred delete.
+ file.releaseRef();
+
+ throw new FileNotFoundException(name);
+ }
+
return new GridLuceneInputStream(name, file);
}
@@ -172,16 +190,36 @@ public class GridLuceneDirectory extends BaseDirectory {
@Override public void close() {
isOpen = false;
+ IgniteException errs = null;
+
for (String fileName : fileMap.keySet()) {
try {
- doDeleteFile(fileName);
+ doDeleteFile(fileName, true);
}
catch (IOException e) {
- throw new IllegalStateException(e);
+ if (errs == null)
+ errs = new IgniteException("Error closing index directory.");
+
+ errs.addSuppressed(e);
}
}
assert fileMap.isEmpty();
+
+ if (errs != null && !F.isEmpty(errs.getSuppressed()))
+ throw errs;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long ramBytesUsed() {
+ ensureOpen();
+
+ return sizeInBytes.get();
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized Collection<Accountable> getChildResources() {
+ return Accountables.namedAccountables("file", new HashMap<>(fileMap));
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
index 3985f09..d7ae132 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
@@ -17,22 +17,19 @@
package org.apache.ignite.internal.processors.query.h2.opt;
-import java.io.Serializable;
import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.lucene.util.Accountable;
import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutputStream.BUFFER_SIZE;
/**
* Lucene file.
*/
-public class GridLuceneFile implements Serializable {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** */
- public static final AtomicInteger filesCnt = new AtomicInteger();
-
+public class GridLuceneFile implements Accountable {
/** */
private LongArray buffers = new LongArray();
@@ -45,6 +42,12 @@ public class GridLuceneFile implements Serializable {
/** */
private volatile long sizeInBytes;
+ /** */
+ private final AtomicLong refCnt = new AtomicLong();
+
+ /** */
+ private final AtomicBoolean deleted = new AtomicBoolean();
+
/**
* File used as buffer, in no RAMDirectory
*
@@ -52,8 +55,6 @@ public class GridLuceneFile implements Serializable {
*/
GridLuceneFile(GridLuceneDirectory dir) {
this.dir = dir;
-
- filesCnt.incrementAndGet();
}
/**
@@ -93,51 +94,89 @@ public class GridLuceneFile implements Serializable {
}
/**
+ * Increment ref counter.
+ */
+ void lockRef() {
+ refCnt.incrementAndGet();
+ }
+
+ /**
+ * Decrement ref counter.
+ */
+ void releaseRef() {
+ refCnt.decrementAndGet();
+
+ deferredDelete();
+ }
+
+ /**
+ * Checks if there is file stream opened.
+ *
+ * @return {@code True} if file has external references.
+ */
+ boolean hasRefs() {
+ long refs = refCnt.get();
+
+ assert refs >= 0;
+
+ return refs != 0;
+ }
+
+ /**
* Gets address of buffer.
*
* @param idx Index.
* @return Pointer.
*/
- protected final synchronized long getBuffer(int idx) {
+ final synchronized long getBuffer(int idx) {
return buffers.get(idx);
}
/**
* @return Number of buffers.
*/
- protected final synchronized int numBuffers() {
+ final synchronized int numBuffers() {
return buffers.size();
}
/**
- * Expert: allocate a new buffer.
- * Subclasses can allocate differently.
+ * Expert: allocate a new buffer. Subclasses can allocate differently.
*
* @return allocated buffer.
*/
- protected long newBuffer() {
+ private long newBuffer() {
return dir.memory().allocate(BUFFER_SIZE);
}
/**
* Deletes file and deallocates memory..
*/
- public synchronized void delete() {
- if (buffers == null)
+ public void delete() {
+ if (!deleted.compareAndSet(false, true))
return;
+ deferredDelete();
+ }
+
+ /**
+ * Deferred delete.
+ */
+ synchronized void deferredDelete() {
+ if (!deleted.get() || hasRefs())
+ return;
+
+ assert refCnt.get() == 0;
+
for (int i = 0; i < buffers.idx; i++)
dir.memory().release(buffers.arr[i], BUFFER_SIZE);
buffers = null;
-
- filesCnt.decrementAndGet();
}
/**
* @return Size in bytes.
*/
- public long getSizeInBytes() {
+ long getSizeInBytes() {
return sizeInBytes;
}
@@ -148,6 +187,16 @@ public class GridLuceneFile implements Serializable {
return dir;
}
+ /** {@inheritDoc} */
+ @Override public long ramBytesUsed() {
+ return sizeInBytes;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<Accountable> getChildResources() {
+ return Collections.emptyList();
+ }
+
/**
* Simple expandable long[] wrapper.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
index eed5ee4..c51eb5d 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
@@ -296,7 +296,8 @@ public class GridLuceneIndex implements AutoCloseable {
/** {@inheritDoc} */
@Override public void close() {
U.closeQuiet(writer);
- U.closeQuiet(dir);
+
+ dir.close();
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
index 4820af1..9b1bf0c 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.query.h2.opt;
import java.io.EOFException;
import java.io.IOException;
import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
+import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.IndexInput;
import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutputStream.BUFFER_SIZE;
@@ -27,7 +28,7 @@ import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutpu
/**
* A memory-resident {@link IndexInput} implementation.
*/
-public class GridLuceneInputStream extends IndexInput {
+public class GridLuceneInputStream extends IndexInput implements Cloneable {
/** */
private GridLuceneFile file;
@@ -52,6 +53,11 @@ public class GridLuceneInputStream extends IndexInput {
/** */
private final GridUnsafeMemory mem;
+ /** */
+ private volatile boolean closed;
+
+ /** */
+ private boolean isClone;
/**
* Constructor.
*
@@ -91,7 +97,24 @@ public class GridLuceneInputStream extends IndexInput {
/** {@inheritDoc} */
@Override public void close() {
- // nothing to do here
+ if (!isClone) {
+ closed = true;
+
+ file.releaseRef();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public IndexInput clone() {
+ GridLuceneInputStream clone = (GridLuceneInputStream) super.clone();
+
+ if(closed)
+ throw new AlreadyClosedException(toString());
+
+ clone.isClone = true;
+
+ return clone;
+
}
/** {@inheritDoc} */
@@ -222,14 +245,16 @@ public class GridLuceneInputStream extends IndexInput {
public SlicedInputStream(String newResourceDescription, long offset, long length) throws IOException {
super(newResourceDescription, GridLuceneInputStream.this.file, offset + length);
+ // Avoid parent resource closing together with this.
+ super.isClone = true;
+
this.offset = offset;
seek(0L);
}
/** {@inheritDoc} */
- @Override
- public void seek(long pos) throws IOException {
+ @Override public void seek(long pos) throws IOException {
if (pos < 0L) {
throw new IllegalArgumentException("Seeking to negative position: " + this);
}
@@ -237,20 +262,17 @@ public class GridLuceneInputStream extends IndexInput {
}
/** {@inheritDoc} */
- @Override
- public long getFilePointer() {
+ @Override public long getFilePointer() {
return super.getFilePointer() - offset;
}
/** {@inheritDoc} */
- @Override
- public long length() {
+ @Override public long length() {
return super.length() - offset;
}
/** {@inheritDoc} */
- @Override
- public IndexInput slice(String sliceDescription, long ofs, long len) throws IOException {
+ @Override public IndexInput slice(String sliceDescription, long ofs, long len) throws IOException {
return super.slice(sliceDescription, offset + ofs, len);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
index caea226..d8f09df 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
@@ -18,17 +18,21 @@
package org.apache.ignite.internal.processors.query.h2.opt;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
import org.apache.lucene.store.BufferedChecksum;
import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.Accountables;
/**
* A memory-resident {@link IndexOutput} implementation.
*/
-public class GridLuceneOutputStream extends IndexOutput {
+public class GridLuceneOutputStream extends IndexOutput implements Accountable {
/** Off-heap page size. */
static final int BUFFER_SIZE = 32 * 1024;
@@ -93,6 +97,8 @@ public class GridLuceneOutputStream extends IndexOutput {
/** {@inheritDoc} */
@Override public void close() throws IOException {
flush();
+
+ file.releaseRef();
}
/** {@inheritDoc} */
@@ -201,4 +207,14 @@ public class GridLuceneOutputStream extends IndexOutput {
bufPosition += toCp;
}
}
+
+ /** {@inheritDoc} */
+ @Override public long ramBytesUsed() {
+ return file.getSizeInBytes();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<Accountable> getChildResources() {
+ return Collections.singleton(Accountables.namedAccountable("file", file));
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
index ba0324f..ed092df 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
@@ -119,6 +119,10 @@ public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstr
Ignite started = startGrid(GRID_CNT);
+ //TODO: remove next line when IGNITE-2229 issue will be fixed.
+ // see https://issues.apache.org/jira/browse/IGNITE-2229
+ awaitPartitionMapExchange();
+
for (int i = 0; i < 100; i++) {
QueryCursor<Cache.Entry<AffinityKey<Integer>, IndexedEntity>> res = started.cache(DEFAULT_CACHE_NAME)
.query(new TextQuery<AffinityKey<Integer>, IndexedEntity>(IndexedEntity.class, "indexed"));
http://git-wip-us.apache.org/repos/asf/ignite/blob/1e08c3fb/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 258eed8..1ad0d4b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySel
import org.apache.ignite.internal.processors.cache.IgniteCacheDeleteSqlQuerySelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheFieldsQueryNoDataSelfTest;
+import org.apache.ignite.internal.processors.cache.IgniteCacheFullTextQueryNodeJoiningSelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheInsertSqlQuerySelfTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheJoinPartitionedAndReplicatedTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheJoinQueryWithAffinityKeyTest;
@@ -273,6 +274,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
// Full text queries.
suite.addTestSuite(GridCacheFullTextQuerySelfTest.class);
+ suite.addTestSuite(IgniteCacheFullTextQueryNodeJoiningSelfTest.class);
// Ignite cache and H2 comparison.
suite.addTestSuite(BaseH2CompareQueryTest.class);
[14/29] ignite git commit: IGNITE-5734 Web Console: Fixed npm
dependencies. (cherry picked from commit aeafbf1)
Posted by nt...@apache.org.
IGNITE-5734 Web Console: Fixed npm dependencies.
(cherry picked from commit aeafbf1)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/580b6aa8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/580b6aa8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/580b6aa8
Branch: refs/heads/ignite-5947
Commit: 580b6aa8e5a8a887397eab5c4c830ec28f45cd30
Parents: ab18fdf
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Aug 9 17:22:54 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Aug 9 18:25:49 2017 +0700
----------------------------------------------------------------------
modules/web-console/frontend/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/580b6aa8/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index 6b049ff..f96c322 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -57,7 +57,7 @@
"babel-polyfill": "6.23.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-stage-1": "6.24.1",
- "babel-runtime": "6.23.0",
+ "babel-runtime": "6.25.0",
"bootstrap-sass": "3.3.7",
"brace": "0.10.0",
"copy-webpack-plugin": "4.0.1",
[18/29] ignite git commit: IGNITE-6013 Optimized processing response
from cluster. (cherry picked from commit b02c481)
Posted by nt...@apache.org.
IGNITE-6013 Optimized processing response from cluster.
(cherry picked from commit b02c481)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3a7d4f4a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3a7d4f4a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3a7d4f4a
Branch: refs/heads/ignite-5947
Commit: 3a7d4f4a79e7c0a23244387e3a68535375a66a87
Parents: 8b24619
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Aug 11 11:18:42 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Aug 11 11:23:04 2017 +0700
----------------------------------------------------------------------
.../console/agent/handlers/ClusterListener.java | 13 +-
.../ignite/console/agent/rest/RestExecutor.java | 201 +++++++++++++++++--
2 files changed, 194 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3a7d4f4a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
index b811a2d..435ce74 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/handlers/ClusterListener.java
@@ -46,7 +46,7 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SUCCESS;
/**
- * API to retranslate topology from Ignite cluster available by node-uri.
+ * API to transfer topology from Ignite cluster available by node-uri.
*/
public class ClusterListener {
/** */
@@ -65,7 +65,7 @@ public class ClusterListener {
private static final long DFLT_TIMEOUT = 3000L;
/** JSON object mapper. */
- private static final ObjectMapper mapper = new GridJettyObjectMapper();
+ private static final ObjectMapper MAPPER = new GridJettyObjectMapper();
/** Latest topology snapshot. */
private TopologySnapshot top;
@@ -234,10 +234,7 @@ public class ClusterListener {
/** */
boolean differentCluster(TopologySnapshot old) {
- if (old == null || F.isEmpty(old.nids))
- return true;
-
- return Collections.disjoint(nids, old.nids);
+ return old == null || F.isEmpty(old.nids) || Collections.disjoint(nids, old.nids);
}
}
@@ -250,7 +247,7 @@ public class ClusterListener {
switch (res.getStatus()) {
case STATUS_SUCCESS:
- List<GridClientNodeBean> nodes = mapper.readValue(res.getData(),
+ List<GridClientNodeBean> nodes = MAPPER.readValue(res.getData(),
new TypeReference<List<GridClientNodeBean>>() {});
TopologySnapshot newTop = new TopologySnapshot(nodes);
@@ -290,7 +287,7 @@ public class ClusterListener {
switch (res.getStatus()) {
case STATUS_SUCCESS:
- List<GridClientNodeBean> nodes = mapper.readValue(res.getData(),
+ List<GridClientNodeBean> nodes = MAPPER.readValue(res.getData(),
new TypeReference<List<GridClientNodeBean>>() {});
TopologySnapshot newTop = new TopologySnapshot(nodes);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3a7d4f4a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
----------------------------------------------------------------------
diff --git a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
index 03eca4e..13989b4 100644
--- a/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
+++ b/modules/web-console/web-agent/src/main/java/org/apache/ignite/console/agent/rest/RestExecutor.java
@@ -17,9 +17,16 @@
package org.apache.ignite.console.agent.rest;
-import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;
+import java.io.StringWriter;
import java.net.ConnectException;
import java.util.HashMap;
import java.util.Map;
@@ -40,6 +47,9 @@ import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.logger.slf4j.Slf4jLogger;
import org.slf4j.LoggerFactory;
+import static com.fasterxml.jackson.core.JsonToken.END_ARRAY;
+import static com.fasterxml.jackson.core.JsonToken.END_OBJECT;
+import static com.fasterxml.jackson.core.JsonToken.START_ARRAY;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_AUTH_FAILED;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_FAILED;
import static org.apache.ignite.internal.processors.rest.GridRestResponse.STATUS_SUCCESS;
@@ -52,7 +62,7 @@ public class RestExecutor {
private static final IgniteLogger log = new Slf4jLogger(LoggerFactory.getLogger(RestExecutor.class));
/** JSON object mapper. */
- private static final ObjectMapper mapper = new GridJettyObjectMapper();
+ private static final ObjectMapper MAPPER = new GridJettyObjectMapper();
/** */
private final OkHttpClient httpClient;
@@ -141,34 +151,35 @@ public class RestExecutor {
reqBuilder.url(urlBuilder.build());
try (Response resp = httpClient.newCall(reqBuilder.build()).execute()) {
- String content = resp.body().string();
-
if (resp.isSuccessful()) {
- JsonNode node = mapper.readTree(content);
+ RestResponseHolder res = MAPPER.readValue(resp.body().byteStream(), RestResponseHolder.class);
- int status = node.get("successStatus").asInt();
+ int status = res.getSuccessStatus();
switch (status) {
case STATUS_SUCCESS:
- return RestResult.success(node.get("response").toString());
+ return RestResult.success(res.getResponse());
default:
- return RestResult.fail(status, node.get("error").asText());
+ return RestResult.fail(status, res.getError());
}
}
if (resp.code() == 401)
- return RestResult.fail(STATUS_AUTH_FAILED, "Failed to authenticate in grid. " +
+ return RestResult.fail(STATUS_AUTH_FAILED, "Failed to authenticate in cluster. " +
"Please check agent\'s login and password or node port.");
- return RestResult.fail(STATUS_FAILED, "Failed connect to node and execute REST command.");
+ if (resp.code() == 404)
+ return RestResult.fail(STATUS_FAILED, "Failed connect to cluster.");
+
+ return RestResult.fail(STATUS_FAILED, "Failed to execute REST command: " + resp.message());
}
catch (ConnectException ignored) {
- LT.warn(log, "Failed connect to node and execute REST command. " +
+ LT.warn(log, "Failed connect to cluster. " +
"Please ensure that nodes have [ignite-rest-http] module in classpath " +
"(was copied from libs/optional to libs folder).");
- throw new ConnectException("Failed connect to node and execute REST command [url=" + urlBuilder + ", parameters=" + params + "]");
+ throw new ConnectException("Failed connect to cluster [url=" + urlBuilder + ", parameters=" + params + "]");
}
}
@@ -208,4 +219,170 @@ public class RestExecutor {
return sendRequest(demo, "ignite", params, null, null);
}
+
+ /**
+ * REST response holder Java bean.
+ */
+ private static class RestResponseHolder {
+ /** Success flag */
+ private int successStatus;
+
+ /** Error. */
+ private String err;
+
+ /** Response. */
+ private String res;
+
+ /** Session token string representation. */
+ private String sesTokStr;
+
+ /**
+ * @return {@code True} if this request was successful.
+ */
+ public int getSuccessStatus() {
+ return successStatus;
+ }
+
+ /**
+ * @param successStatus Whether request was successful.
+ */
+ public void setSuccessStatus(int successStatus) {
+ this.successStatus = successStatus;
+ }
+
+ /**
+ * @return Error.
+ */
+ public String getError() {
+ return err;
+ }
+
+ /**
+ * @param err Error.
+ */
+ public void setError(String err) {
+ this.err = err;
+ }
+
+ /**
+ * @return Response object.
+ */
+ public String getResponse() {
+ return res;
+ }
+
+ /**
+ * @param res Response object.
+ */
+ @JsonDeserialize(using = RawContentDeserializer.class)
+ public void setResponse(String res) {
+ this.res = res;
+ }
+
+ /**
+ * @return String representation of session token.
+ */
+ public String getSessionToken() {
+ return sesTokStr;
+ }
+
+ /**
+ * @param sesTokStr String representation of session token.
+ */
+ public void setSessionToken(String sesTokStr) {
+ this.sesTokStr = sesTokStr;
+ }
+ }
+
+ /**
+ * Raw content deserializer that will deserialize any data as string.
+ */
+ private static class RawContentDeserializer extends JsonDeserializer<String> {
+ /** */
+ private final JsonFactory factory = new JsonFactory();
+
+ /**
+ * @param tok Token to process.
+ * @param p Parser.
+ * @param gen Generator.
+ */
+ private void writeToken(JsonToken tok, JsonParser p, JsonGenerator gen) throws IOException {
+ switch (tok) {
+ case FIELD_NAME:
+ gen.writeFieldName(p.getText());
+ break;
+
+ case START_ARRAY:
+ gen.writeStartArray();
+ break;
+
+ case END_ARRAY:
+ gen.writeEndArray();
+ break;
+
+ case START_OBJECT:
+ gen.writeStartObject();
+ break;
+
+ case END_OBJECT:
+ gen.writeEndObject();
+ break;
+
+ case VALUE_NUMBER_INT:
+ gen.writeNumber(p.getLongValue());
+ break;
+
+ case VALUE_NUMBER_FLOAT:
+ gen.writeNumber(p.getDoubleValue());
+ break;
+
+ case VALUE_TRUE:
+ gen.writeBoolean(true);
+ break;
+
+ case VALUE_FALSE:
+ gen.writeBoolean(false);
+ break;
+
+ case VALUE_NULL:
+ gen.writeNull();
+ break;
+
+ default:
+ gen.writeString(p.getText());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
+ JsonToken startTok = p.getCurrentToken();
+
+ if (startTok.isStructStart()) {
+ StringWriter wrt = new StringWriter(4096);
+
+ JsonGenerator gen = factory.createGenerator(wrt);
+
+ JsonToken tok = startTok, endTok = startTok == START_ARRAY ? END_ARRAY : END_OBJECT;
+
+ int cnt = 1;
+
+ while (cnt > 0) {
+ writeToken(tok, p, gen);
+
+ tok = p.nextToken();
+
+ if (tok == startTok)
+ cnt++;
+ else if (tok == endTok)
+ cnt--;
+ }
+
+ gen.close();
+
+ return wrt.toString();
+ }
+
+ return p.getValueAsString();
+ }
+ }
}
[28/29] ignite git commit: IGNITE-6032: ODBC: Added
SQL_SCROLL_OPTIONS support for SQLGetInfo
Posted by nt...@apache.org.
IGNITE-6032: ODBC: Added SQL_SCROLL_OPTIONS support for SQLGetInfo
(cherry picked from commit f3d3d1bd718068c941e14b4e5949573b0a5d0c6a)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/020ff360
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/020ff360
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/020ff360
Branch: refs/heads/ignite-5947
Commit: 020ff3608d07fc584effe0826d72eb5edac0e1d6
Parents: 276e84a
Author: Igor Sapego <is...@gridgain.com>
Authored: Tue Aug 15 16:55:31 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Aug 15 16:55:31 2017 +0300
----------------------------------------------------------------------
.../cpp/odbc-test/src/meta_queries_test.cpp | 13 +++++++++++++
.../cpp/odbc/src/config/connection_info.cpp | 19 ++++++++++++++++++-
.../platforms/cpp/odbc/src/meta/column_meta.cpp | 3 +++
3 files changed, 34 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/020ff360/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index ff3695d..5d4e22f 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -337,4 +337,17 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithSelectQuery)
CheckSingleRowResultSetWithGetData(stmt);
}
+BOOST_AUTO_TEST_CASE(TestGetInfoScrollOptions)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLUINTEGER val = 0;
+ SQLRETURN ret = SQLGetInfo(dbc, SQL_SCROLL_OPTIONS, &val, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
+
+ BOOST_CHECK_NE(val, 0);
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/020ff360/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index 4e7cc3c..4925957 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -118,6 +118,7 @@ namespace ignite
DBG_STR_CASE(SQL_CONVERT_WLONGVARCHAR);
DBG_STR_CASE(SQL_CONVERT_WVARCHAR);
DBG_STR_CASE(SQL_CONVERT_GUID);
+ DBG_STR_CASE(SQL_SCROLL_OPTIONS);
DBG_STR_CASE(SQL_PARAM_ARRAY_ROW_COUNTS);
DBG_STR_CASE(SQL_PARAM_ARRAY_SELECTS);
default:
@@ -628,6 +629,19 @@ namespace ignite
SQL_CVT_BINARY | SQL_CVT_VARBINARY | SQL_CVT_LONGVARBINARY | SQL_CVT_GUID;
#endif //SQL_CONVERT_GUID
+#ifdef SQL_SCROLL_OPTIONS
+ // Bitmask enumerating the scroll options supported for scrollable cursors
+ // SQL_SO_FORWARD_ONLY = The cursor only scrolls forward. (ODBC 1.0)
+ // SQL_SO_STATIC = The data in the result set is static. (ODBC 2.0)
+ // SQL_SO_KEYSET_DRIVEN = The driver saves and uses the keys for every row in the result set. (ODBC 1.0)
+ // SQL_SO_DYNAMIC = The driver keeps the keys for every row in the rowset(the keyset size is the same
+ // as the rowset size). (ODBC 1.0)
+ // SQL_SO_MIXED = The driver keeps the keys for every row in the keyset, and the keyset size is greater
+ // than the rowset size.The cursor is keyset - driven inside the keyset and dynamic outside the
+ // keyset. (ODBC 1.0)
+ intParams[SQL_SCROLL_OPTIONS] = SQL_SO_FORWARD_ONLY | SQL_SO_STATIC;
+#endif //SQL_SCROLL_OPTIONS
+
//======================= Short Params ========================
#ifdef SQL_MAX_CONCURRENT_ACTIVITIES
// The maximum number of active statements that the driver can
@@ -666,13 +680,16 @@ namespace ignite
SqlResult::Type ConnectionInfo::GetInfo(InfoType type, void* buf,
short buflen, short* reslen) const
{
- if (!buf || !buflen)
+ if (!buf)
return SqlResult::AI_ERROR;
StringInfoMap::const_iterator itStr = strParams.find(type);
if (itStr != strParams.end())
{
+ if (!buflen)
+ return SqlResult::AI_ERROR;
+
unsigned short strlen = static_cast<short>(
utility::CopyStringToBuffer(itStr->second,
reinterpret_cast<char*>(buf), buflen));
http://git-wip-us.apache.org/repos/asf/ignite/blob/020ff360/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
index 97fdf80..f1bd9a1 100644
--- a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
+++ b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
@@ -60,6 +60,9 @@ namespace ignite
DBG_STR_CASE(SQL_DESC_UNNAMED);
DBG_STR_CASE(SQL_DESC_UNSIGNED);
DBG_STR_CASE(SQL_DESC_UPDATABLE);
+ DBG_STR_CASE(SQL_COLUMN_LENGTH);
+ DBG_STR_CASE(SQL_COLUMN_PRECISION);
+ DBG_STR_CASE(SQL_COLUMN_SCALE);
default:
break;
}
[08/29] ignite git commit: IGNITE-5939: ODBC: SQLColAttributes now
works with legacy attribute codes.
Posted by nt...@apache.org.
IGNITE-5939: ODBC: SQLColAttributes now works with legacy attribute codes.
(cherry picked from commit 70ffa2c)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4e0385fb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4e0385fb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4e0385fb
Branch: refs/heads/ignite-5947
Commit: 4e0385fbc0f50548f2da3407fdfdfe939b463c67
Parents: 0b3a9a7
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Aug 4 18:34:27 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Aug 4 18:36:46 2017 +0300
----------------------------------------------------------------------
.../cpp/odbc-test/src/meta_queries_test.cpp | 51 ++++++++++++++++++++
.../platforms/cpp/odbc/src/meta/column_meta.cpp | 3 ++
2 files changed, 54 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/4e0385fb/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 5b7ae59..454a989 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -186,4 +186,55 @@ BOOST_AUTO_TEST_CASE(TestGetTypeInfoAllTypes)
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnLength)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR req[] = "select strField from TestType";
+ SQLExecDirect(stmt, req, SQL_NTS);
+
+ SQLLEN intVal;
+ SQLCHAR strBuf[1024];
+ SQLSMALLINT strLen;
+
+ SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_LENGTH, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnPresicion)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR req[] = "select strField from TestType";
+ SQLExecDirect(stmt, req, SQL_NTS);
+
+ SQLLEN intVal;
+ SQLCHAR strBuf[1024];
+ SQLSMALLINT strLen;
+
+ SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_PRECISION, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR req[] = "select strField from TestType";
+ SQLExecDirect(stmt, req, SQL_NTS);
+
+ SQLLEN intVal;
+ SQLCHAR strBuf[1024];
+ SQLSMALLINT strLen;
+
+ SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_SCALE, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/4e0385fb/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
index 12dbfc1..97fdf80 100644
--- a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
+++ b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
@@ -179,6 +179,7 @@ namespace ignite
case SQL_DESC_LENGTH:
case SQL_DESC_OCTET_LENGTH:
+ case SQL_COLUMN_LENGTH:
{
value = type_traits::BinaryTypeTransferLength(dataType);
@@ -200,6 +201,7 @@ namespace ignite
}
case SQL_DESC_PRECISION:
+ case SQL_COLUMN_PRECISION:
{
value = type_traits::BinaryTypeColumnSize(dataType);
@@ -207,6 +209,7 @@ namespace ignite
}
case SQL_DESC_SCALE:
+ case SQL_COLUMN_SCALE:
{
value = type_traits::BinaryTypeDecimalDigits(dataType);
[15/29] ignite git commit: IGNITE-5987 Added -nq (visor will not quit
in batch mode) option for Visor Cmd. (cherry picked from commit 8d6e842)
Posted by nt...@apache.org.
IGNITE-5987 Added -nq (visor will not quit in batch mode) option for Visor Cmd.
(cherry picked from commit 8d6e842)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/841db65e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/841db65e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/841db65e
Branch: refs/heads/ignite-5947
Commit: 841db65e56063605475710bc170de4aea672c31d
Parents: 580b6aa
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Aug 9 18:55:04 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Aug 9 18:56:14 2017 +0700
----------------------------------------------------------------------
.../org/apache/ignite/visor/commands/VisorConsole.scala | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/841db65e/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
----------------------------------------------------------------------
diff --git a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
index 19d130e..d53a0d5 100644
--- a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
+++ b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
@@ -92,6 +92,7 @@ class VisorConsole {
println(" -cfg=<path> - connect with specified configuration.")
println(" -b=<path> - batch mode with file.")
println(" -e=cmd1;cmd2;... - batch mode with commands.")
+ println(" -nq - batch mode will not quit after execution (useful for alerts monitoring).")
visor.quit()
}
@@ -103,6 +104,10 @@ class VisorConsole {
val cfgFile = argValue("cfg", argLst)
val batchFile = argValue("b", argLst)
val batchCommand = argValue("e", argLst)
+ val noBatchQuit = hasArgName("nq", argLst)
+
+ if (noBatchQuit && batchFile.isEmpty && batchCommand.isEmpty)
+ visor.warn("Option \"-nq\" will be ignored because batch mode options \"-b\" or \"-e\" were not specified.")
cfgFile.foreach(cfg => {
if (cfg.trim.isEmpty) {
@@ -149,7 +154,10 @@ class VisorConsole {
case Some(cmd) =>
visor.batchMode = true
- new ByteArrayInputStream((cmd + "\nquit\n").getBytes("UTF-8"))
+ val script = if (noBatchQuit) cmd else cmd + "\nquit\n"
+
+ new ByteArrayInputStream(script.getBytes("UTF-8"))
+
case None => new FileInputStream(FileDescriptor.in)
}
@@ -159,7 +167,7 @@ class VisorConsole {
new TerminalSupport(false) {}
} catch {
- case ignored: ClassNotFoundException => null
+ case _: ClassNotFoundException => null
}
val reader = new ConsoleReader(inputStream, System.out, term)
[12/29] ignite git commit: IGNITE-5993: Removed unused SQL-related
classes and methods (old tree index, snapshots, etc). This closes #2414.
Posted by nt...@apache.org.
IGNITE-5993: Removed unused SQL-related classes and methods (old tree index, snapshots, etc). This closes #2414.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7c77b869
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7c77b869
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7c77b869
Branch: refs/heads/ignite-5947
Commit: 7c77b869bc3efdf19e53cc2b064f4290fd73e2b2
Parents: 879f191
Author: devozerov <vo...@gridgain.com>
Authored: Wed Aug 9 11:47:58 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Aug 9 11:49:53 2017 +0300
----------------------------------------------------------------------
.../query/h2/opt/GridH2SpatialIndex.java | 7 -
.../processors/query/h2/H2RowDescriptor.java | 11 -
.../processors/query/h2/H2TableEngine.java | 4 +-
.../query/h2/database/H2PkHashIndex.java | 7 -
.../query/h2/database/H2TreeIndex.java | 26 -
.../query/h2/opt/GridH2IndexBase.java | 93 +--
.../query/h2/opt/GridH2QueryContext.java | 59 --
.../query/h2/opt/GridH2RowDescriptor.java | 5 -
.../processors/query/h2/opt/GridH2Table.java | 186 +-----
.../query/h2/opt/GridH2TreeIndex.java | 602 -------------------
.../query/h2/twostep/GridMapQueryExecutor.java | 25 -
.../query/h2/opt/GridH2TableSelfTest.java | 172 ------
12 files changed, 7 insertions(+), 1190 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/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 9389290..d83e860 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
@@ -31,7 +31,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.query.h2.H2Cursor;
import org.apache.ignite.internal.util.GridCursorIteratorWrapper;
-import org.apache.ignite.internal.util.IgniteTree;
import org.apache.ignite.internal.util.lang.GridCursor;
import org.h2.engine.Session;
import org.h2.index.Cursor;
@@ -51,7 +50,6 @@ import org.h2.table.IndexColumn;
import org.h2.table.TableFilter;
import org.h2.value.Value;
import org.h2.value.ValueGeometry;
-import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.processors.query.h2.opt.GridH2AbstractKeyValueRow.KEY_COL;
@@ -158,11 +156,6 @@ public class GridH2SpatialIndex extends GridH2IndexBase implements SpatialIndex
}
/** {@inheritDoc} */
- @Nullable @Override protected IgniteTree doTakeSnapshot() {
- return null; // TODO We do not support snapshots, but probably this is possible.
- }
-
- /** {@inheritDoc} */
@Override public GridH2Row put(GridH2Row row) {
assert row instanceof GridH2AbstractKeyValueRow : "requires key to be at 0";
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
index dab83d1..31f0e69 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
@@ -107,9 +107,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
private final GridUnsafeGuard guard;
/** */
- private final boolean snapshotableIdx;
-
- /** */
private final GridQueryProperty[] props;
/** Id of user-defined key column */
@@ -170,9 +167,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
valueAliasColumnId =
(type.valueFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.valueFieldAlias()) : -1;
-
- // Index is not snapshotable in db-x.
- snapshotableIdx = false;
}
/** {@inheritDoc} */
@@ -382,11 +376,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
}
/** {@inheritDoc} */
- @Override public boolean snapshotableIndex() {
- return snapshotableIdx;
- }
-
- /** {@inheritDoc} */
@Override public boolean isKeyColumn(int columnId) {
assert columnId >= 0;
return columnId == KEY_COL || columnId == keyAliasColumnId;
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
index 57b7ba0..6bdcc30 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
@@ -56,8 +56,8 @@ public class H2TableEngine implements TableEngine {
* @throws SQLException If failed.
* @return Created table.
*/
- public static synchronized GridH2Table createTable(Connection conn, String sql,
- @Nullable GridH2RowDescriptor rowDesc, H2RowFactory rowFactory, H2TableDescriptor tblDesc)
+ public static synchronized GridH2Table createTable(Connection conn, String sql, GridH2RowDescriptor rowDesc,
+ H2RowFactory rowFactory, H2TableDescriptor tblDesc)
throws SQLException {
rowDesc0 = rowDesc;
rowFactory0 = rowFactory;
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/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 2ae5868..1937a4b 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
@@ -30,7 +30,6 @@ 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.GridH2Row;
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.lang.IgniteBiPredicate;
import org.apache.ignite.spi.indexing.IndexingQueryFilter;
@@ -44,7 +43,6 @@ import org.h2.result.SortOrder;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableFilter;
-import org.jetbrains.annotations.Nullable;
/**
*
@@ -199,11 +197,6 @@ public class H2PkHashIndex extends GridH2IndexBase {
throw new UnsupportedOperationException();
}
- /** {@inheritDoc} */
- @Nullable @Override protected IgniteTree doTakeSnapshot() {
- throw new AssertionError("This method must not be called for PK index");
- }
-
/**
* Cursor.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/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 e02510f..eb579c3 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
@@ -215,25 +215,6 @@ 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) {
try {
InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
@@ -344,13 +325,6 @@ public class H2TreeIndex extends GridH2IndexBase {
}
/** {@inheritDoc} */
- @Nullable @Override protected IgniteTree<SearchRow, GridH2Row> doTakeSnapshot() {
- int seg = threadLocalSegment();
-
- return treeForRead(seg);
- }
-
- /** {@inheritDoc} */
@Override protected H2Tree treeForRead(int segment) {
return segments[segment];
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
index 542adf0..5d5fb56 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java
@@ -22,7 +22,6 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
import javax.cache.CacheException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteInterruptedException;
@@ -35,7 +34,6 @@ import org.apache.ignite.internal.managers.communication.GridIoPolicy;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.processors.cache.CacheObject;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2IndexRangeRequest;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2IndexRangeResponse;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowMessage;
@@ -93,15 +91,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
private static final Object EXPLICIT_NULL = new Object();
/** */
- private static final AtomicLong idxIdGen = new AtomicLong();
-
- /** */
- protected final long idxId = idxIdGen.incrementAndGet();
-
- /** */
- private final ThreadLocal<Object> snapshot = new ThreadLocal<>();
-
- /** */
private Object msgTopic;
/** */
@@ -198,16 +187,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
public abstract GridH2Row put(GridH2Row row);
/**
- * Puts row.
- *
- * @param row Row.
- * @return {@code True} if replaced existing row.
- */
- public boolean putx(GridH2Row row) {
- return put(row) != null;
- }
-
- /**
* Remove row from index.
*
* @param row Row.
@@ -233,32 +212,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
public abstract GridH2Row findOne(GridH2Row row);
/**
- * Takes or sets existing snapshot to be used in current thread.
- *
- * @param s Optional existing snapshot to use.
- * @param qctx Query context.
- * @return Snapshot.
- */
- public final Object takeSnapshot(@Nullable Object s, GridH2QueryContext qctx) {
- assert snapshot.get() == null;
-
- if (s == null)
- s = doTakeSnapshot();
-
- if (s != null) {
- if (s instanceof GridReservable && !((GridReservable)s).reserve())
- return null;
-
- snapshot.set(s);
-
- if (qctx != null)
- qctx.putSnapshot(idxId, s);
- }
-
- return s;
- }
-
- /**
* @param ses Session.
*/
private static void clearViewIndexCache(Session ses) {
@@ -303,38 +256,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
}
/**
- * Takes and returns actual snapshot or {@code null} if snapshots are not supported.
- *
- * @return Snapshot or {@code null}.
- */
- @Nullable protected abstract IgniteTree doTakeSnapshot();
-
- /**
- * @return Thread local snapshot.
- */
- @SuppressWarnings("unchecked")
- protected <T> T threadLocalSnapshot() {
- return (T)snapshot.get();
- }
-
- /**
- * Releases snapshot for current thread.
- */
- public void releaseSnapshot() {
- Object s = snapshot.get();
-
- assert s != null;
-
- snapshot.remove();
-
- if (s instanceof GridReservable)
- ((GridReservable)s).release();
-
- if (s instanceof AutoCloseable)
- U.closeQuiet((AutoCloseable)s);
- }
-
- /**
* Filters rows from expired ones and using predicate.
*
* @param cursor GridCursor over rows.
@@ -498,11 +419,9 @@ public abstract class GridH2IndexBase extends BaseIndex {
if (msg.bounds() != null) {
// This is the first request containing all the search rows.
- IgniteTree snapshotTree = qctx.getSnapshot(idxId);
-
assert !msg.bounds().isEmpty() : "empty bounds";
- src = new RangeSource(msg.bounds(), msg.segment(), snapshotTree, qctx.filter());
+ src = new RangeSource(msg.bounds(), msg.segment(), qctx.filter());
}
else {
// This is request to fetch next portion of data.
@@ -619,7 +538,7 @@ public abstract class GridH2IndexBase extends BaseIndex {
if (isLocalQry) {
if (partMap != null && !partMap.containsKey(cctx.localNodeId()))
- return Collections.<SegmentKey>emptyList(); // Prevent remote index call for local queries.
+ return Collections.emptyList(); // Prevent remote index call for local queries.
nodes = Collections.singletonList(cctx.localNode());
}
@@ -1543,9 +1462,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
int curRangeId = -1;
/** */
- final IgniteTree tree;
-
- /** */
private final int segment;
/** */
@@ -1556,18 +1472,15 @@ public abstract class GridH2IndexBase extends BaseIndex {
/**
* @param bounds Bounds.
- * @param tree Snapshot.
* @param filter Filter.
*/
RangeSource(
Iterable<GridH2RowRangeBounds> bounds,
int segment,
- IgniteTree tree,
IndexingQueryFilter filter
) {
this.segment = segment;
this.filter = filter;
- this.tree = tree;
boundsIter = bounds.iterator();
}
@@ -1623,7 +1536,7 @@ public abstract class GridH2IndexBase extends BaseIndex {
SearchRow first = toSearchRow(bounds.first());
SearchRow last = toSearchRow(bounds.last());
- IgniteTree t = tree != null ? tree : treeForRead(segment);
+ IgniteTree t = treeForRead(segment);
iter = new CursorIteratorWrapper(doFind0(t, first, true, last, filter));
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
index a7ee0dc..2b4e180 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
@@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.spi.indexing.IndexingQueryFilter;
@@ -51,10 +50,6 @@ public class GridH2QueryContext {
/** */
private volatile boolean cleared;
- /** Index snapshots. */
- @GridToStringInclude
- private Map<Long, Object> snapshots;
-
/** */
private List<GridReservable> reservations;
@@ -248,51 +243,6 @@ public class GridH2QueryContext {
}
/**
- * @param idxId Index ID.
- * @param snapshot Index snapshot.
- */
- public void putSnapshot(long idxId, Object snapshot) {
- assert snapshot != null;
- assert get() == null : "need to snapshot indexes before setting query context for correct visibility";
-
- if (snapshot instanceof GridReservable && !((GridReservable)snapshot).reserve())
- throw new IllegalStateException("Must be already reserved before.");
-
- if (snapshots == null)
- snapshots = new HashMap<>();
-
- if (snapshots.put(idxId, snapshot) != null)
- throw new IllegalStateException("Index already snapshoted.");
- }
-
- /**
- * Clear taken snapshots.
- */
- public void clearSnapshots() {
- if (F.isEmpty(snapshots))
- return;
-
- for (Object snapshot : snapshots.values()) {
- if (snapshot instanceof GridReservable)
- ((GridReservable)snapshot).release();
- }
-
- snapshots = null;
- }
-
- /**
- * @param idxId Index ID.
- * @return Index snapshot or {@code null} if none.
- */
- @SuppressWarnings("unchecked")
- public <T> T getSnapshot(long idxId) {
- if (snapshots == null)
- return null;
-
- return (T)snapshots.get(idxId);
- }
-
- /**
* @param batchLookupId Batch lookup ID.
* @param streams Range streams.
*/
@@ -363,13 +313,6 @@ public class GridH2QueryContext {
}
/**
- * @return If indexes were snapshotted before query execution.
- */
- public boolean hasIndexSnapshots() {
- return snapshots != null;
- }
-
- /**
* Sets current thread local context. This method must be called when all the non-volatile properties are
* already set to ensure visibility for other threads.
*
@@ -440,8 +383,6 @@ public class GridH2QueryContext {
public void clearContext(boolean nodeStop) {
cleared = true;
- clearSnapshots();
-
List<GridReservable> r = reservations;
if (!nodeStop && !F.isEmpty(r)) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
index ce73010..d273e16 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
@@ -154,11 +154,6 @@ public interface GridH2RowDescriptor extends GridOffHeapSmartPointerFactory<Grid
public Value wrap(Object o, int type) throws IgniteCheckedException;
/**
- * @return {@code True} if index should support snapshots.
- */
- public boolean snapshotableIndex();
-
- /**
* Checks if provided column id matches key column or key alias.
*
* @param colId Column id.
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
index 76d0258..f76cb5f 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
@@ -22,8 +22,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -61,7 +59,6 @@ import org.jsr166.LongAdder8;
import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.internal.processors.query.h2.opt.GridH2AbstractKeyValueRow.KEY_COL;
-import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.MAP;
/**
* H2 Table implementation.
@@ -95,18 +92,12 @@ public class GridH2Table extends TableBase {
private final ConcurrentMap<Session, Boolean> sessions = new ConcurrentHashMap8<>();
/** */
- private final AtomicReferenceArray<Object[]> actualSnapshot;
-
- /** */
private IndexColumn affKeyCol;
/** */
private final LongAdder8 size = new LongAdder8();
/** */
- private final boolean snapshotEnabled;
-
- /** */
private final H2RowFactory rowFactory;
/** */
@@ -127,7 +118,7 @@ public class GridH2Table extends TableBase {
* @param idxsFactory Indexes factory.
* @param cctx Cache context.
*/
- public GridH2Table(CreateTableData createTblData, @Nullable GridH2RowDescriptor desc, H2RowFactory rowFactory,
+ public GridH2Table(CreateTableData createTblData, GridH2RowDescriptor desc, H2RowFactory rowFactory,
GridH2SystemIndexFactory idxsFactory, GridCacheContext cctx) {
super(createTblData);
@@ -136,7 +127,7 @@ public class GridH2Table extends TableBase {
this.desc = desc;
this.cctx = cctx;
- if (desc != null && desc.context() != null && !desc.context().customAffinityMapper()) {
+ if (desc.context() != null && !desc.context().customAffinityMapper()) {
boolean affinityColExists = true;
String affKey = desc.type().affinityKey();
@@ -186,18 +177,10 @@ public class GridH2Table extends TableBase {
else
idxs.add(0, new GridH2PrimaryScanIndex(this, index(0), null));
- snapshotEnabled = desc == null || desc.snapshotableIndex();
-
pkIndexPos = hasHashIndex ? 2 : 1;
sysIdxsCnt = idxs.size();
- final int segments = desc != null ? desc.context().config().getQueryParallelism() :
- // Get index segments count from PK index. Null desc can be passed from tests.
- index(pkIndexPos).segmentsCount();
-
- actualSnapshot = snapshotEnabled ? new AtomicReferenceArray<Object[]>(Math.max(segments, 1)) : null;
-
lock = new ReentrantReadWriteLock();
}
@@ -259,79 +242,10 @@ public class GridH2Table extends TableBase {
throw new IllegalStateException("Table " + identifierString() + " already destroyed.");
}
- if (snapshotInLock()) {
- final GridH2QueryContext qctx = GridH2QueryContext.get();
-
- assert qctx != null;
-
- snapshotIndexes(null, qctx.segment());
- }
-
return false;
}
/**
- * @return {@code True} If we must snapshot and release index snapshots in {@link #lock(Session, boolean, boolean)}
- * and {@link #unlock(Session)} methods.
- */
- private boolean snapshotInLock() {
- if (!snapshotEnabled)
- return false;
-
- GridH2QueryContext qctx = GridH2QueryContext.get();
-
- // On MAP queries with distributed joins we lock tables before the queries.
- return qctx == null || qctx.type() != MAP || !qctx.hasIndexSnapshots();
- }
-
- /**
- * @param qctx Query context.
- * @param segment id of index segment to be snapshoted.
- */
- public void snapshotIndexes(GridH2QueryContext qctx, int segment) {
- if (!snapshotEnabled)
- return;
-
- Object[] segmentSnapshot;
-
- // Try to reuse existing snapshots outside of the lock.
- for (long waitTime = 200; ; waitTime *= 2) { // Increase wait time to avoid starvation.
- segmentSnapshot = actualSnapshot.get(segment);
-
- if (segmentSnapshot != null) { // Reuse existing snapshot without locking.
- segmentSnapshot = doSnapshotIndexes(segment, segmentSnapshot, qctx);
-
- if (segmentSnapshot != null)
- return; // Reused successfully.
- }
-
- if (tryLock(true, waitTime))
- break;
- }
-
- try {
- ensureNotDestroyed();
-
- // Try again inside of the lock.
- segmentSnapshot = actualSnapshot.get(segment);
-
- if (segmentSnapshot != null) // Try reusing.
- segmentSnapshot = doSnapshotIndexes(segment, segmentSnapshot, qctx);
-
- if (segmentSnapshot == null) { // Reuse failed, produce new snapshots.
- segmentSnapshot = doSnapshotIndexes(segment,null, qctx);
-
- assert segmentSnapshot != null;
-
- actualSnapshot.set(segment, segmentSnapshot);
- }
- }
- finally {
- unlock(true);
- }
- }
-
- /**
* @return Table identifier.
*/
public QueryTable identifier() {
@@ -364,27 +278,6 @@ public class GridH2Table extends TableBase {
}
/**
- * @param exclusive Exclusive lock.
- * @param waitMillis Milliseconds to wait for the lock.
- * @return Whether lock was acquired.
- */
- private boolean tryLock(boolean exclusive, long waitMillis) {
- Lock l = exclusive ? lock.writeLock() : lock.readLock();
-
- try {
- if (!l.tryLock(waitMillis, TimeUnit.MILLISECONDS))
- return false;
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
-
- throw new IgniteInterruptedException("Thread got interrupted while trying to acquire table lock.", e);
- }
-
- return true;
- }
-
- /**
* Release table lock.
*
* @param exclusive Exclusive flag.
@@ -403,55 +296,6 @@ public class GridH2Table extends TableBase {
throw new IllegalStateException("Table " + identifierString() + " already destroyed.");
}
- /**
- * Must be called inside of write lock because when using multiple indexes we have to ensure that all of them have
- * the same contents at snapshot taking time.
- *
- * @param segment id of index segment snapshot.
- * @param segmentSnapshot snapshot to be reused.
- * @param qctx Query context.
- * @return New indexes data snapshot.
- */
- @SuppressWarnings("unchecked")
- private Object[] doSnapshotIndexes(int segment, Object[] segmentSnapshot, GridH2QueryContext qctx) {
- assert snapshotEnabled;
-
- //TODO: make HashIndex snapshotable or remove it at all?
- if (segmentSnapshot == null) // Nothing to reuse, create new snapshots.
- segmentSnapshot = new Object[idxs.size() - pkIndexPos];
-
- // Take snapshots on all except first which is scan.
- for (int i = pkIndexPos, len = idxs.size(); i < len; i++) {
- Object s = segmentSnapshot[i - pkIndexPos];
-
- boolean reuseExisting = s != null;
-
- if (!(idxs.get(i) instanceof GridH2IndexBase))
- continue;
-
- s = index(i).takeSnapshot(s, qctx);
-
- if (reuseExisting && s == null) { // Existing snapshot was invalidated before we were able to reserve it.
- // Release already taken snapshots.
- if (qctx != null)
- qctx.clearSnapshots();
-
- for (int j = pkIndexPos; j < i; j++)
- if ((idxs.get(j) instanceof GridH2IndexBase))
- index(j).releaseSnapshot();
-
- // Drop invalidated snapshot.
- actualSnapshot.compareAndSet(segment, segmentSnapshot, null);
-
- return null;
- }
-
- segmentSnapshot[i - pkIndexPos] = s;
- }
-
- return segmentSnapshot;
- }
-
/** {@inheritDoc} */
@Override public void close(Session ses) {
// No-op.
@@ -525,32 +369,10 @@ public class GridH2Table extends TableBase {
if (exclusive == null)
return;
- if (snapshotInLock())
- releaseSnapshots();
-
unlock(exclusive);
}
/**
- * Releases snapshots.
- */
- public void releaseSnapshots() {
- if (!snapshotEnabled)
- return;
-
- releaseSnapshots0(idxs);
- }
-
- /**
- * @param idxs Indexes.
- */
- private void releaseSnapshots0(ArrayList<Index> idxs) {
- // Release snapshots on all except first which is scan and second which is hash.
- for (int i = 2, len = idxs.size(); i < len; i++)
- ((GridH2IndexBase)idxs.get(i)).releaseSnapshot();
- }
-
- /**
* Updates table for given key. If value is null then row with given key will be removed from table,
* otherwise value and expiration time will be updated or new row will be added.
*
@@ -700,10 +522,6 @@ public class GridH2Table extends TableBase {
return false;
}
- // The snapshot is not actual after update.
- if (actualSnapshot != null)
- actualSnapshot.set(pk.segmentForRow(row), null);
-
return true;
}
finally {
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java
deleted file mode 100644
index 03fedcb..0000000
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.query.h2.opt;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.processors.query.h2.H2Cursor;
-import org.apache.ignite.internal.util.GridCursorIteratorWrapper;
-import org.apache.ignite.internal.util.IgniteTree;
-import org.apache.ignite.internal.util.lang.GridCursor;
-import org.apache.ignite.internal.util.offheap.unsafe.GridOffHeapSnapTreeMap;
-import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeGuard;
-import org.apache.ignite.internal.util.snaptree.SnapTreeMap;
-import org.apache.ignite.internal.util.typedef.internal.SB;
-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.SearchRow;
-import org.h2.result.SortOrder;
-import org.h2.table.Column;
-import org.h2.table.IndexColumn;
-import org.h2.table.TableFilter;
-import org.h2.value.Value;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Base class for snapshotable segmented tree indexes.
- */
-@SuppressWarnings("ComparatorNotSerializable")
-public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridSearchRowPointer> {
- /** */
- private final IgniteNavigableMapTree[] segments;
-
- /** */
- private final boolean snapshotEnabled;
-
- /**
- * Constructor with index initialization. Creates index with single segment.
- *
- * @param name Index name.
- * @param tbl Table.
- * @param pk If this index is primary key.
- * @param colsList Index columns list.
- */
- @SuppressWarnings("unchecked")
- public GridH2TreeIndex(String name, GridH2Table tbl, boolean pk, List<IndexColumn> colsList) {
- this(name, tbl, pk, colsList, 1);
- }
-
- /**
- * Constructor with index initialization.
- *
- * @param name Index name.
- * @param tbl Table.
- * @param pk If this index is primary key.
- * @param colsList Index columns list.
- * @param segmentsCnt Number of segments.
- */
- @SuppressWarnings("unchecked")
- public GridH2TreeIndex(String name, GridH2Table tbl, boolean pk, List<IndexColumn> colsList, int segmentsCnt) {
- assert segmentsCnt > 0 : segmentsCnt;
-
- IndexColumn[] cols = colsList.toArray(new IndexColumn[colsList.size()]);
-
- IndexColumn.mapColumns(cols, tbl);
-
- initBaseIndex(tbl, 0, name, cols,
- pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false));
-
- segments = new IgniteNavigableMapTree[segmentsCnt];
-
- final GridH2RowDescriptor desc = tbl.rowDescriptor();
-
- if (desc == null || desc.memory() == null) {
- snapshotEnabled = desc == null || desc.snapshotableIndex();
-
- if (snapshotEnabled) {
- for (int i = 0; i < segmentsCnt; i++) {
- segments[i] = new IgniteNavigableMapTree(new SnapTreeMap<GridSearchRowPointer, GridH2Row>(this) {
- @Override protected void afterNodeUpdate_nl(Node<GridSearchRowPointer, GridH2Row> node, Object val) {
- if (val != null)
- node.key = (GridSearchRowPointer)val;
- }
-
- @Override protected Comparable<? super GridSearchRowPointer> comparable(Object key) {
- if (key instanceof ComparableRow)
- return (Comparable<? super SearchRow>)key;
-
- return super.comparable(key);
- }
- });
- }
- }
- else {
- for (int i = 0; i < segmentsCnt; i++) {
- segments[i] = new IgniteNavigableMapTree(
- new ConcurrentSkipListMap<GridSearchRowPointer, GridH2Row>(
- new Comparator<GridSearchRowPointer>() {
- @Override public int compare(GridSearchRowPointer o1, GridSearchRowPointer o2) {
- if (o1 instanceof ComparableRow)
- return ((ComparableRow)o1).compareTo(o2);
-
- if (o2 instanceof ComparableRow)
- return -((ComparableRow)o2).compareTo(o1);
-
- return compareRows(o1, o2);
- }
- }
- ));
- }
- }
- }
- else {
- assert desc.snapshotableIndex() : desc;
-
- snapshotEnabled = true;
-
- for (int i = 0; i < segmentsCnt; i++) {
- segments[i] = new IgniteNavigableMapTree(new GridOffHeapSnapTreeMap<GridSearchRowPointer, GridH2Row>(desc, desc, desc.memory(), desc.guard(), this) {
- @Override protected void afterNodeUpdate_nl(long node, GridH2Row val) {
- final long oldKey = keyPtr(node);
-
- if (val != null) {
- key(node, val);
-
- guard.finalizeLater(new Runnable() {
- @Override public void run() {
- desc.createPointer(oldKey).decrementRefCount();
- }
- });
- }
- }
-
- @Override protected Comparable<? super GridSearchRowPointer> comparable(Object key) {
- if (key instanceof ComparableRow)
- return (Comparable<? super SearchRow>)key;
-
- return super.comparable(key);
- }
- });
- }
- }
-
- initDistributedJoinMessaging(tbl);
- }
-
- /** {@inheritDoc} */
- @Override protected IgniteTree doTakeSnapshot() {
- assert snapshotEnabled;
-
- int seg = threadLocalSegment();
-
- IgniteNavigableMapTree tree = segments[seg];
-
- return tree.clone();
- }
-
- /** {@inheritDoc} */
- @Override protected final IgniteTree treeForRead(int seg) {
- if (!snapshotEnabled)
- return segments[seg];
-
- IgniteTree res = threadLocalSnapshot();
-
- if (res == null)
- return segments[seg];
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public void destroy() {
- assert threadLocalSnapshot() == null;
-
- super.destroy();
- }
-
- /** {@inheritDoc} */
- @Override public long getRowCount(@Nullable Session ses) {
- IndexingQueryFilter f = threadLocalFilter();
-
- int seg = threadLocalSegment();
-
- // Fast path if we don't need to perform any filtering.
- if (f == null || f.forCache((getTable()).cacheName()) == null)
- try {
- return treeForRead(seg).size();
- } catch (IgniteCheckedException e) {
- throw DbException.convert(e);
- }
-
- GridCursor<GridH2Row> cursor = doFind(null, false, null);
-
- long size = 0;
-
- try {
- while (cursor.next())
- size++;
- }
- catch (IgniteCheckedException e) {
- throw DbException.convert(e);
- }
-
- return size;
- }
-
- /** {@inheritDoc} */
- @Override public long getRowCountApproximation() {
- return table.getRowCountApproximation();
- }
-
- /** {@inheritDoc} */
- @Override public int compare(GridSearchRowPointer r1, GridSearchRowPointer r2) {
- // Second row here must be data row if first is a search row.
- return -compareRows(r2, r1);
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- SB sb = new SB((indexType.isUnique() ? "Unique index '" : "Index '") + getName() + "' [");
-
- boolean first = true;
-
- for (IndexColumn col : getIndexColumns()) {
- if (first)
- first = false;
- else
- sb.a(", ");
-
- sb.a(col.getSQL());
- }
-
- sb.a(" ]");
-
- return sb.toString();
- }
-
- /** {@inheritDoc} */
- @Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter,
- SortOrder sortOrder, HashSet<Column> cols) {
- long rowCnt = getRowCountApproximation();
- double baseCost = getCostRangeIndex(masks, rowCnt, filters, filter, sortOrder, false, cols);
- int mul = getDistributedMultiplier(ses, filters, filter);
-
- return mul * baseCost;
- }
-
- /** {@inheritDoc} */
- @Override public boolean canFindNext() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override public Cursor find(Session ses, @Nullable SearchRow first, @Nullable SearchRow last) {
- return new H2Cursor(doFind(first, true, last), null);
- }
-
- /** {@inheritDoc} */
- @Override public Cursor findNext(Session ses, SearchRow higherThan, SearchRow last) {
- return new H2Cursor(doFind(higherThan, false, last), null);
- }
-
- /**
- * Finds row with key equal one in given search row.
- * WARNING!! Method call must be protected by {@link GridUnsafeGuard#begin()}
- * {@link GridUnsafeGuard#end()} block.
- *
- * @param row Search row.
- * @return Row.
- */
- @Override public GridH2Row findOne(GridH2Row row) {
- int seg = segmentForRow(row);
-
- return segments[seg].findOne(row);
- }
-
- /**
- * Returns sub-tree bounded by given values.
- *
- * @param first Lower bound.
- * @param includeFirst Whether lower bound should be inclusive.
- * @param last Upper bound always inclusive.
- * @return Iterator over rows in given range.
- */
- @SuppressWarnings("unchecked")
- private GridCursor<GridH2Row> doFind(@Nullable SearchRow first, boolean includeFirst, @Nullable SearchRow last) {
- int seg = threadLocalSegment();
-
- IgniteTree t = treeForRead(seg);
-
- return doFind0(t, first, includeFirst, last, threadLocalFilter());
- }
-
- /** {@inheritDoc} */
- @Override protected final GridCursor<GridH2Row> doFind0(
- IgniteTree t,
- @Nullable SearchRow first,
- boolean includeFirst,
- @Nullable SearchRow last,
- IndexingQueryFilter filter
- ) {
- includeFirst &= first != null;
-
- GridCursor<GridH2Row> range = subTree(t, comparable(first, includeFirst ? -1 : 1),
- comparable(last, 1));
-
- if (range == null)
- return EMPTY_CURSOR;
-
- return filter(range, filter);
- }
-
- /**
- * @param row Row.
- * @param bias Bias.
- * @return Comparable row.
- */
- private GridSearchRowPointer comparable(SearchRow row, int bias) {
- if (row == null)
- return null;
-
- if (bias == 0 && row instanceof GridH2Row)
- return (GridSearchRowPointer)row;
-
- return new ComparableRow(row, bias);
- }
-
- /**
- * Takes sup-map from given one.
- *
- * @param tree Tree.
- * @param first Lower bound.
- * @param last Upper bound.
- * @return Sub-map.
- */
- @SuppressWarnings({"IfMayBeConditional", "TypeMayBeWeakened"})
- private GridCursor<GridH2Row> subTree(IgniteTree tree,
- @Nullable GridSearchRowPointer first, @Nullable GridSearchRowPointer last) {
-
- if (first != null && last != null && compare(first, last) > 0)
- return null;
-
- try {
- // We take exclusive bounds because it is possible that one search row will be equal to multiple key rows
- // in tree and we must return them all.
- return tree.find(first, last);
- }
- catch (IgniteCheckedException e) {
- throw DbException.convert(e);
- }
- }
-
- /**
- * Gets iterator over all rows in this index.
- *
- * @return Rows iterator.
- */
- GridCursor<GridH2Row> rows() {
- return doFind(null, false, null);
- }
-
- /** {@inheritDoc} */
- @Override public boolean canGetFirstOrLast() {
- return true;
- }
-
- /** {@inheritDoc} */
- @Override public Cursor findFirstOrLast(Session ses, boolean first) {
- try {
- int seg = threadLocalSegment();
-
- IgniteTree t = treeForRead(seg);
-
- GridH2Row row = (GridH2Row)(first ? t.findFirst() : t.findLast());
-
- return new SingleRowCursor(row);
- }
- catch (IgniteCheckedException e) {
- throw DbException.convert(e);
- }
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row put(GridH2Row row) {
- int seg = segmentForRow(row);
-
- return segments[seg].put(row);
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row remove(SearchRow row) {
- GridSearchRowPointer comparable = comparable(row, 0);
-
- int seg = segmentForRow(row);
-
- return segments[seg].remove(comparable);
- }
-
- /** {@inheritDoc} */
- @Override protected int segmentsCount() {
- return segments.length;
- }
-
- /**
- * Comparable row with bias. Will be used for queries to have correct bounds (in case of multicolumn index
- * and query on few first columns we will multiple equal entries in tree).
- */
- private final class ComparableRow implements GridSearchRowPointer, Comparable<SearchRow> {
- /** */
- private final SearchRow row;
-
- /** */
- private final int bias;
-
- /**
- * @param row Row.
- * @param bias Bias.
- */
- private ComparableRow(SearchRow row, int bias) {
- this.row = row;
- this.bias = bias;
- }
-
- /** {@inheritDoc} */
- @Override public int compareTo(SearchRow o) {
- int res = compareRows(o, row);
-
- if (res == 0)
- return bias;
-
- return -res;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object obj) {
- throw new IllegalStateException("Should never be called.");
- }
-
- /** {@inheritDoc} */
- @Override public int getColumnCount() {
- return row.getColumnCount();
- }
-
- /** {@inheritDoc} */
- @Override public Value getValue(int idx) {
- return row.getValue(idx);
- }
-
- /** {@inheritDoc} */
- @Override public void setValue(int idx, Value v) {
- row.setValue(idx, v);
- }
-
- /** {@inheritDoc} */
- @Override public void setKeyAndVersion(SearchRow old) {
- row.setKeyAndVersion(old);
- }
-
- /** {@inheritDoc} */
- @Override public int getVersion() {
- return row.getVersion();
- }
-
- /** {@inheritDoc} */
- @Override public void setKey(long key) {
- row.setKey(key);
- }
-
- /** {@inheritDoc} */
- @Override public long getKey() {
- return row.getKey();
- }
-
- /** {@inheritDoc} */
- @Override public int getMemory() {
- return row.getMemory();
- }
-
- /** {@inheritDoc} */
- @Override public long pointer() {
- throw new IllegalStateException();
- }
-
- /** {@inheritDoc} */
- @Override public void incrementRefCount() {
- throw new IllegalStateException();
- }
-
- /** {@inheritDoc} */
- @Override public void decrementRefCount() {
- throw new IllegalStateException();
- }
- }
-
- /**
- * Adapter from {@link NavigableMap} to {@link IgniteTree}.
- */
- private static final class IgniteNavigableMapTree implements IgniteTree<GridSearchRowPointer, GridH2Row>, Cloneable {
- /** Tree. */
- private final NavigableMap<GridSearchRowPointer, GridH2Row> tree;
-
- /**
- * @param tree Tree.
- */
- private IgniteNavigableMapTree(NavigableMap<GridSearchRowPointer, GridH2Row> tree) {
- this.tree = tree;
- }
-
- /** {@inheritDoc} */
- @Override public void invoke(GridSearchRowPointer key, Object x, InvokeClosure<GridH2Row> c) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row put(GridH2Row val) {
- return tree.put(val, val);
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row findOne(GridSearchRowPointer key) {
- return tree.get(key);
- }
-
- /** {@inheritDoc} */
- @Override public GridCursor<GridH2Row> find(GridSearchRowPointer lower, GridSearchRowPointer upper)
- throws IgniteCheckedException {
-
- Collection<GridH2Row> rows;
-
- if (lower == null && upper == null)
- rows = tree.values();
- else if (lower != null && upper == null)
- rows = tree.tailMap(lower).values();
- else if (lower == null)
- rows = tree.headMap(upper).values();
- else
- rows = tree.subMap(lower, false, upper, false).values();
-
- return new GridCursorIteratorWrapper<>(rows.iterator());
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row findFirst() throws IgniteCheckedException {
- Map.Entry<GridSearchRowPointer, GridH2Row> first = tree.firstEntry();
- return (first == null) ? null : first.getValue();
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row findLast() throws IgniteCheckedException {
- Map.Entry<GridSearchRowPointer, GridH2Row> last = tree.lastEntry();
- return (last == null) ? null : last.getValue();
- }
-
- /** {@inheritDoc} */
- @Override public GridH2Row remove(GridSearchRowPointer key) {
- return tree.remove(key);
- }
-
- /** {@inheritDoc} */
- @Override public long size() {
- return tree.size();
- }
-
- /** {@inheritDoc} */
- @Override public IgniteNavigableMapTree clone() {
- IgniteNavigableMapTree cp;
-
- try {
- cp = (IgniteNavigableMapTree)super.clone();
- }
- catch (final CloneNotSupportedException e) {
- throw DbException.convert(e);
- }
-
- return new IgniteNavigableMapTree(cp.tree);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index 19b628b..e717367 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -26,7 +26,6 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
@@ -59,7 +58,6 @@ import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2RetryException;
-import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryCancelRequest;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryFailResponse;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageRequest;
@@ -545,22 +543,6 @@ public class GridMapQueryExecutor {
.topologyVersion(topVer)
.reservations(reserved);
- List<GridH2Table> snapshotedTbls = null;
-
- if (!F.isEmpty(tbls)) {
- snapshotedTbls = new ArrayList<>(tbls.size());
-
- for (QueryTable tbl : tbls) {
- GridH2Table h2Tbl = h2.dataTable(tbl);
-
- Objects.requireNonNull(h2Tbl, tbl.toString());
-
- h2Tbl.snapshotIndexes(qctx, segmentId);
-
- snapshotedTbls.add(h2Tbl);
- }
- }
-
Connection conn = h2.connectionForSchema(schemaName);
H2Utils.setupConnection(conn, distributedJoinMode != OFF, enforceJoinOrder);
@@ -596,8 +578,6 @@ public class GridMapQueryExecutor {
qr.queryCancel(qryIdx));
if (evt) {
- assert mainCctx != null;
-
ctx.event().record(new CacheQueryExecutedEvent<>(
node,
"SQL query executed.",
@@ -635,11 +615,6 @@ public class GridMapQueryExecutor {
if (distributedJoinMode == OFF)
qctx.clearContext(false);
-
- if (!F.isEmpty(snapshotedTbls)) {
- for (GridH2Table dataTbl : snapshotedTbls)
- dataTbl.releaseSnapshots();
- }
}
}
catch (Throwable e) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/7c77b869/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java
index 88ff61e..a1a64e8 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java
@@ -18,38 +18,20 @@
package org.apache.ignite.internal.processors.query.h2.opt;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
import java.util.Random;
-import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex;
-import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory;
-import org.apache.ignite.internal.util.lang.GridCursor;
-import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.h2.Driver;
-import org.h2.index.Cursor;
-import org.h2.index.Index;
-import org.h2.result.Row;
-import org.h2.result.SearchRow;
-import org.h2.result.SortOrder;
-import org.h2.table.IndexColumn;
import org.h2.value.ValueLong;
import org.h2.value.ValueString;
import org.h2.value.ValueTimestamp;
import org.h2.value.ValueUuid;
-import org.jetbrains.annotations.Nullable;
/**
* Tests H2 Table.
@@ -173,47 +155,6 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
assertEquals(MAX_X, idx.getRowCount(null));
}
- // Check correct rows order.
- checkOrdered((GridH2TreeIndex)tbl.indexes().get(0), new Comparator<SearchRow>() {
- @Override public int compare(SearchRow o1, SearchRow o2) {
- UUID id1 = (UUID)o1.getValue(0).getObject();
- UUID id2 = (UUID)o2.getValue(0).getObject();
-
- return id1.compareTo(id2);
- }
- });
-
- checkOrdered((GridH2TreeIndex)tbl.indexes().get(1), new Comparator<SearchRow>() {
- @Override public int compare(SearchRow o1, SearchRow o2) {
- Long x1 = (Long)o1.getValue(3).getObject();
- Long x2 = (Long)o2.getValue(3).getObject();
-
- int c = x2.compareTo(x1);
-
- if (c != 0)
- return c;
-
- Timestamp t1 = (Timestamp)o1.getValue(1).getObject();
- Timestamp t2 = (Timestamp)o2.getValue(1).getObject();
-
- return t1.compareTo(t2);
- }
- });
-
- checkOrdered((GridH2TreeIndex)tbl.indexes().get(2), new Comparator<SearchRow>() {
- @Override public int compare(SearchRow o1, SearchRow o2) {
- String s1 = (String)o1.getValue(2).getObject();
- String s2 = (String)o2.getValue(2).getObject();
-
- return s2.compareTo(s1);
- }
- });
-
- // Indexes data consistency.
- ArrayList<? extends Index> idxs = tbl.indexes();
-
- checkIndexesConsistent((ArrayList<Index>)idxs, null);
-
// Check unique index.
UUID id = UUID.randomUUID();
UUID id2 = UUID.randomUUID();
@@ -405,54 +346,6 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
/**
- * @throws Exception If failed.
- */
- public void testIndexFindFirstOrLast() throws Exception {
- Index index = tbl.getIndexes().get(2);
- assertTrue(index instanceof GridH2TreeIndex);
- assertTrue(index.canGetFirstOrLast());
-
- //find first on empty data
- Cursor cursor = index.findFirstOrLast(null, true);
- assertFalse(cursor.next());
- assertNull(cursor.get());
-
- //find last on empty data
- cursor = index.findFirstOrLast(null, false);
- assertFalse(cursor.next());
- assertNull(cursor.get());
-
- //fill with data
- int rows = 100;
- long t = System.currentTimeMillis();
- Random rnd = new Random();
- UUID min = null;
- UUID max = null;
-
- for (int i = 0 ; i < rows; i++) {
- UUID id = UUID.randomUUID();
- if (min == null || id.compareTo(min) < 0)
- min = id;
- if (max == null || id.compareTo(max) > 0)
- max = id;
- GridH2Row row = row(id, t++, id.toString(), rnd.nextInt(100));
- ((GridH2TreeIndex)index).put(row);
- }
-
- //find first
- cursor = index.findFirstOrLast(null, true);
- assertTrue(cursor.next());
- assertEquals(min, cursor.get().getValue(0).getObject());
- assertFalse(cursor.next());
-
- //find last
- cursor = index.findFirstOrLast(null, false);
- assertTrue(cursor.next());
- assertEquals(max, cursor.get().getValue(0).getObject());
- assertFalse(cursor.next());
- }
-
- /**
* Check query plan to correctly select index.
*
* @param conn Connection.
@@ -473,69 +366,4 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
}
}
}
-
- /**
- * @param idxs Indexes.
- * @param rowSet Rows.
- * @return Rows.
- */
- private Set<Row> checkIndexesConsistent(ArrayList<Index> idxs, @Nullable Set<Row> rowSet) throws IgniteCheckedException {
- for (Index idx : idxs) {
- if (!(idx instanceof GridH2TreeIndex))
- continue;
-
- Set<Row> set = new HashSet<>();
-
- GridCursor<GridH2Row> cursor = ((GridH2TreeIndex)idx).rows();
-
- while(cursor.next())
- assertTrue(set.add(cursor.get()));
-
- //((GridH2SnapTreeSet)((GridH2Index)idx).tree).print();
-
- if (rowSet == null || rowSet.isEmpty())
- rowSet = set;
- else
- assertEquals(rowSet, set);
- }
-
- return rowSet;
- }
-
- /**
- * @param idxs Indexes list.
- */
- private void checkOrdered(ArrayList<Index> idxs) throws IgniteCheckedException {
- for (Index idx : idxs) {
- if (!(idx instanceof GridH2TreeIndex))
- continue;
-
- GridH2TreeIndex h2Idx = (GridH2TreeIndex)idx;
-
- checkOrdered(h2Idx, h2Idx);
- }
- }
-
- /**
- * @param idx Index.
- * @param cmp Comparator.
- */
- private void checkOrdered(GridH2TreeIndex idx, Comparator<? super GridH2Row> cmp) throws IgniteCheckedException {
- GridCursor<GridH2Row> cursor = idx.rows();
-
- GridH2Row min = null;
-
- while (cursor.next()) {
- GridH2Row row = cursor.get();
-
- System.out.println(row);
-
- assertNotNull(row);
-
- assertFalse("Incorrect row order in index: " + idx + "\n min: " + min + "\n row: " + row,
- min != null && cmp.compare(min, row) > 0);
-
- min = row;
- }
- }
}
\ No newline at end of file
[22/29] ignite git commit: IGNITE-5741 - Replaced HeapByteBuffer with
DirectByteBuffer in WAL records iterator - Fixes #2329.
Posted by nt...@apache.org.
IGNITE-5741 - Replaced HeapByteBuffer with DirectByteBuffer in WAL records iterator - Fixes #2329.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c23a2dcf
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c23a2dcf
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c23a2dcf
Branch: refs/heads/ignite-5947
Commit: c23a2dcfb1395e87cb4e14457a053c6b4727b318
Parents: 13f38d7
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Mon Aug 14 16:33:12 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 16:41:34 2017 +0300
----------------------------------------------------------------------
.../wal/AbstractWalRecordsIterator.java | 11 ++++-
.../persistence/wal/ByteBufferExpander.java | 22 ++++++---
.../wal/FileWriteAheadLogManager.java | 11 ++---
.../reader/StandaloneWalRecordsIterator.java | 9 ++--
.../apache/ignite/internal/util/GridUnsafe.java | 14 ++++++
.../db/wal/crc/IgniteDataIntegrityTests.java | 52 +++++++++++++++++++-
6 files changed, 100 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
index beed90b..db949c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/AbstractWalRecordsIterator.java
@@ -95,7 +95,6 @@ public abstract class AbstractWalRecordsIterator
this.serializer = serializer;
this.ioFactory = ioFactory;
- // Do not allocate direct buffer for iterator.
buf = new ByteBufferExpander(bufSize, ByteOrder.nativeOrder());
}
@@ -128,6 +127,16 @@ public abstract class AbstractWalRecordsIterator
return curRec != null;
}
+ /** {@inheritDoc} */
+ @Override protected void onClose() throws IgniteCheckedException {
+ try {
+ buf.close();
+ }
+ catch (Exception ex) {
+ throw new IgniteCheckedException(ex);
+ }
+ }
+
/**
* Switches records iterator to the next record.
* <ul>
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/ByteBufferExpander.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/ByteBufferExpander.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/ByteBufferExpander.java
index 829cd5c..cf1db84 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/ByteBufferExpander.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/ByteBufferExpander.java
@@ -19,19 +19,24 @@ package org.apache.ignite.internal.processors.cache.persistence.wal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import org.apache.ignite.internal.util.GridUnsafe;
/**
* ByteBuffer wrapper for dynamically expand buffer size.
*/
-public class ByteBufferExpander {
+public class ByteBufferExpander implements AutoCloseable {
/** Byte buffer */
private ByteBuffer buf;
+ /**
+ * @param initSize Initial size.
+ * @param order Byte order.
+ */
public ByteBufferExpander(int initSize, ByteOrder order) {
- ByteBuffer buffer = ByteBuffer.allocate(initSize);
+ ByteBuffer buffer = GridUnsafe.allocateBuffer(initSize);
buffer.order(order);
- this.buf = buffer;
+ buf = buffer;
}
/**
@@ -49,16 +54,17 @@ public class ByteBufferExpander {
* @return ByteBuffer with requested size.
*/
public ByteBuffer expand(int size) {
- ByteBuffer newBuf = ByteBuffer.allocate(size);
+ ByteBuffer newBuf = GridUnsafe.reallocateBuffer(buf, size);
newBuf.order(buf.order());
- newBuf.put(buf);
-
- newBuf.flip();
-
buf = newBuf;
return newBuf;
}
+
+ /** {@inheritDoc} */
+ @Override public void close() {
+ GridUnsafe.freeBuffer(buf);
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
index 17db8f8..bb1f910 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/FileWriteAheadLogManager.java
@@ -1430,12 +1430,8 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
*/
private int readSerializerVersion(FileIO io, File file, long idx)
throws IOException, IgniteCheckedException {
- try {
- ByteBuffer buf = ByteBuffer.allocate(RecordV1Serializer.HEADER_RECORD_SIZE);
- buf.order(ByteOrder.nativeOrder());
-
- FileInput in = new FileInput(io,
- new ByteBufferExpander(RecordV1Serializer.HEADER_RECORD_SIZE, ByteOrder.nativeOrder()));
+ try (ByteBufferExpander buf = new ByteBufferExpander(RecordV1Serializer.HEADER_RECORD_SIZE, ByteOrder.nativeOrder())){
+ FileInput in = new FileInput(io, buf);
// Header record must be agnostic to the serializer version.
WALRecord rec = serializer.readRecord(in, new FileWALPointer(idx, 0, 0));
@@ -2402,9 +2398,12 @@ public class FileWriteAheadLogManager extends GridCacheSharedManagerAdapter impl
/** {@inheritDoc} */
@Override protected void onClose() throws IgniteCheckedException {
+ super.onClose();
+
curRec = null;
final ReadFileHandle handle = closeCurrentWalSegment();
+
if (handle != null && handle.workDir)
releaseWorkSegment(curWalSegmIdx);
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
index 85022ad..cd0f8ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneWalRecordsIterator.java
@@ -180,9 +180,11 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
FileWALPointer ptr;
- try (FileIO fileIO = ioFactory.create(file, "r")) {
- final DataInput in = new FileInput(fileIO,
- new ByteBufferExpander(HEADER_RECORD_SIZE, ByteOrder.nativeOrder()));
+ try (
+ FileIO fileIO = ioFactory.create(file, "r");
+ ByteBufferExpander buf = new ByteBufferExpander(HEADER_RECORD_SIZE, ByteOrder.nativeOrder())
+ ) {
+ final DataInput in = new FileInput(fileIO, buf);
// Header record must be agnostic to the serializer version.
final int type = in.readUnsignedByte();
@@ -256,6 +258,7 @@ class StandaloneWalRecordsIterator extends AbstractWalRecordsIterator {
/** {@inheritDoc} */
@Override protected void onClose() throws IgniteCheckedException {
super.onClose();
+
curRec = null;
closeCurrentWalSegment();
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
index 0add64d..15e6f2c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java
@@ -139,6 +139,20 @@ public abstract class GridUnsafe {
}
/**
+ *
+ * @param buf Buffer.
+ * @param len New length.
+ * @return Reallocated direct buffer.
+ */
+ public static ByteBuffer reallocateBuffer(ByteBuffer buf, int len) {
+ long ptr = bufferAddress(buf);
+
+ long newPtr = reallocateMemory(ptr, len);
+
+ return wrapPointer(newPtr, len);
+ }
+
+ /**
* Gets boolean value from object field.
*
* @param obj Object.
http://git-wip-us.apache.org/repos/asf/ignite/blob/c23a2dcf/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteDataIntegrityTests.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteDataIntegrityTests.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteDataIntegrityTests.java
index b93c74d..270c560 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteDataIntegrityTests.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/wal/crc/IgniteDataIntegrityTests.java
@@ -41,6 +41,9 @@ public class IgniteDataIntegrityTests extends TestCase {
/** Random access file. */
private RandomAccessFile randomAccessFile;
+ /** Buffer expander. */
+ private ByteBufferExpander expBuf;
+
/** {@inheritDoc} */
@Override protected void setUp() throws Exception {
super.setUp();
@@ -50,9 +53,11 @@ public class IgniteDataIntegrityTests extends TestCase {
randomAccessFile = new RandomAccessFile(file, "rw");
+ expBuf = new ByteBufferExpander(1024, ByteOrder.BIG_ENDIAN);
+
fileInput = new FileInput(
new RandomAccessFileIO(randomAccessFile),
- new ByteBufferExpander(1024, ByteOrder.BIG_ENDIAN)
+ expBuf
);
ByteBuffer buf = ByteBuffer.allocate(1024);
@@ -70,6 +75,12 @@ public class IgniteDataIntegrityTests extends TestCase {
randomAccessFile.getFD().sync();
}
+ /** {@inheritDoc} */
+ @Override protected void tearDown() throws Exception {
+ randomAccessFile.close();
+ expBuf.close();
+ }
+
/**
*
*/
@@ -108,6 +119,45 @@ public class IgniteDataIntegrityTests extends TestCase {
}
/**
+ *
+ */
+ public void testExpandBuffer() {
+ ByteBufferExpander expBuf = new ByteBufferExpander(16, ByteOrder.nativeOrder());
+
+ ByteBuffer b1 = expBuf.buffer();
+
+ b1.put((byte)1);
+ b1.putInt(2);
+ b1.putLong(3L);
+
+ assertEquals(13, b1.position());
+ assertEquals(16, b1.limit());
+
+ ByteBuffer b2 = expBuf.expand(32);
+
+ assertEquals(0, b2.position());
+ assertEquals((byte)1, b2.get());
+ assertEquals(2, b2.getInt());
+ assertEquals(3L, b2.getLong());
+ assertEquals(13, b2.position());
+ assertEquals(32, b2.limit());
+
+ b2.putInt(4);
+
+ assertEquals(17, b2.position());
+ assertEquals(32, b2.limit());
+
+ b2.flip();
+
+ assertEquals(0, b2.position());
+ assertEquals((byte)1, b2.get());
+ assertEquals(2, b2.getInt());
+ assertEquals(3L, b2.getLong());
+ assertEquals(4, b2.getInt());
+ assertEquals(17, b2.limit());
+ }
+
+ /**
* @param rangeFrom Range from.
* @param rangeTo Range to.
*/
[25/29] ignite git commit: IGNITE-6052 request cluster state from
daemon node via compute grid - Fixes #2439.
Posted by nt...@apache.org.
IGNITE-6052 request cluster state from daemon node via compute grid - Fixes #2439.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/305c0f4f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/305c0f4f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/305c0f4f
Branch: refs/heads/ignite-5947
Commit: 305c0f4ffb745bdc04cd0a6f3b45dbd9ff5da302
Parents: cdac5a8
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Mon Aug 14 17:47:11 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 17:48:35 2017 +0300
----------------------------------------------------------------------
.../cluster/GridClusterStateProcessor.java | 64 +++++++++++++++++---
.../IgniteStandByClusterTest.java | 48 ++++++++++++---
2 files changed, 94 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/305c0f4f/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
index 283a58f..13a889c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cluster/GridClusterStateProcessor.java
@@ -55,6 +55,7 @@ import org.apache.ignite.internal.util.typedef.CI2;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteCallable;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.lang.IgniteRunnable;
import org.apache.ignite.resources.IgniteInstanceResource;
@@ -119,6 +120,9 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
* @return Cluster state to be used on public API.
*/
public boolean publicApiActiveState() {
+ if (ctx.isDaemon())
+ return sendComputeCheckGlobalState();
+
DiscoveryDataClusterState globalState = this.globalState;
assert globalState != null;
@@ -407,7 +411,7 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
if (ctx.isDaemon() || ctx.clientNode()) {
GridFutureAdapter<Void> fut = new GridFutureAdapter<>();
- sendCompute(activate, fut);
+ sendComputeChangeGlobalState(activate, fut);
return fut;
}
@@ -490,11 +494,9 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
* @param activate New cluster state.
* @param resFut State change future.
*/
- private void sendCompute(boolean activate, final GridFutureAdapter<Void> resFut) {
+ private void sendComputeChangeGlobalState(boolean activate, final GridFutureAdapter<Void> resFut) {
AffinityTopologyVersion topVer = ctx.discovery().topologyVersionEx();
- IgniteCompute comp = ((ClusterGroupAdapter)ctx.cluster().get().forServers()).compute();
-
if (log.isInfoEnabled()) {
log.info("Sending " + prettyStr(activate) + " request from node [id=" + ctx.localNodeId() +
", topVer=" + topVer +
@@ -502,7 +504,9 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
", daemon" + ctx.isDaemon() + "]");
}
- IgniteFuture<Void> fut = comp.runAsync(new ClientChangeGlobalStateComputeRequest(activate));
+ IgniteCompute comp = ((ClusterGroupAdapter)ctx.cluster().get().forServers()).compute();
+
+ IgniteFuture<Void> fut = comp.runAsync(new ChangeGlobalStateComputeRequest(activate));
fut.listen(new CI1<IgniteFuture>() {
@Override public void apply(IgniteFuture fut) {
@@ -519,6 +523,32 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
}
/**
+ * Check cluster state.
+ *
+ * @return Cluster state, {@code True} if cluster active, {@code False} if inactive.
+ */
+ private boolean sendComputeCheckGlobalState() {
+ AffinityTopologyVersion topVer = ctx.discovery().topologyVersionEx();
+
+ if (log.isInfoEnabled()) {
+ log.info("Sending check cluster state request from node [id=" + ctx.localNodeId() +
+ ", topVer=" + topVer +
+ ", client=" + ctx.clientNode() +
+ ", daemon" + ctx.isDaemon() + "]");
+ }
+ IgniteCompute comp = ((ClusterGroupAdapter)ctx.cluster().get().forServers()).compute();
+
+ return comp.call(new IgniteCallable<Boolean>() {
+ @IgniteInstanceResource
+ private Ignite ig;
+
+ @Override public Boolean call() throws Exception {
+ return ig.active();
+ }
+ });
+ }
+
+ /**
* @param errs Errors.
* @param req State change request.
*/
@@ -854,7 +884,7 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
/**
*
*/
- private static class ClientChangeGlobalStateComputeRequest implements IgniteRunnable {
+ private static class ChangeGlobalStateComputeRequest implements IgniteRunnable {
/** */
private static final long serialVersionUID = 0L;
@@ -863,18 +893,34 @@ public class GridClusterStateProcessor extends GridProcessorAdapter {
/** Ignite. */
@IgniteInstanceResource
- private Ignite ignite;
+ private Ignite ig;
/**
* @param activate New cluster state.
*/
- private ClientChangeGlobalStateComputeRequest(boolean activate) {
+ private ChangeGlobalStateComputeRequest(boolean activate) {
this.activate = activate;
}
/** {@inheritDoc} */
@Override public void run() {
- ignite.active(activate);
+ ig.active(activate);
+ }
+ }
+
+ /**
+ *
+ */
+ private static class CheckGlobalStateComputeRequest implements IgniteCallable<Boolean> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Ignite. */
+ @IgniteInstanceResource
+ private Ignite ig;
+
+ @Override public Boolean call() throws Exception {
+ return ig.active();
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/305c0f4f/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/standbycluster/IgniteStandByClusterTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/standbycluster/IgniteStandByClusterTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/standbycluster/IgniteStandByClusterTest.java
index 30fff08..c2bece0 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/standbycluster/IgniteStandByClusterTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/standbycluster/IgniteStandByClusterTest.java
@@ -252,6 +252,36 @@ public class IgniteStandByClusterTest extends GridCommonAbstractTest {
/**
* @throws Exception if fail.
*/
+ public void testCheckStatusFromDaemon() throws Exception {
+ IgniteEx ig = startGrid(0);
+
+ assertFalse(ig.active());
+
+ ig.active(true);
+
+ IgniteEx daemon = startGrid(
+ getConfiguration("daemon")
+ .setDaemon(true)
+ .setClientMode(true)
+ );
+
+ assertTrue(ig.active());
+ assertTrue(daemon.active());
+
+ daemon.active(false);
+
+ assertFalse(ig.active());
+ assertFalse(daemon.active());
+
+ daemon.active(true);
+
+ assertTrue(ig.active());
+ assertTrue(daemon.active());
+ }
+
+ /**
+ * @throws Exception if fail.
+ */
public void testRestartCluster() throws Exception {
IgniteEx ig1 = startGrid(getConfiguration("node1"));
IgniteEx ig2 = startGrid(getConfiguration("node2"));
@@ -298,25 +328,25 @@ public class IgniteStandByClusterTest extends GridCommonAbstractTest {
ig1.active(true);
- checkPlugin(ig1,1,0);
- checkPlugin(ig2,1,0);
- checkPlugin(ig3,1,0);
+ checkPlugin(ig1, 1, 0);
+ checkPlugin(ig2, 1, 0);
+ checkPlugin(ig3, 1, 0);
ig2.active(false);
ig3.active(true);
- checkPlugin(ig1,2,1);
- checkPlugin(ig2,2,1);
- checkPlugin(ig3,2,1);
+ checkPlugin(ig1, 2, 1);
+ checkPlugin(ig2, 2, 1);
+ checkPlugin(ig3, 2, 1);
ig1.active(false);
ig2.active(true);
- checkPlugin(ig1,3,2);
- checkPlugin(ig2,3,2);
- checkPlugin(ig3,3,2);
+ checkPlugin(ig1, 3, 2);
+ checkPlugin(ig2, 3, 2);
+ checkPlugin(ig3, 3, 2);
}
[06/29] ignite git commit: Merge remote-tracking branch
'upstream/ignite-2.1.4' into ignite-2.1.4
Posted by nt...@apache.org.
Merge remote-tracking branch 'upstream/ignite-2.1.4' into ignite-2.1.4
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d1a74a4b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d1a74a4b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d1a74a4b
Branch: refs/heads/ignite-5947
Commit: d1a74a4be8744528e6ed23706174041ddb0f2618
Parents: 0f22223 772d462
Author: devozerov <vo...@gridgain.com>
Authored: Fri Aug 4 12:04:38 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Aug 4 12:04:38 2017 +0300
----------------------------------------------------------------------
.../ignite/tests/utils/TestTransaction.java | 10 +
.../apache/ignite/IgniteSystemProperties.java | 6 +
.../IgniteDiagnosticPrepareContext.java | 3 +-
.../apache/ignite/internal/IgniteKernal.java | 3 +-
.../mem/file/MappedFileMemoryProvider.java | 3 +-
.../GridCachePartitionExchangeManager.java | 2 +-
.../processors/cache/GridCacheProcessor.java | 16 +-
.../cache/GridCacheSharedContext.java | 24 +
.../processors/cache/GridCacheUtils.java | 7 +-
.../cache/IgniteCacheOffheapManagerImpl.java | 26 +-
.../processors/cache/IgniteCacheProxyImpl.java | 24 +-
.../GridDhtPartitionsExchangeFuture.java | 20 +-
.../cache/distributed/near/GridNearTxLocal.java | 51 ++
.../GridCacheDatabaseSharedManager.java | 7 +-
.../persistence/freelist/FreeListImpl.java | 18 +-
.../wal/FileWriteAheadLogManager.java | 37 +-
.../reader/StandaloneWalRecordsIterator.java | 4 +-
.../store/GridCacheStoreManagerAdapter.java | 10 +
.../cache/transactions/IgniteTxAdapter.java | 20 +-
.../cache/transactions/IgniteTxManager.java | 74 ++
.../cache/transactions/IgniteTxMap.java | 2 +-
.../transactions/TransactionProxyImpl.java | 46 +-
.../cluster/GridClusterStateProcessor.java | 3 +-
.../datastructures/GridCacheLockImpl.java | 13 +-
.../processors/odbc/SqlListenerProcessor.java | 3 +-
.../ignite/internal/util/nio/GridNioServer.java | 7 +-
.../internal/visor/debug/VisorThreadInfo.java | 10 +-
.../internal/visor/query/VisorQueryTask.java | 2 +-
.../visor/query/VisorScanQueryTask.java | 2 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 38 +-
.../apache/ignite/transactions/Transaction.java | 14 +
.../ignite/transactions/TransactionState.java | 7 +-
.../cache/store/jdbc/model/BinaryTest.java | 1 -
.../processors/cache/IgniteCacheGroupsTest.java | 22 +-
...ptimisticTxSuspendResumeMultiServerTest.java | 30 +
.../IgniteOptimisticTxSuspendResumeTest.java | 751 +++++++++++++++++++
.../IgnitePessimisticTxSuspendResumeTest.java | 91 +++
.../IgnitePdsCacheRebalancingAbstractTest.java | 2 +
.../TxOptimisticDeadlockDetectionTest.java | 2 +
.../ignite/testframework/GridTestUtils.java | 26 +
.../cache/GridAbstractCacheStoreSelfTest.java | 10 +
.../testsuites/IgniteCacheTestSuite6.java | 42 ++
.../ignite/tests/p2p/JobStealingTask.java | 12 +-
.../org/apache/ignite/tests/p2p/NodeFilter.java | 30 +
.../hadoop/jobtracker/HadoopJobTracker.java | 24 +-
.../hadoop/shuffle/HadoopShuffleJob.java | 5 +-
.../processors/query/h2/IgniteH2Indexing.java | 21 +-
.../cache/index/H2DynamicTableSelfTest.java | 32 +
.../processors/cache/jta/CacheJtaManager.java | 5 +-
.../processors/cache/jta/CacheJtaResource.java | 28 +-
.../GridJtaTransactionManagerSelfTest.java | 208 +++++
.../ignite/testsuites/IgniteJtaTestSuite.java | 5 +-
.../apache/ignite/stream/mqtt/MqttStreamer.java | 6 +-
.../include/ignite/binary/binary_writer.h | 4 +-
.../ignite/impl/binary/binary_reader_impl.h | 50 +-
.../ignite/impl/binary/binary_type_impl.h | 67 ++
.../ignite/impl/binary/binary_writer_impl.h | 43 +-
.../src/impl/binary/binary_reader_impl.cpp | 63 +-
.../src/impl/binary/binary_writer_impl.cpp | 41 +-
.../core-test/config/cache-query-default.xml | 29 +
.../src/binary_reader_writer_raw_test.cpp | 36 +
.../core-test/src/binary_reader_writer_test.cpp | 135 +++-
.../cpp/core-test/src/cache_query_test.cpp | 215 +++++-
.../cpp/core-test/src/cluster_test.cpp | 13 +
.../ignite/cache/query/query_fields_row.h | 28 +
.../ignite/cache/query/query_sql_fields.h | 13 +-
.../platforms/cpp/core/include/ignite/ignite.h | 15 +
.../ignite/impl/cache/query/query_argument.h | 63 ++
.../impl/cache/query/query_fields_row_impl.h | 29 +
.../ignite/impl/cluster/cluster_group_impl.h | 15 +
.../cpp/core/include/ignite/impl/ignite_impl.h | 24 +-
modules/platforms/cpp/core/src/ignite.cpp | 10 +
.../src/impl/cluster/cluster_group_impl.cpp | 26 +-
.../platforms/cpp/core/src/impl/ignite_impl.cpp | 4 +
.../spi/deployment/uri/UriDeploymentSpi.java | 3 +-
modules/web-console/backend/app/mongo.js | 2 +-
modules/web-console/backend/app/settings.js | 3 +-
modules/web-console/backend/index.js | 16 +-
modules/web-console/backend/middlewares/api.js | 39 +-
.../web-console/backend/services/activities.js | 12 +-
modules/web-console/frontend/app/app.js | 10 +-
.../components/grid-item-selected/component.js | 28 +
.../components/grid-item-selected/controller.js | 38 +
.../app/components/grid-item-selected/index.js | 24 +
.../components/grid-item-selected/template.pug | 17 +
.../list-of-registered-users.tpl.pug | 4 +-
.../app/components/ui-grid-hovering/cell.js | 48 ++
.../app/components/ui-grid-hovering/hovering.js | 31 +
.../app/components/ui-grid-hovering/index.js | 30 +
.../app/components/ui-grid-hovering/style.scss | 22 +
.../app/components/ui-grid-hovering/viewport.js | 42 ++
.../frontend/app/controllers/auth.controller.js | 9 +-
.../app/modules/agent/AgentManager.service.js | 24 +-
.../app/modules/agent/AgentModal.service.js | 8 +-
.../configuration/generator/Maven.service.js | 13 +-
.../frontend/app/modules/demo/Demo.module.js | 22 +-
.../frontend/app/modules/sql/sql.controller.js | 11 +-
.../states/configuration/clusters/hadoop.pug | 2 +-
.../configuration/summary/summary.worker.js | 4 +-
.../frontend/app/modules/states/errors.state.js | 2 +-
.../app/modules/states/password.state.js | 2 +
.../app/modules/states/profile.state.js | 2 +-
.../frontend/app/modules/states/signin.state.js | 6 +-
.../app/modules/user/AclRoute.provider.js | 50 --
.../frontend/app/modules/user/user.module.js | 35 +-
.../frontend/app/services/Messages.service.js | 7 +
.../web-console/frontend/views/signin.tpl.pug | 2 +-
.../views/templates/agent-download.tpl.pug | 2 -
108 files changed, 2918 insertions(+), 440 deletions(-)
----------------------------------------------------------------------
[24/29] ignite git commit: IGNITE-5843 Persist cache configuration
received on node join - Fixes #2347.
Posted by nt...@apache.org.
IGNITE-5843 Persist cache configuration received on node join - Fixes #2347.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/cdac5a87
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/cdac5a87
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/cdac5a87
Branch: refs/heads/ignite-5947
Commit: cdac5a87cb1432ffd0ec32a2888505805e7348da
Parents: 2f38065
Author: EdShangGG <es...@gridgain.com>
Authored: Mon Aug 14 16:56:11 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 17:32:01 2017 +0300
----------------------------------------------------------------------
.../cache/CacheAffinitySharedManager.java | 56 +++++++++++++++-----
.../GridCacheDatabaseSharedManager.java | 15 +++---
.../persistence/file/FilePageStoreManager.java | 1 -
.../processors/query/GridQueryProcessor.java | 15 ------
.../persistence/IgnitePdsDynamicCacheTest.java | 43 +++++++++++++++
5 files changed, 92 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/cdac5a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index d251d52..9fc791e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -720,13 +720,6 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
try {
- // Save configuration before cache started.
- if (cctx.pageStore() != null && !cctx.kernalContext().clientNode()) {
- cctx.pageStore().storeCacheData(
- new StoredCacheData(req.startCacheConfiguration())
- );
- }
-
if (startCache) {
cctx.cache().prepareCacheStart(req.startCacheConfiguration(),
cacheDesc,
@@ -2157,7 +2150,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
/**
*
*/
- static class CachesInfo {
+ class CachesInfo {
/** Registered cache groups (updated from exchange thread). */
private final ConcurrentHashMap<Integer, CacheGroupDescriptor> registeredGrps = new ConcurrentHashMap<>();
@@ -2170,10 +2163,29 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
*/
void init(Map<Integer, CacheGroupDescriptor> grps, Map<String, DynamicCacheDescriptor> caches) {
for (CacheGroupDescriptor grpDesc : grps.values())
- registeredGrps.put(grpDesc.groupId(), grpDesc);
+ registerGroup(grpDesc);
for (DynamicCacheDescriptor cacheDesc : caches.values())
- registeredCaches.put(cacheDesc.cacheId(), cacheDesc);
+ registerCache(cacheDesc);
+ }
+
+
+ /**
+ * @param desc Description.
+ */
+ private DynamicCacheDescriptor registerCache(DynamicCacheDescriptor desc) {
+ saveCacheConfiguration(desc.cacheConfiguration());
+
+ return registeredCaches.put(desc.cacheId(), desc);
+ }
+
+ /**
+ * @param grpDesc Group description.
+ */
+ private CacheGroupDescriptor registerGroup(CacheGroupDescriptor grpDesc) {
+ saveCacheConfiguration(grpDesc.config());
+
+ return registeredGrps.put(grpDesc.groupId(), grpDesc);
}
/**
@@ -2203,10 +2215,10 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
CacheGroupDescriptor grpDesc = desc.groupDescriptor();
if (!registeredGrps.containsKey(grpDesc.groupId()))
- registeredGrps.put(grpDesc.groupId(), grpDesc);
+ registerGroup(grpDesc);
if (!registeredCaches.containsKey(desc.cacheId()))
- registeredCaches.put(desc.cacheId(), desc);
+ registerCache(desc);
}
}
@@ -2221,7 +2233,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
}
for (ExchangeActions.CacheGroupActionData startAction : exchActions.cacheGroupsToStart()) {
- CacheGroupDescriptor old = registeredGrps.put(startAction.descriptor().groupId(), startAction.descriptor());
+ CacheGroupDescriptor old = registerGroup(startAction.descriptor());
assert old == null : old;
}
@@ -2230,7 +2242,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
registeredCaches.remove(req.descriptor().cacheId());
for (ExchangeActions.CacheActionData req : exchActions.cacheStartRequests())
- registeredCaches.put(req.descriptor().cacheId(), req.descriptor());
+ registerCache(req.descriptor());
}
/**
@@ -2250,4 +2262,20 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
registeredCaches.clear();
}
}
+
+ /**
+ * @param cfg cache configuration
+ */
+ private void saveCacheConfiguration(CacheConfiguration<?, ?> cfg) {
+ if (cctx.pageStore() != null && cctx.database().persistenceEnabled() && !cctx.kernalContext().clientNode()) {
+ try {
+ cctx.pageStore().storeCacheData(
+ new StoredCacheData(cfg)
+ );
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log(), "Error while saving cache configuration on disk, cfg = " + cfg, e);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/cdac5a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
index a1eb4af..56dcac0 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheDatabaseSharedManager.java
@@ -56,9 +56,6 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.management.InstanceNotFoundException;
-import javax.management.JMException;
-import javax.management.MBeanRegistrationException;
import javax.management.ObjectName;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
@@ -98,6 +95,7 @@ import org.apache.ignite.internal.pagemem.wal.record.delta.PartitionDestroyRecor
import org.apache.ignite.internal.pagemem.wal.record.delta.PartitionMetaStateRecord;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.cache.CacheGroupDescriptor;
import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
@@ -1453,11 +1451,12 @@ public class GridCacheDatabaseSharedManager extends IgniteCacheDatabaseSharedMan
// TODO IGNITE-5075: cache descriptor can be removed.
GridCacheSharedContext sharedCtx = context();
- String memPlcName = sharedCtx
- .cache()
- .cacheGroupDescriptors().get(grpId)
- .config()
- .getMemoryPolicyName();
+ CacheGroupDescriptor desc = sharedCtx.cache().cacheGroupDescriptors().get(grpId);
+
+ if (desc == null)
+ throw new IgniteCheckedException("Failed to find cache group descriptor [grpId=" + grpId + ']');
+
+ String memPlcName = desc.config().getMemoryPolicyName();
return (PageMemoryEx)sharedCtx.database().memoryPolicy(memPlcName).pageMemory();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/cdac5a87/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index 0041ea6..13bcd2a 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -210,7 +210,6 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
@Override public void storeCacheData(
StoredCacheData cacheData
) throws IgniteCheckedException {
-
File cacheWorkDir = cacheWorkDirectory(cacheData.config());
File file;
http://git-wip-us.apache.org/repos/asf/ignite/blob/cdac5a87/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
index d44be2c..baafb1e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
@@ -504,21 +504,6 @@ public class GridQueryProcessor extends GridProcessorAdapter {
if (cacheDesc != null && F.eq(cacheDesc.deploymentId(), proposeMsg.deploymentId()))
cacheDesc.schemaChangeFinish(msg);
-
- if (ctx.cache().context().pageStore() != null &&
- ctx.cache().context().database().persistenceEnabled()) {
-
- StoredCacheData cacheData = new StoredCacheData(cacheDesc.cacheConfiguration());
-
- cacheData.queryEntities(cacheDesc.schema().entities());
-
- try {
- ctx.cache().context().pageStore().storeCacheData(cacheData);
- }
- catch (IgniteCheckedException e) {
- throw new IllegalStateException("Failed to persist cache data: " + cacheData.config().getName(), e);
- }
- }
}
// Propose message will be used from exchange thread to
http://git-wip-us.apache.org/repos/asf/ignite/blob/cdac5a87/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDynamicCacheTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDynamicCacheTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDynamicCacheTest.java
index 189b866..5873a35 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDynamicCacheTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsDynamicCacheTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.persistence;
import java.io.Serializable;
import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
@@ -160,6 +161,48 @@ public class IgnitePdsDynamicCacheTest extends IgniteDbDynamicCacheSelfTest {
}
/**
+ * @throws Exception If failed.
+ */
+ public void testDynamicCacheSavingOnNewNode() throws Exception {
+ Ignite ignite = startGrid(0);
+
+ ignite.active(true);
+
+ CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME);
+
+ ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
+ ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+ ccfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+ ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
+
+ IgniteCache cache = ignite.getOrCreateCache(ccfg);
+
+ for (int i = 0; i < 160; i++)
+ cache.put(i, i);
+
+ ignite = startGrid(1);
+
+ awaitPartitionMapExchange();
+
+ cache = ignite.cache(DEFAULT_CACHE_NAME);
+
+ for (int i = 0; i < 160; i++)
+ assertEquals(i, cache.get(i));
+
+ stopAllGrids(true);
+
+ startGrid(0);
+ ignite = startGrid(1);
+
+ ignite.active(true);
+
+ cache = ignite.cache(DEFAULT_CACHE_NAME);
+
+ for (int i = 0; i < 160; i++)
+ assertEquals(i, cache.get(i));
+ }
+
+ /**
* @throws IgniteCheckedException If failed.
*/
private void deleteWorkFiles() throws IgniteCheckedException {
[19/29] ignite git commit: Merge branch 'ignite-2.1.3' into
ignite-2.1.4
Posted by nt...@apache.org.
Merge branch 'ignite-2.1.3' into ignite-2.1.4
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/74d6ab99
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/74d6ab99
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/74d6ab99
Branch: refs/heads/ignite-5947
Commit: 74d6ab9916b3a01c78cdf1ad86211c9fcbb2214d
Parents: 3a7d4f4 2e5c343
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Mon Aug 14 11:08:28 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 11:08:28 2017 +0300
----------------------------------------------------------------------
.../cache/persistence/tree/io/PagePartitionCountersIO.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
[29/29] ignite git commit: IGNITE-5497 WIP
Posted by nt...@apache.org.
IGNITE-5497 WIP
Signed-off-by: nikolay_tikhonov <nt...@gridgain.com>
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/49bc7fb4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/49bc7fb4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/49bc7fb4
Branch: refs/heads/ignite-5947
Commit: 49bc7fb414d14e78bd913390a9913b0c79d085fc
Parents: 020ff36
Author: nikolay_tikhonov <nt...@gridgain.com>
Authored: Tue Aug 15 20:51:44 2017 +0300
Committer: nikolay_tikhonov <nt...@gridgain.com>
Committed: Tue Aug 15 20:59:27 2017 +0300
----------------------------------------------------------------------
.../processors/cache/CacheObjectUtils.java | 27 +-
.../cache/CacheTwoDimensionalArrayTest.java | 291 +++++++++++++++++++
2 files changed, 316 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/49bc7fb4/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectUtils.java
index f9c76df..6a63768 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectUtils.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.processors.cache;
+import java.lang.reflect.Array;
import org.apache.ignite.internal.binary.BinaryUtils;
import org.apache.ignite.internal.util.typedef.F;
@@ -123,8 +124,30 @@ public class CacheObjectUtils {
Object[] res = new Object[arr.length];
- for (int i = 0; i < arr.length; i++)
- res[i] = unwrapBinary(ctx, arr[i], keepBinary, cpy);
+ boolean canCastArray = true;
+ Class cls = null;
+
+ for (int i = 0; i < arr.length; i++) {
+ Object obj = unwrapBinary(ctx, arr[i], keepBinary, cpy);
+
+ res[i] = obj;
+
+ if (canCastArray && obj != null) {
+ if (cls == null)
+ cls = obj.getClass();
+ else if (cls != obj.getClass())
+ canCastArray = false;
+ }
+ }
+
+ // If array contains all element the same type then will create typed array.
+ if (canCastArray && cls != null) {
+ Object[] res0 = (Object[])Array.newInstance(cls, res.length);
+
+ System.arraycopy(res, 0, res0, 0, res.length);
+
+ res = res0;
+ }
return res;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/49bc7fb4/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTwoDimensionalArrayTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTwoDimensionalArrayTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTwoDimensionalArrayTest.java
new file mode 100644
index 0000000..69d457c
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTwoDimensionalArrayTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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.cache;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ *
+ */
+public class CacheTwoDimensionalArrayTest extends GridCommonAbstractTest {
+ /** */
+ private static int NODES = 3;
+
+ /** */
+ private static int KEYS = 100;
+
+ /** */
+ private static int size = 5;
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ startGridsMultiThreaded(NODES);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSimpleModel() throws Exception {
+ doTestSimpleModel(ATOMIC, PARTITIONED);
+ }
+
+ /**
+ * @param atomicityMode Cache atomicity mode.
+ * @param cacheMode Cache mode.
+ *
+ * @throws Exception If failed.
+ */
+ private void doTestSimpleModel(CacheAtomicityMode atomicityMode, CacheMode cacheMode) throws Exception {
+ CacheConfiguration ccfg = getConfiguration(atomicityMode, cacheMode);
+
+ ignite(0).getOrCreateCache(ccfg);
+
+ int n = size, m = size -1;
+
+ // Primitive empty array.
+ {
+ IgniteCache<Integer, int[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, new int[n][m]);
+
+ for (int key = 0; key < KEYS; key++) {
+ int[][] exp = new int[n][m];
+
+ int[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ // Object empty array.
+ {
+ IgniteCache<Integer, Object[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, new Object[n][m]);
+
+ for (int key = 0; key < KEYS; key++) {
+ Object[][] exp = new Object[n][m];
+
+ Object[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ {
+ IgniteCache<Integer, int[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, intArray(n, m, key));
+
+ for (int key = 0; key < KEYS; key++) {
+ int[][] exp = intArray(n, m, key);
+
+ int[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ {
+ IgniteCache<Integer, int[][][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, new int[5][6][7]);
+
+ for (int key = 0; key < KEYS; key++) {
+ int[][][] exp = new int[5][6][7];
+
+ int[][][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ {
+ IgniteCache<Integer, Object[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, objectArray(n, m, key));
+
+ for (int key = 0; key < KEYS; key++) {
+ Object[][] exp = objectArray(n, m, key);
+
+ Object[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ {
+ IgniteCache<Integer, TestObject[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, testObjectArray(n, m, key));
+
+ for (int key = 0; key < KEYS; key++) {
+ TestObject[][] exp = testObjectArray(n, m, key);
+
+ TestObject[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+
+ {
+ IgniteCache<Integer, TestObject[][]> cache = ignite(0).cache(ccfg.getName());
+
+ for (int key = 0; key < KEYS; key++)
+ cache.put(key, testObjectArray(n, m, key));
+
+ for (int key = 0; key < KEYS; key++) {
+ TestObject[][] exp = testObjectArray(n, m, key);
+
+ TestObject[][] act = cache.get(key);
+
+ assertArrayEquals(exp, act);
+ }
+
+ cache.removeAll();
+ }
+ }
+
+ /**
+ * @return Array.
+ */
+ private int[][] intArray(int n, int m,int K) {
+ int[][] arr = new int[n][m];
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m; j++)
+ arr[i][j] = (i + j) * K;
+ }
+
+ return arr;
+ }
+
+ /**
+ * @return Array.
+ */
+ private Object[][] objectArray(int n, int m, int K) {
+ Object[][] arr = new Object[n][m];
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m; j++)
+ arr[i][j] = ((n + m) % 2 == 0) ? (i + j) * K : new TestObject((i + j) * K);
+ }
+
+ return arr;
+ }
+
+ /**
+ * @return Array.
+ */
+ private TestObject[][] testObjectArray(int n, int m, int K) {
+ TestObject[][] arr = new TestObject[n][m];
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m; j++)
+ arr[i][j] = new TestObject((i + j) * K);
+ }
+
+ return arr;
+ }
+
+ /**
+ * @param atomicityMode Atomicity mode.
+ * @param cacheMode Cache mode.
+ *
+ * @return Cache configuration.
+ */
+ @NotNull private CacheConfiguration getConfiguration(CacheAtomicityMode atomicityMode,
+ CacheMode cacheMode) {
+ CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME);
+
+ ccfg.setCacheMode(cacheMode);
+ ccfg.setAtomicityMode(atomicityMode);
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+ ccfg.setBackups(1);
+
+ return ccfg;
+ }
+
+ /**
+ *
+ */
+ private static class TestObject {
+ /** */
+ private int val;
+
+ /**
+ * @param val Value.
+ */
+ public TestObject(int val) {
+ this.val = val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ TestObject object = (TestObject)o;
+
+ return val == object.val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return val;
+ }
+ }
+}
[21/29] ignite git commit: IGNITE-5890 Added estimated time to
rebalance completion and time to rebalance start to MXBean - Fixes #2386.
Posted by nt...@apache.org.
IGNITE-5890 Added estimated time to rebalance completion and time to rebalance start to MXBean - Fixes #2386.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/13f38d79
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/13f38d79
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/13f38d79
Branch: refs/heads/ignite-5947
Commit: 13f38d79b57b395e43d42a8f3c278cf48336d7c5
Parents: fde550b
Author: Dmitriy Govorukhin <dm...@gmail.com>
Authored: Mon Aug 14 12:12:46 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 14:17:42 2017 +0300
----------------------------------------------------------------------
.../org/apache/ignite/cache/CacheMetrics.java | 10 ++
.../cache/CacheClusterMetricsMXBeanImpl.java | 10 ++
.../cache/CacheLocalMetricsMXBeanImpl.java | 10 ++
.../processors/cache/CacheMetricsImpl.java | 36 +++++-
.../processors/cache/CacheMetricsSnapshot.java | 18 +++
.../dht/preloader/GridDhtPartitionDemander.java | 22 +++-
.../dht/preloader/GridDhtPreloader.java | 18 +--
.../cache/CacheGroupsMetricsRebalanceTest.java | 118 +++++++++++++++++++
.../platform/PlatformCacheWriteMetricsTask.java | 10 ++
9 files changed, 234 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java b/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java
index 0cff4a8..20ea692 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheMetrics.java
@@ -506,6 +506,16 @@ public interface CacheMetrics {
public long getRebalancingBytesRate();
/**
+ * @return Estimated rebalancing finished time.
+ */
+ public long estimateRebalancingFinishTime();
+
+ /**
+ * @return Rebalancing start time.
+ */
+ public long rebalancingStartTime();
+
+ /**
* Checks whether statistics collection is enabled in this cache.
* <p>
* The default value is {@code false}.
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java
index 266c577..df4a6ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheClusterMetricsMXBeanImpl.java
@@ -382,4 +382,14 @@ class CacheClusterMetricsMXBeanImpl implements CacheMetricsMXBean {
@Override public long getRebalancingBytesRate() {
return cache.clusterMetrics().getRebalancingBytesRate();
}
+
+ /** {@inheritDoc} */
+ @Override public long estimateRebalancingFinishTime() {
+ return cache.clusterMetrics().estimateRebalancingFinishTime();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long rebalancingStartTime() {
+ return cache.clusterMetrics().rebalancingStartTime();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java
index f363bfe..a767193 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLocalMetricsMXBeanImpl.java
@@ -382,4 +382,14 @@ class CacheLocalMetricsMXBeanImpl implements CacheMetricsMXBean {
@Override public long getRebalancingBytesRate() {
return cache.metrics0().getRebalancingBytesRate();
}
+
+ /** {@inheritDoc} */
+ @Override public long estimateRebalancingFinishTime() {
+ return cache.metrics0().estimateRebalancingFinishTime();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long rebalancingStartTime() {
+ return cache.metrics0().rebalancingStartTime();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
index 6a8ae0b..d03a6f8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsImpl.java
@@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
import org.apache.ignite.internal.processors.cache.store.GridCacheWriteBehindStore;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
/**
* Adapter for cache metrics.
@@ -108,6 +109,9 @@ public class CacheMetricsImpl implements CacheMetrics {
/** Total rebalanced bytes count. */
private AtomicLong totalRebalancedBytes = new AtomicLong();
+ /** Rebalanced start time. */
+ private AtomicLong rebalanceStartTime = new AtomicLong(-1L);
+
/** Estimated rebalancing keys count. */
private AtomicLong estimatedRebalancingKeys = new AtomicLong();
@@ -734,7 +738,7 @@ public class CacheMetricsImpl implements CacheMetrics {
}
/** {@inheritDoc} */
- public int getTotalPartitionsCount() {
+ @Override public int getTotalPartitionsCount() {
int res = 0;
if (cctx.isLocal())
@@ -749,7 +753,7 @@ public class CacheMetricsImpl implements CacheMetrics {
}
/** {@inheritDoc} */
- public int getRebalancingPartitionsCount() {
+ @Override public int getRebalancingPartitionsCount() {
int res = 0;
if (cctx.isLocal())
@@ -764,17 +768,17 @@ public class CacheMetricsImpl implements CacheMetrics {
}
/** {@inheritDoc} */
- public long getKeysToRebalanceLeft() {
+ @Override public long getKeysToRebalanceLeft() {
return Math.max(0, estimatedRebalancingKeys.get() - rebalancedKeys.get());
}
/** {@inheritDoc} */
- public long getRebalancingKeysRate() {
+ @Override public long getRebalancingKeysRate() {
return rebalancingKeysRate.getRate();
}
/** {@inheritDoc} */
- public long getRebalancingBytesRate() {
+ @Override public long getRebalancingBytesRate() {
return rebalancingBytesRate.getRate();
}
@@ -791,6 +795,28 @@ public class CacheMetricsImpl implements CacheMetrics {
rebalancingBytesRate.clear();
rebalancingKeysRate.clear();
+
+ rebalanceStartTime.set(-1L);
+ }
+
+ /**
+ *
+ */
+ public void startRebalance(long delay){
+ rebalanceStartTime.addAndGet(delay + U.currentTimeMillis());
+ }
+
+ /** {@inheritDoc} */
+ @Override public long estimateRebalancingFinishTime() {
+ long rate = rebalancingKeysRate.getRate();
+
+ return rate <= 0 ? -1L :
+ ((getKeysToRebalanceLeft() / rate) * REBALANCE_RATE_INTERVAL) + U.currentTimeMillis();
+ }
+
+ /** {@inheritDoc} */
+ @Override public long rebalancingStartTime() {
+ return rebalanceStartTime.get();
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java
index e9141c6..2d38db8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheMetricsSnapshot.java
@@ -203,6 +203,12 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable {
/** Get rebalancing bytes rate. */
private long rebalancingBytesRate;
+ /** Start rebalance time. */
+ private long rebalanceStartTime;
+
+ /** Estimate rebalance finish time. */
+ private long rebalanceFinishTime;
+
/** */
private String keyType;
@@ -307,6 +313,8 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable {
keysToRebalanceLeft = m.getKeysToRebalanceLeft();
rebalancingBytesRate = m.getRebalancingBytesRate();
rebalancingKeysRate = m.getRebalancingKeysRate();
+ rebalanceStartTime = m.rebalancingStartTime();
+ rebalanceFinishTime = m.estimateRebalancingFinishTime();
}
/**
@@ -716,6 +724,16 @@ public class CacheMetricsSnapshot implements CacheMetrics, Externalizable {
}
/** {@inheritDoc} */
+ @Override public long estimateRebalancingFinishTime() {
+ return rebalanceFinishTime;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long rebalancingStartTime() {
+ return rebalanceStartTime;
+ }
+
+ /** {@inheritDoc} */
@Override public boolean isWriteBehindEnabled() {
return isWriteBehindEnabled;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
index 248b739..2258187 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
@@ -257,11 +257,13 @@ public class GridDhtPartitionDemander {
* @param forcedRebFut External future for forced rebalance.
* @return Rebalancing runnable.
*/
- Runnable addAssignments(final GridDhtPreloaderAssignments assigns,
+ Runnable addAssignments(
+ final GridDhtPreloaderAssignments assigns,
boolean force,
int cnt,
final Runnable next,
- @Nullable final GridCompoundFuture<Boolean, Boolean> forcedRebFut) {
+ @Nullable final GridCompoundFuture<Boolean, Boolean> forcedRebFut
+ ) {
if (log.isDebugEnabled())
log.debug("Adding partition assignments: " + assigns);
@@ -289,14 +291,14 @@ public class GridDhtPartitionDemander {
rebalanceFut = fut;
- fut.sendRebalanceStartedEvent();
-
- for (GridCacheContext cctx : grp.caches()) {
+ for (final GridCacheContext cctx : grp.caches()) {
if (cctx.config().isStatisticsEnabled()) {
final CacheMetricsImpl metrics = cctx.cache().metrics0();
metrics.clearRebalanceCounters();
+ metrics.startRebalance(0);
+
rebalanceFut.listen(new IgniteInClosure<IgniteInternalFuture<Boolean>>() {
@Override public void apply(IgniteInternalFuture<Boolean> fut) {
metrics.clearRebalanceCounters();
@@ -305,6 +307,8 @@ public class GridDhtPartitionDemander {
}
}
+ fut.sendRebalanceStartedEvent();
+
if (assigns.cancelled()) { // Pending exchange.
if (log.isDebugEnabled())
log.debug("Rebalancing skipped due to cancelled assignments.");
@@ -350,6 +354,14 @@ public class GridDhtPartitionDemander {
};
}
else if (delay > 0) {
+ for (GridCacheContext cctx : grp.caches()) {
+ if (cctx.config().isStatisticsEnabled()) {
+ final CacheMetricsImpl metrics = cctx.cache().metrics0();
+
+ metrics.startRebalance(delay);
+ }
+ }
+
GridTimeoutObject obj = lastTimeoutObj.get();
if (obj != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
index 7efd4aa..305da92 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
@@ -306,12 +306,12 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
GridDhtPartitionDemandMessage msg = assigns.get(n);
- if (msg == null) {
- assigns.put(n, msg = new GridDhtPartitionDemandMessage(
- top.updateSequence(),
- exchId.topologyVersion(),
- grp.groupId()));
- }
+ if (msg == null) {
+ assigns.put(n, msg = new GridDhtPartitionDemandMessage(
+ top.updateSequence(),
+ exchId.topologyVersion(),
+ grp.groupId()));
+ }
msg.addPartition(p, false);
}
@@ -396,11 +396,13 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
}
/** {@inheritDoc} */
- @Override public Runnable addAssignments(GridDhtPreloaderAssignments assignments,
+ @Override public Runnable addAssignments(
+ GridDhtPreloaderAssignments assignments,
boolean forceRebalance,
int cnt,
Runnable next,
- @Nullable GridCompoundFuture<Boolean, Boolean> forcedRebFut) {
+ @Nullable GridCompoundFuture<Boolean, Boolean> forcedRebFut
+ ) {
return demander.addAssignments(assignments, forceRebalance, cnt, next, forcedRebFut);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
index c15fa5f..a1a855a 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGroupsMetricsRebalanceTest.java
@@ -21,20 +21,28 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CacheRebalanceMode;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.CacheRebalancingEvent;
import org.apache.ignite.events.Event;
import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.util.typedef.PA;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_REBALANCE_STATISTICS_TIME_INTERVAL;
+import static org.apache.ignite.testframework.GridTestUtils.runAsync;
+import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
+
/**
*
*/
@@ -71,6 +79,7 @@ public class CacheGroupsMetricsRebalanceTest extends GridCommonAbstractTest {
.setCacheMode(CacheMode.PARTITIONED)
.setAtomicityMode(CacheAtomicityMode.ATOMIC)
.setRebalanceMode(CacheRebalanceMode.ASYNC)
+ .setRebalanceBatchSize(100)
.setStatisticsEnabled(true);
CacheConfiguration cfg2 = new CacheConfiguration(cfg1)
@@ -137,4 +146,113 @@ public class CacheGroupsMetricsRebalanceTest extends GridCommonAbstractTest {
assertTrue(ratio > 40 && ratio < 60);
}
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testRebalanceEstimateFinishTime() throws Exception {
+ System.setProperty(IGNITE_REBALANCE_STATISTICS_TIME_INTERVAL, String.valueOf(1000));
+
+ Ignite ig1 = startGrid(1);
+
+ final int KEYS = 4_000_000;
+
+ IgniteCache<Object, Object> cache1 = ig1.cache(CACHE1);
+
+ try (IgniteDataStreamer<Integer, String> st = ig1.dataStreamer(CACHE1)) {
+ for (int i = 0; i < KEYS; i++)
+ st.addData(i, CACHE1 + "-" + i);
+ }
+
+ final CountDownLatch finishRebalanceLatch = new CountDownLatch(1);
+
+ final Ignite ig2 = startGrid(2);
+
+ ig2.events().localListen(new IgnitePredicate<Event>() {
+ @Override public boolean apply(Event evt) {
+ CacheRebalancingEvent rebEvent = (CacheRebalancingEvent)evt;
+
+ if (rebEvent.cacheName().equals(CACHE1)) {
+ System.out.println("CountDown rebalance stop latch:" + rebEvent.cacheName());
+
+ finishRebalanceLatch.countDown();
+ }
+
+ return false;
+ }
+ }, EventType.EVT_CACHE_REBALANCE_STOPPED);
+
+ waitForCondition(new PA() {
+ @Override public boolean apply() {
+ return ig2.cache(CACHE1).localMetrics().rebalancingStartTime() != -1L;
+ }
+ }, 5_000);
+
+ CacheMetrics metrics = ig2.cache(CACHE1).localMetrics();
+
+ long startTime = metrics.rebalancingStartTime();
+
+ assertTrue(startTime > 0);
+ assertTrue((U.currentTimeMillis() - startTime) < 5000);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ runAsync(new Runnable() {
+ @Override public void run() {
+ // Waiting 25% keys will be rebalanced.
+ int partKeys = KEYS / 2;
+
+ final long keysLine = (long)(partKeys - (partKeys * 0.25));
+
+ System.out.println("Wait until keys left will be less " + keysLine);
+
+ while (finishRebalanceLatch.getCount() != 0) {
+ CacheMetrics m = ig2.cache(CACHE1).localMetrics();
+
+ long keyLeft = m.getKeysToRebalanceLeft();
+
+ if (keyLeft > 0 && keyLeft < keysLine)
+ latch.countDown();
+
+ System.out.println("Keys left: " + m.getKeysToRebalanceLeft());
+
+ try {
+ Thread.sleep(1_000);
+ }
+ catch (InterruptedException e) {
+ System.out.println("Interrupt thread: " + e.getMessage());
+
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ });
+
+ latch.await();
+
+ long finishTime = ig2.cache(CACHE1).localMetrics().estimateRebalancingFinishTime();
+
+ assertTrue(finishTime > 0);
+
+ long timePassed = U.currentTimeMillis() - startTime;
+ long timeLeft = finishTime - System.currentTimeMillis();
+
+ assertTrue(finishRebalanceLatch.await(timeLeft + 2_000, TimeUnit.SECONDS));
+
+ System.out.println(
+ "TimePassed:" + timePassed +
+ "\nTimeLeft:" + timeLeft +
+ "\nTime to rebalance: " + (finishTime - startTime) +
+ "\nStartTime: " + startTime +
+ "\nFinishTime: " + finishTime
+ );
+
+ System.clearProperty(IGNITE_REBALANCE_STATISTICS_TIME_INTERVAL);
+
+ System.out.println("Rebalance time:" + (U.currentTimeMillis() - startTime));
+
+ long diff = finishTime - U.currentTimeMillis();
+
+ assertTrue("Expected less 5000, Actual:" + diff, Math.abs(diff) < 10_000);
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/13f38d79/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java
index f1d8114..64ff0bc 100644
--- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java
+++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformCacheWriteMetricsTask.java
@@ -433,6 +433,16 @@ public class PlatformCacheWriteMetricsTask extends ComputeTaskAdapter<Long, Obje
@Override public long getHeapEntriesCount() {
return 59;
}
+
+ /** {@inheritDoc} */
+ @Override public long estimateRebalancingFinishTime() {
+ return 60;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long rebalancingStartTime() {
+ return 61;
+ }
}
}
[03/29] ignite git commit: ignite-5712 Context switching for
optimistic transactions
Posted by nt...@apache.org.
ignite-5712 Context switching for optimistic transactions
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e255a564
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e255a564
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e255a564
Branch: refs/heads/ignite-5947
Commit: e255a564985a12113984ec02f15a4443495b8ffc
Parents: 3fdf453
Author: Nikolay Izhikov <ni...@gmail.com>
Authored: Wed Aug 2 11:52:44 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Aug 2 18:55:36 2017 +0300
----------------------------------------------------------------------
.../ignite/tests/utils/TestTransaction.java | 10 +
.../cache/GridCacheSharedContext.java | 24 +
.../cache/distributed/near/GridNearTxLocal.java | 51 ++
.../store/GridCacheStoreManagerAdapter.java | 10 +
.../cache/transactions/IgniteTxAdapter.java | 20 +-
.../cache/transactions/IgniteTxManager.java | 74 ++
.../cache/transactions/IgniteTxMap.java | 2 +-
.../transactions/TransactionProxyImpl.java | 46 +-
.../apache/ignite/transactions/Transaction.java | 14 +
.../ignite/transactions/TransactionState.java | 7 +-
...ptimisticTxSuspendResumeMultiServerTest.java | 30 +
.../IgniteOptimisticTxSuspendResumeTest.java | 751 +++++++++++++++++++
.../IgnitePessimisticTxSuspendResumeTest.java | 91 +++
.../ignite/testframework/GridTestUtils.java | 26 +
.../cache/GridAbstractCacheStoreSelfTest.java | 10 +
.../testsuites/IgniteCacheTestSuite6.java | 42 ++
.../processors/cache/jta/CacheJtaManager.java | 5 +-
.../processors/cache/jta/CacheJtaResource.java | 28 +-
.../GridJtaTransactionManagerSelfTest.java | 208 +++++
.../ignite/testsuites/IgniteJtaTestSuite.java | 5 +-
20 files changed, 1438 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/cassandra/store/src/test/java/org/apache/ignite/tests/utils/TestTransaction.java
----------------------------------------------------------------------
diff --git a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/utils/TestTransaction.java b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/utils/TestTransaction.java
index 4a03d25..e587bd7 100644
--- a/modules/cassandra/store/src/test/java/org/apache/ignite/tests/utils/TestTransaction.java
+++ b/modules/cassandra/store/src/test/java/org/apache/ignite/tests/utils/TestTransaction.java
@@ -140,4 +140,14 @@ public class TestTransaction implements Transaction {
@Override public IgniteFuture<Void> rollbackAsync() throws IgniteException {
return null;
}
+
+ /** {@inheritDoc} */
+ @Override public void suspend() throws IgniteException{
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void resume() throws IgniteException {
+ // No-op.
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index 5387cc8..3fb63dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -944,6 +944,30 @@ public class GridCacheSharedContext<K, V> {
}
/**
+ * Suspends transaction. It could be resume later. Supported only for optimistic transactions.
+ *
+ * @param tx Transaction to suspend.
+ * @throws IgniteCheckedException If suspension failed.
+ */
+ public void suspendTx(GridNearTxLocal tx) throws IgniteCheckedException {
+ tx.txState().awaitLastFut(this);
+
+ tx.suspend();
+ }
+
+ /**
+ * Resume transaction if it was previously suspended.
+ *
+ * @param tx Transaction to resume.
+ * @throws IgniteCheckedException If resume failed.
+ */
+ public void resumeTx(GridNearTxLocal tx) throws IgniteCheckedException {
+ tx.txState().awaitLastFut(this);
+
+ tx.resume();
+ }
+
+ /**
* @return Store session listeners.
*/
@Nullable public Collection<CacheStoreSessionListener> storeSessionListeners() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index 81e5ca8..2fb0ff3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -105,12 +105,14 @@ import static org.apache.ignite.internal.processors.cache.GridCacheOperation.TRA
import static org.apache.ignite.internal.processors.cache.GridCacheOperation.UPDATE;
import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry.SER_READ_EMPTY_ENTRY_VER;
import static org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry.SER_READ_NOT_EMPTY_VER;
+import static org.apache.ignite.transactions.TransactionState.ACTIVE;
import static org.apache.ignite.transactions.TransactionState.COMMITTED;
import static org.apache.ignite.transactions.TransactionState.COMMITTING;
import static org.apache.ignite.transactions.TransactionState.PREPARED;
import static org.apache.ignite.transactions.TransactionState.PREPARING;
import static org.apache.ignite.transactions.TransactionState.ROLLED_BACK;
import static org.apache.ignite.transactions.TransactionState.ROLLING_BACK;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
import static org.apache.ignite.transactions.TransactionState.UNKNOWN;
/**
@@ -2851,6 +2853,47 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements AutoClosea
}
/**
+ * Suspends transaction. It could be resumed later. Supported only for optimistic transactions.
+ *
+ * @throws IgniteCheckedException If the transaction is in an incorrect state, or timed out.
+ */
+ public void suspend() throws IgniteCheckedException {
+ if (log.isDebugEnabled())
+ log.debug("Suspend near local tx: " + this);
+
+ if (pessimistic())
+ throw new UnsupportedOperationException("Suspension is not supported for pessimistic transactions.");
+
+ if (threadId() != Thread.currentThread().getId())
+ throw new IgniteCheckedException("Only thread started transaction can suspend it.");
+
+ synchronized (this) {
+ checkValid();
+
+ cctx.tm().suspendTx(this);
+ }
+ }
+
+ /**
+ * Resumes transaction (possibly in another thread) if it was previously suspended.
+ *
+ * @throws IgniteCheckedException If the transaction is in an incorrect state, or timed out.
+ */
+ public void resume() throws IgniteCheckedException {
+ if (log.isDebugEnabled())
+ log.debug("Resume near local tx: " + this);
+
+ if (pessimistic())
+ throw new UnsupportedOperationException("Resume is not supported for pessimistic transactions.");
+
+ synchronized (this) {
+ checkValid();
+
+ cctx.tm().resumeTx(this);
+ }
+ }
+
+ /**
* @param maps Mappings.
*/
void addEntryMapping(@Nullable Collection<GridDistributedTxMapping> maps) {
@@ -3952,6 +3995,14 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements AutoClosea
}
/**
+ * @param threadId new owner of transaction.
+ * @throws IgniteCheckedException if method executed not in the middle of resume or suspend.
+ */
+ public void threadId(long threadId) {
+ this.threadId = threadId;
+ }
+
+ /**
* Post-lock closure.
*
* @param <T> Return type.
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
index c02e2c7..bb16ad1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
@@ -1358,6 +1358,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
}
/** {@inheritDoc} */
+ @Override public void suspend() throws IgniteException {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
@Override public long timeout() {
return tx.timeout();
}
@@ -1403,6 +1408,11 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
}
/** {@inheritDoc} */
+ @Override public void resume() throws IgniteException {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteAsyncSupport withAsync() {
throw new UnsupportedOperationException();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 91ce3ce..61ca78c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -97,6 +97,7 @@ import static org.apache.ignite.transactions.TransactionState.PREPARED;
import static org.apache.ignite.transactions.TransactionState.PREPARING;
import static org.apache.ignite.transactions.TransactionState.ROLLED_BACK;
import static org.apache.ignite.transactions.TransactionState.ROLLING_BACK;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
/**
* Managed transaction adapter.
@@ -977,10 +978,10 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter implement
switch (state) {
case ACTIVE: {
- valid = false;
+ valid = prev == SUSPENDED;
break;
- } // Active is initial state and cannot be transitioned to.
+ }
case PREPARING: {
valid = prev == ACTIVE;
@@ -1025,15 +1026,20 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter implement
}
case MARKED_ROLLBACK: {
- valid = prev == ACTIVE || prev == PREPARING || prev == PREPARED;
+ valid = prev == ACTIVE || prev == PREPARING || prev == PREPARED || prev == SUSPENDED;
break;
}
case ROLLING_BACK: {
- valid =
- prev == ACTIVE || prev == MARKED_ROLLBACK || prev == PREPARING ||
- prev == PREPARED || (prev == COMMITTING && local() && !dht());
+ valid = prev == ACTIVE || prev == MARKED_ROLLBACK || prev == PREPARING ||
+ prev == PREPARED || prev == SUSPENDED || (prev == COMMITTING && local() && !dht());
+
+ break;
+ }
+
+ case SUSPENDED: {
+ valid = prev == ACTIVE;
break;
}
@@ -1064,7 +1070,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter implement
if (valid) {
// Seal transactions maps.
- if (state != ACTIVE)
+ if (state != ACTIVE && state != SUSPENDED)
seal();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index 7d612ec..a427da3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -113,6 +113,7 @@ import static org.apache.ignite.transactions.TransactionState.COMMITTING;
import static org.apache.ignite.transactions.TransactionState.MARKED_ROLLBACK;
import static org.apache.ignite.transactions.TransactionState.PREPARED;
import static org.apache.ignite.transactions.TransactionState.PREPARING;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
import static org.apache.ignite.transactions.TransactionState.UNKNOWN;
import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
@@ -2240,6 +2241,79 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
}
/**
+ * Suspends transaction.
+ * Should not be used directly. Use tx.suspend() instead.
+ *
+ * @param tx Transaction to be suspended.
+ *
+ * @see #resumeTx(GridNearTxLocal)
+ * @see GridNearTxLocal#suspend()
+ * @see GridNearTxLocal#resume()
+ */
+ public void suspendTx(final GridNearTxLocal tx) throws IgniteCheckedException {
+ assert tx != null && !tx.system() : tx;
+
+ if (!tx.state(SUSPENDED)) {
+ throw new IgniteCheckedException("Trying to suspend transaction with incorrect state "
+ + "[expected=" + ACTIVE + ", actual=" + tx.state() + ']');
+ }
+
+ clearThreadMap(tx);
+
+ transactionMap(tx).remove(tx.xidVersion(), tx);
+ }
+
+ /**
+ * Resume transaction in current thread.
+ * Please don't use directly. Use tx.resume() instead.
+ *
+ * @param tx Transaction to be resumed.
+ *
+ * @see #suspendTx(GridNearTxLocal)
+ * @see GridNearTxLocal#suspend()
+ * @see GridNearTxLocal#resume()
+ */
+ public void resumeTx(GridNearTxLocal tx) throws IgniteCheckedException {
+ assert tx != null && !tx.system() : tx;
+ assert !threadMap.containsValue(tx) : tx;
+ assert !transactionMap(tx).containsValue(tx) : tx;
+ assert !haveSystemTxForThread(Thread.currentThread().getId());
+
+ if(!tx.state(ACTIVE)) {
+ throw new IgniteCheckedException("Trying to resume transaction with incorrect state "
+ + "[expected=" + SUSPENDED + ", actual=" + tx.state() + ']');
+ }
+
+ long threadId = Thread.currentThread().getId();
+
+ if (threadMap.putIfAbsent(threadId, tx) != null)
+ throw new IgniteCheckedException("Thread already start a transaction.");
+
+ if (transactionMap(tx).putIfAbsent(tx.xidVersion(), tx) != null)
+ throw new IgniteCheckedException("Thread already start a transaction.");
+
+ tx.threadId(threadId);
+ }
+
+ /**
+ * @param threadId Thread id.
+ * @return True if thread have system transaction. False otherwise.
+ */
+ private boolean haveSystemTxForThread(long threadId) {
+ if (!sysThreadMap.isEmpty()) {
+ for (GridCacheContext cacheCtx : cctx.cache().context().cacheContexts()) {
+ if (!cacheCtx.systemTx())
+ continue;
+
+ if (sysThreadMap.containsKey(new TxThreadKey(threadId, cacheCtx.cacheId())))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Timeout object for node failure handler.
*/
private final class NodeFailureTimeoutObject extends GridTimeoutObjectAdapter {
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
index 429c995..6b79550 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
@@ -190,4 +190,4 @@ public class IgniteTxMap extends AbstractMap<IgniteTxKey, IgniteTxEntry> impleme
@Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
throw new IllegalStateException("Transaction view map should never be serialized: " + this);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TransactionProxyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TransactionProxyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TransactionProxyImpl.java
index 8750cab..f25fc36 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TransactionProxyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/TransactionProxyImpl.java
@@ -44,6 +44,8 @@ import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionState;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
+
/**
* Cache transaction proxy.
*/
@@ -98,6 +100,18 @@ public class TransactionProxyImpl<K, V> implements TransactionProxy, Externaliza
* Enters a call.
*/
private void enter() {
+ enter(false);
+ }
+
+ /**
+ * Enters a call.
+ *
+ * @param resume Flag to indicate that resume operation in progress.
+ */
+ private void enter(boolean resume) {
+ if (!resume && state() == SUSPENDED)
+ throw new IgniteException("Tx in SUSPENDED state. All operations except resume are prohibited.");
+
if (cctx.deploymentEnabled())
cctx.deploy().onEnter();
@@ -204,6 +218,21 @@ public class TransactionProxyImpl<K, V> implements TransactionProxy, Externaliza
}
/** {@inheritDoc} */
+ @Override public void suspend() throws IgniteException {
+ enter();
+
+ try {
+ cctx.suspendTx(tx);
+ }
+ catch (IgniteCheckedException e) {
+ throw U.convertException(e);
+ }
+ finally {
+ leave();
+ }
+ }
+
+ /** {@inheritDoc} */
@Override public long timeout(long timeout) {
return tx.timeout(timeout);
}
@@ -333,6 +362,21 @@ public class TransactionProxyImpl<K, V> implements TransactionProxy, Externaliza
}
}
+ /** {@inheritDoc} */
+ @Override public void resume() throws IgniteException {
+ enter(true);
+
+ try {
+ cctx.resumeTx(tx);
+ }
+ catch (IgniteCheckedException e) {
+ throw U.convertException(e);
+ }
+ finally {
+ leave();
+ }
+ }
+
/**
* @param res Result to convert to finished future.
*/
@@ -377,4 +421,4 @@ public class TransactionProxyImpl<K, V> implements TransactionProxy, Externaliza
@Override public String toString() {
return S.toString(TransactionProxyImpl.class, this);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
index 57a2b00..a1b4d78 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/Transaction.java
@@ -272,4 +272,18 @@ public interface Transaction extends AutoCloseable, IgniteAsyncSupport {
* @throws IgniteException If rollback failed.
*/
public IgniteFuture<Void> rollbackAsync() throws IgniteException;
+
+ /**
+ * Resume transaction if it was previously suspended. <strong>Supported only for optimistic transactions.</strong>
+ *
+ * @throws IgniteException If resume failed.
+ */
+ public void resume() throws IgniteException;
+
+ /**
+ * Suspends transaction. It could be resumed later. <strong>Supported only for optimistic transactions.</strong>
+ *
+ * @throws IgniteException If suspension failed.
+ */
+ public void suspend() throws IgniteException;
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/main/java/org/apache/ignite/transactions/TransactionState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionState.java b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionState.java
index 1980242..d01c0fa 100644
--- a/modules/core/src/main/java/org/apache/ignite/transactions/TransactionState.java
+++ b/modules/core/src/main/java/org/apache/ignite/transactions/TransactionState.java
@@ -48,7 +48,10 @@ public enum TransactionState {
ROLLED_BACK,
/** Transaction rollback failed or is otherwise unknown state. */
- UNKNOWN;
+ UNKNOWN,
+
+ /** Transaction has been suspended by user. */
+ SUSPENDED;
/** Enumerated values. */
private static final TransactionState[] VALS = values();
@@ -62,4 +65,4 @@ public enum TransactionState {
@Nullable public static TransactionState fromOrdinal(int ord) {
return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeMultiServerTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeMultiServerTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeMultiServerTest.java
new file mode 100644
index 0000000..a6318d4
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeMultiServerTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.cache.distributed;
+
+/**
+ *
+ */
+public class IgniteOptimisticTxSuspendResumeMultiServerTest extends IgniteOptimisticTxSuspendResumeTest {
+ /**
+ * @return Number of server nodes.
+ */
+ protected int serversNumber() {
+ return 4;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
new file mode 100644
index 0000000..d16aebd
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
@@ -0,0 +1,751 @@
+/*
+ * 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.cache.distributed;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.NearCacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.apache.ignite.transactions.TransactionTimeoutException;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.cache.CacheMode.REPLICATED;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
+import static org.apache.ignite.transactions.TransactionState.ACTIVE;
+import static org.apache.ignite.transactions.TransactionState.COMMITTED;
+import static org.apache.ignite.transactions.TransactionState.MARKED_ROLLBACK;
+import static org.apache.ignite.transactions.TransactionState.ROLLED_BACK;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
+
+/**
+ *
+ */
+public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest {
+ /** Transaction timeout. */
+ private static final long TX_TIMEOUT = 100;
+
+ /** Future timeout */
+ private static final int FUT_TIMEOUT = 5000;
+
+ private boolean client = false;
+
+ /**
+ * List of closures to execute transaction operation that prohibited in suspended state.
+ */
+ private static final List<CI1Exc<Transaction>> SUSPENDED_TX_PROHIBITED_OPS = Arrays.asList(
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.suspend();
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.close();
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.commit();
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.commitAsync().get(FUT_TIMEOUT);
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.rollback();
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.rollbackAsync().get(FUT_TIMEOUT);
+ }
+ },
+ new CI1Exc<Transaction>() {
+ @Override public void applyx(Transaction tx) throws Exception {
+ tx.setRollbackOnly();
+ }
+ }
+ );
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setClientMode(client);
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGrids(serversNumber());
+
+ if (serversNumber() > 1) {
+ client = true;
+
+ startGrid(serversNumber());
+
+ startGrid(serversNumber() + 1);
+
+ client = false;
+ }
+
+ awaitPartitionMapExchange();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids(true);
+ }
+
+ /**
+ * @return Number of server nodes.
+ */
+ protected int serversNumber() {
+ return 1;
+ }
+
+ /**
+ * Test for transaction starting in one thread, continuing in another.
+ *
+ * @throws Exception If failed.
+ */
+ public void testResumeTxInAnotherThread() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ final AtomicInteger cntr = new AtomicInteger(0);
+
+ cache.put(-1, -1);
+ cache.put(cntr.get(), cntr.getAndIncrement());
+
+ tx.suspend();
+
+ assertEquals(SUSPENDED, tx.state());
+
+ assertNull("Thread already have tx", ignite.transactions().tx());
+
+ assertNull(cache.get(-1));
+ assertNull(cache.get(cntr.get()));
+
+ for (int i = 0; i < 10; i++) {
+ GridTestUtils.runAsync(new Runnable() {
+ @Override public void run() {
+ assertEquals(SUSPENDED, tx.state());
+
+ tx.resume();
+
+ assertEquals(ACTIVE, tx.state());
+
+ cache.put(cntr.get(), cntr.getAndIncrement());
+
+ tx.suspend();
+ }
+ }).get(FUT_TIMEOUT);
+ }
+
+ tx.resume();
+
+ cache.remove(-1);
+
+ tx.commit();
+
+ assertEquals(COMMITTED, tx.state());
+
+ for (int i = 0; i < cntr.get(); i++)
+ assertEquals(i, (int)cache.get(i));
+
+ assertFalse(cache.containsKey(-1));
+
+ cache.removeAll();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test for transaction starting in one thread, continuing in another, and resuming in initiating thread.
+ * Cache operations performed for a couple of caches.
+ *
+ * @throws Exception If failed.
+ */
+ public void testCrossCacheTxInAnotherThread() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final IgniteCache<Integer, Integer> otherCache =
+ ignite.getOrCreateCache(cacheConfiguration(PARTITIONED, 0, false).setName("otherCache"));
+
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ final AtomicInteger cntr = new AtomicInteger(0);
+
+ cache.put(-1, -1);
+ otherCache.put(-1, -1);
+
+ tx.suspend();
+
+ for (int i = 0; i < 10; i++) {
+ GridTestUtils.runAsync(new Runnable() {
+ @Override public void run() {
+ tx.resume();
+
+ assertEquals(ACTIVE, tx.state());
+
+ cache.put(cntr.get(), cntr.get());
+ otherCache.put(cntr.get(), cntr.getAndIncrement());
+
+ tx.suspend();
+ }
+ }).get(FUT_TIMEOUT);
+ }
+
+ tx.resume();
+
+ cache.remove(-1);
+ otherCache.remove(-1);
+
+ tx.commit();
+
+ assertEquals(COMMITTED, tx.state());
+
+ for (int i = 0; i < cntr.get(); i++) {
+ assertEquals(i, (int)cache.get(i));
+ assertEquals(i, (int)otherCache.get(i));
+ }
+
+ assertFalse(cache.containsKey(-1));
+ assertFalse(otherCache.containsKey(-1));
+
+ cache.removeAll();
+ otherCache.removeAll();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test for transaction rollback.
+ *
+ * @throws Exception If failed.
+ */
+ public void testTxRollback() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ cache.put(1, 1);
+ cache.put(2, 2);
+
+ tx.suspend();
+
+ assertNull("There is no transaction for current thread", ignite.transactions().tx());
+
+ assertEquals(SUSPENDED, tx.state());
+
+ GridTestUtils.runAsync(new Runnable() {
+ @Override public void run() {
+ tx.resume();
+
+ assertEquals(ACTIVE, tx.state());
+
+ cache.put(3, 3);
+
+ tx.rollback();
+ }
+ }).get(FUT_TIMEOUT);
+
+ assertEquals(ROLLED_BACK, tx.state());
+
+ assertFalse(cache.containsKey(1));
+ assertFalse(cache.containsKey(2));
+ assertFalse(cache.containsKey(3));
+
+ cache.removeAll();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test for starting and suspending transactions, and then resuming and committing in another thread.
+ *
+ * @throws Exception If failed.
+ */
+ public void testMultiTxSuspendResume() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final List<Transaction> clientTxs = new ArrayList<>();
+
+ for (int i = 0; i < 10; i++) {
+ Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ cache.put(i, i);
+
+ tx.suspend();
+
+ clientTxs.add(tx);
+ }
+
+ GridTestUtils.runMultiThreaded(new CI1Exc<Integer>() {
+ public void applyx(Integer idx) throws Exception {
+ Transaction tx = clientTxs.get(idx);
+
+ assertEquals(SUSPENDED, tx.state());
+
+ tx.resume();
+
+ assertEquals(ACTIVE, tx.state());
+
+ tx.commit();
+ }
+ }, 10, "th-suspend");
+
+ for (int i = 0; i < 10; i++)
+ assertEquals(i, (int)cache.get(i));
+
+ cache.removeAll();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test checking all operations(exception resume) on suspended transaction from the other thread are prohibited.
+ *
+ * @throws Exception If failed.
+ */
+ public void testOpsProhibitedOnSuspendedTxFromOtherThread() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (final CI1Exc<Transaction> txOperation : SUSPENDED_TX_PROHIBITED_OPS) {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ cache.put(1, 1);
+
+ tx.suspend();
+
+ multithreaded(new RunnableX() {
+ @Override public void runx() throws Exception {
+ GridTestUtils.assertThrowsWithCause(txOperation, tx, IgniteException.class);
+ }
+ }, 1);
+
+ tx.resume();
+ tx.close();
+
+ assertNull(cache.get(1));
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Test checking all operations(exception resume) on suspended transaction are prohibited.
+ *
+ * @throws Exception If failed.
+ */
+ public void testOpsProhibitedOnSuspendedTx() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (CI1Exc<Transaction> txOperation : SUSPENDED_TX_PROHIBITED_OPS) {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ cache.put(1, 1);
+
+ tx.suspend();
+
+ GridTestUtils.assertThrowsWithCause(txOperation, tx, IgniteException.class);
+
+ tx.resume();
+ tx.close();
+
+ assertNull(cache.get(1));
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Test checking timeout on resumed transaction.
+ *
+ * @throws Exception If failed.
+ */
+ public void testTxTimeoutOnResumed() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation, TX_TIMEOUT, 0);
+
+ cache.put(1, 1);
+
+ tx.suspend();
+
+ Thread.sleep(TX_TIMEOUT * 2);
+
+ GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ tx.resume();
+
+ return null;
+ }
+ }, TransactionTimeoutException.class);
+
+ assertEquals(MARKED_ROLLBACK, tx.state());
+
+ tx.close();
+ }
+ }
+ });
+ }
+
+ /**
+ * Test checking timeout on suspended transaction.
+ *
+ * @throws Exception If failed.
+ */
+ public void testTxTimeoutOnSuspend() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation, TX_TIMEOUT, 0);
+
+ cache.put(1, 1);
+
+ Thread.sleep(TX_TIMEOUT * 2);
+
+ GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ tx.suspend();
+
+ return null;
+ }
+ }, TransactionTimeoutException.class);
+
+ assertEquals(MARKED_ROLLBACK, tx.state());
+
+ tx.close();
+
+ assertNull(cache.get(1));
+ }
+ }
+ });
+ }
+
+ /**
+ * Test start 1 transaction, suspendTx it. And then start another transaction, trying to write
+ * the same key and commit it.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSuspendTxAndStartNew() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation tx1Isolation : TransactionIsolation.values()) {
+ for (TransactionIsolation tx2Isolation : TransactionIsolation.values()) {
+ Transaction tx1 = ignite.transactions().txStart(OPTIMISTIC, tx1Isolation);
+
+ cache.put(1, 1);
+
+ tx1.suspend();
+
+ assertFalse(cache.containsKey(1));
+
+ Transaction tx2 = ignite.transactions().txStart(OPTIMISTIC, tx2Isolation);
+
+ cache.put(1, 2);
+
+ tx2.commit();
+
+ assertEquals(2, (int)cache.get(1));
+
+ tx1.resume();
+
+ assertEquals(1, (int)cache.get(1));
+
+ tx1.close();
+
+ cache.removeAll();
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Test start 1 transaction, suspendTx it. And then start another transaction, trying to write
+ * the same key.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSuspendTxAndStartNewWithoutCommit() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation tx1Isolation : TransactionIsolation.values()) {
+ for (TransactionIsolation tx2Isolation : TransactionIsolation.values()) {
+ Transaction tx1 = ignite.transactions().txStart(OPTIMISTIC, tx1Isolation);
+
+ cache.put(1, 1);
+
+ tx1.suspend();
+
+ assertFalse(cache.containsKey(1));
+
+ Transaction tx2 = ignite.transactions().txStart(OPTIMISTIC, tx2Isolation);
+
+ cache.put(1, 2);
+
+ tx2.suspend();
+
+ assertFalse(cache.containsKey(1));
+
+ tx1.resume();
+
+ assertEquals(1, (int)cache.get(1));
+
+ tx1.suspend();
+
+ tx2.resume();
+
+ assertEquals(2, (int)cache.get(1));
+
+ tx2.rollback();
+
+ tx1.resume();
+ tx1.rollback();
+
+ cache.removeAll();
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Test we can resume and complete transaction if topology changed while transaction is suspended.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSuspendTxAndResumeAfterTopologyChange() throws Exception {
+ executeTestForAllCaches(new CI2Exc<Ignite, IgniteCache<Integer, Integer>>() {
+ @Override public void applyx(Ignite ignite, final IgniteCache<Integer, Integer> cache) throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ Transaction tx = ignite.transactions().txStart(OPTIMISTIC, isolation);
+
+ cache.put(1, 1);
+
+ tx.suspend();
+
+ assertEquals(SUSPENDED, tx.state());
+
+ try (IgniteEx g = startGrid(serversNumber() + 3)) {
+ tx.resume();
+
+ assertEquals(ACTIVE, tx.state());
+
+ assertEquals(1, (int)cache.get(1));
+
+ tx.commit();
+
+ assertEquals(1, (int)cache.get(1));
+ }
+
+ cache.removeAll();
+ }
+ }
+ });
+ }
+
+ /**
+ * @return Cache configurations to test.
+ */
+ private List<CacheConfiguration<Integer, Integer>> cacheConfigurations() {
+ List<CacheConfiguration<Integer, Integer>> cfgs = new ArrayList<>();
+
+ cfgs.add(cacheConfiguration(PARTITIONED, 0, false));
+ cfgs.add(cacheConfiguration(PARTITIONED, 1, false));
+ cfgs.add(cacheConfiguration(PARTITIONED, 1, true));
+ cfgs.add(cacheConfiguration(REPLICATED, 0, false));
+
+ return cfgs;
+ }
+
+ /**
+ * @param cacheMode Cache mode.
+ * @param backups Number of backups.
+ * @param nearCache If {@code true} near cache is enabled.
+ * @return Cache configuration.
+ */
+ private CacheConfiguration<Integer, Integer> cacheConfiguration(
+ CacheMode cacheMode,
+ int backups,
+ boolean nearCache) {
+ CacheConfiguration<Integer, Integer> ccfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME);
+
+ ccfg.setCacheMode(cacheMode);
+ ccfg.setAtomicityMode(TRANSACTIONAL);
+ ccfg.setWriteSynchronizationMode(FULL_SYNC);
+
+ if (cacheMode == PARTITIONED)
+ ccfg.setBackups(backups);
+
+ if (nearCache)
+ ccfg.setNearConfiguration(new NearCacheConfiguration<Integer, Integer>());
+
+ return ccfg;
+ }
+
+ /**
+ * @param c Closure.
+ * @throws Exception If failed.
+ */
+ private void executeTestForAllCaches(CI2<Ignite, IgniteCache<Integer, Integer>> c) throws Exception {
+ for (CacheConfiguration<Integer, Integer> ccfg : cacheConfigurations()) {
+ ignite(0).createCache(ccfg);
+
+ log.info("Run test for cache [cache=" + ccfg.getCacheMode() +
+ ", backups=" + ccfg.getBackups() +
+ ", near=" + (ccfg.getNearConfiguration() != null) + "]");
+
+ int srvNum = serversNumber();
+ if (serversNumber() > 1) {
+ ignite(serversNumber() + 1).createNearCache(ccfg.getName(), new NearCacheConfiguration<>());
+ srvNum += 2;
+ }
+
+ try {
+ for (int i = 0; i < srvNum; i++) {
+ Ignite ignite = ignite(i);
+
+ log.info("Run test for node [node=" + i + ", client=" + ignite.configuration().isClientMode() + ']');
+
+ c.apply(ignite, ignite.<Integer, Integer>cache(ccfg.getName()));
+ }
+ }
+ finally {
+ ignite(0).destroyCache(ccfg.getName());
+ }
+ }
+ }
+
+ /**
+ * Closure with 2 parameters that can throw any exception.
+ *
+ * @param <E1> Type of first closure parameter.
+ * @param <E2> Type of second closure parameter.
+ */
+ public static abstract class CI2Exc<E1, E2> implements CI2<E1, E2> {
+ /**
+ * Closure body.
+ *
+ * @param e1 First closure argument.
+ * @param e2 Second closure argument.
+ * @throws Exception If failed.
+ */
+ public abstract void applyx(E1 e1, E2 e2) throws Exception;
+
+ /** {@inheritdoc} */
+ @Override public void apply(E1 e1, E2 e2) {
+ try {
+ applyx(e1, e2);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Closure that can throw any exception.
+ *
+ * @param <T> Type of closure parameter.
+ */
+ public static abstract class CI1Exc<T> implements CI1<T> {
+ /**
+ * Closure body.
+ *
+ * @param o Closure argument.
+ * @throws Exception If failed.
+ */
+ public abstract void applyx(T o) throws Exception;
+
+ /** {@inheritdoc} */
+ @Override public void apply(T o) {
+ try {
+ applyx(o);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Runnable that can throw any exception.
+ */
+ public static abstract class RunnableX implements Runnable {
+ /**
+ * Closure body.
+ *
+ * @throws Exception If failed.
+ */
+ public abstract void runx() throws Exception;
+
+ /** {@inheritdoc} */
+ @Override public void run() {
+ try {
+ runx();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgnitePessimisticTxSuspendResumeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgnitePessimisticTxSuspendResumeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgnitePessimisticTxSuspendResumeTest.java
new file mode 100644
index 0000000..57a1470
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgnitePessimisticTxSuspendResumeTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.cache.distributed;
+
+import java.util.concurrent.Callable;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteTransactions;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+
+/**
+ *
+ */
+public class IgnitePessimisticTxSuspendResumeTest extends GridCommonAbstractTest {
+ /**
+ * Creates new cache configuration.
+ *
+ * @return CacheConfiguration New cache configuration.
+ */
+ protected CacheConfiguration<Integer, String> getCacheConfiguration() {
+ CacheConfiguration<Integer, String> cacheCfg = defaultCacheConfiguration();
+
+ cacheCfg.setCacheMode(PARTITIONED);
+
+ return cacheCfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setClientMode(false);
+ cfg.setCacheConfiguration(getCacheConfiguration());
+
+ return cfg;
+ }
+
+ /**
+ * Test for suspension on pessimistic transaction.
+ *
+ * @throws Exception If failed.
+ */
+ public void testSuspendPessimisticTx() throws Exception {
+ try (Ignite g = startGrid()) {
+ IgniteCache<Integer, String> cache = jcache();
+
+ IgniteTransactions txs = g.transactions();
+
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ final Transaction tx = txs.txStart(TransactionConcurrency.PESSIMISTIC, isolation);
+
+ cache.put(1, "1");
+
+ GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ tx.suspend();
+
+ return null;
+ }
+ }, UnsupportedOperationException.class);
+
+ tx.close();
+
+ assertNull(cache.get(1));
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
index cbcbaee..585c759 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridTestUtils.java
@@ -426,6 +426,32 @@ public final class GridTestUtils {
}
/**
+ * Checks whether closure throws exception, which is itself of a specified
+ * class, or has a cause of the specified class.
+ *
+ * @param call Closure.
+ * @param p Parameter passed to closure.
+ * @param cls Expected class.
+ * @return Thrown throwable.
+ */
+ public static <P> Throwable assertThrowsWithCause(IgniteInClosure<P> call, P p, Class<? extends Throwable> cls) {
+ assert call != null;
+ assert cls != null;
+
+ try {
+ call.apply(p);
+ }
+ catch (Throwable e) {
+ if (!X.hasCause(e, cls))
+ fail("Exception is neither of a specified class, nor has a cause of the specified class: " + cls, e);
+
+ return e;
+ }
+
+ throw new AssertionError("Exception has not been thrown.");
+ }
+
+ /**
* Throw assertion error with specified error message and initialized cause.
*
* @param msg Error message.
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/testframework/junits/cache/GridAbstractCacheStoreSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/cache/GridAbstractCacheStoreSelfTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/cache/GridAbstractCacheStoreSelfTest.java
index c5673b3..f764212 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/cache/GridAbstractCacheStoreSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/cache/GridAbstractCacheStoreSelfTest.java
@@ -579,6 +579,16 @@ public abstract class GridAbstractCacheStoreSelfTest<T extends CacheStore<Object
}
/** {@inheritDoc} */
+ @Override public void suspend() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void resume() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteFuture<Void> rollbackAsync() throws IgniteException {
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
new file mode 100644
index 0000000..90190d0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite6.java
@@ -0,0 +1,42 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteOptimisticTxSuspendResumeMultiServerTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteOptimisticTxSuspendResumeTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgnitePessimisticTxSuspendResumeTest;
+
+/**
+ * Test suite.
+ */
+public class IgniteCacheTestSuite6 extends TestSuite {
+ /**
+ * @return IgniteCache test suite.
+ * @throws Exception Thrown in case of the failure.
+ */
+ public static TestSuite suite() throws Exception {
+ TestSuite suite = new TestSuite("IgniteCache Test Suite part 6");
+
+ suite.addTestSuite(IgniteOptimisticTxSuspendResumeTest.class);
+ suite.addTestSuite(IgniteOptimisticTxSuspendResumeMultiServerTest.class);
+ suite.addTestSuite(IgnitePessimisticTxSuspendResumeTest.class);
+
+ return suite;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java
----------------------------------------------------------------------
diff --git a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java
index 5047491..dd5f6b7 100644
--- a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java
+++ b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaManager.java
@@ -28,10 +28,11 @@ import org.apache.ignite.cache.jta.CacheTmLookup;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.TransactionConfiguration;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal;
-import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.lifecycle.LifecycleAware;
import org.jetbrains.annotations.Nullable;
+import static org.apache.ignite.transactions.TransactionState.SUSPENDED;
+
/**
* Implementation of {@link CacheJtaManagerAdapter}.
*/
@@ -147,7 +148,7 @@ public class CacheJtaManager extends CacheJtaManagerAdapter {
if (jtaTm != null) {
CacheJtaResource rsrc = this.rsrc.get();
- if (rsrc == null || rsrc.isFinished()) {
+ if (rsrc == null || rsrc.isFinished() || rsrc.cacheTx().state() == SUSPENDED) {
try {
Transaction jtaTx = jtaTm.getTransaction();
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java
----------------------------------------------------------------------
diff --git a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java
index 649f7c4..e29c44b 100644
--- a/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java
+++ b/modules/jta/src/main/java/org/apache/ignite/internal/processors/cache/jta/CacheJtaResource.java
@@ -71,12 +71,21 @@ final class CacheJtaResource implements XAResource, Synchronization {
}
/** {@inheritDoc} */
- @Override public void start(Xid xid, int flags) {
+ @Override public void start(Xid xid, int flags) throws XAException {
if (log.isDebugEnabled())
log.debug("XA resource start(...) [xid=" + xid + ", flags=<" + flags(flags) + ">]");
// Simply save global transaction id.
this.xid = xid;
+
+ if ((flags & TMRESUME) == TMRESUME) {
+ try {
+ cacheTx.resume();
+ }
+ catch (IgniteCheckedException e) {
+ throwException("Failed to resume cache transaction: " + e.getMessage(), e);
+ }
+ }
}
/**
@@ -128,7 +137,7 @@ final class CacheJtaResource implements XAResource, Synchronization {
}
/** {@inheritDoc} */
- @Override public void end(Xid xid, int flags) {
+ @Override public void end(Xid xid, int flags) throws XAException {
assert this.xid.equals(xid);
if (log.isDebugEnabled())
@@ -136,6 +145,14 @@ final class CacheJtaResource implements XAResource, Synchronization {
if ((flags & TMFAIL) > 0)
cacheTx.setRollbackOnly();
+ else if ((flags & TMSUSPEND) == TMSUSPEND) {
+ try {
+ cacheTx.suspend();
+ }
+ catch (IgniteCheckedException e) {
+ throwException("Failed to suspend cache transaction: " + e.getMessage(), e);
+ }
+ }
}
/** {@inheritDoc} */
@@ -297,6 +314,13 @@ final class CacheJtaResource implements XAResource, Synchronization {
return state == COMMITTED || state == ROLLED_BACK;
}
+ /**
+ * @return Internal tx
+ */
+ GridNearTxLocal cacheTx() {
+ return cacheTx;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(CacheJtaResource.class, this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java
new file mode 100644
index 0000000..a181068
--- /dev/null
+++ b/modules/jta/src/test/java/org/apache/ignite/internal/processors/cache/GridJtaTransactionManagerSelfTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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.cache;
+
+import javax.cache.configuration.Factory;
+import javax.transaction.Transaction;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.TransactionConfiguration;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.transactions.TransactionConcurrency;
+import org.apache.ignite.transactions.TransactionIsolation;
+import org.objectweb.jotm.Current;
+import org.objectweb.jotm.Jotm;
+import org.objectweb.transaction.jta.TransactionManager;
+
+import static org.apache.ignite.cache.CacheMode.PARTITIONED;
+import static org.apache.ignite.transactions.TransactionState.ACTIVE;
+
+/**
+ * JTA Tx Manager test.
+ */
+public class GridJtaTransactionManagerSelfTest extends GridCommonAbstractTest {
+ /** Java Open Transaction Manager facade. */
+ private static Jotm jotm;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName).
+ setCacheConfiguration(defaultCacheConfiguration().setCacheMode(PARTITIONED));
+
+ cfg.getTransactionConfiguration().setTxManagerFactory(new Factory<TransactionManager>() {
+ private static final long serialVersionUID = 0L;
+
+ @Override public TransactionManager create() {
+ return jotm.getTransactionManager();
+ }
+ });
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ jotm = new Jotm(true, false);
+
+ Current.setAppServer(false);
+
+ startGrid();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+
+ jotm.stop();
+ }
+
+ /**
+ * Test for switching tx context by JTA Manager.
+ *
+ * @throws Exception If failed.
+ */
+ public void testJtaTxContextSwitch() throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ TransactionConfiguration cfg = grid().context().config().getTransactionConfiguration();
+
+ cfg.setDefaultTxConcurrency(TransactionConcurrency.OPTIMISTIC);
+ cfg.setDefaultTxIsolation(isolation);
+
+ TransactionManager jtaTm = jotm.getTransactionManager();
+
+ IgniteCache<Integer, String> cache = jcache();
+
+ assertNull(grid().transactions().tx());
+
+ jtaTm.begin();
+
+ Transaction tx1 = jtaTm.getTransaction();
+
+ cache.put(1, Integer.toString(1));
+
+ assertNotNull(grid().transactions().tx());
+
+ assertEquals(ACTIVE, grid().transactions().tx().state());
+
+ assertEquals(Integer.toString(1), cache.get(1));
+
+ jtaTm.suspend();
+
+ assertNull(grid().transactions().tx());
+
+ assertNull(cache.get(1));
+
+ jtaTm.begin();
+
+ Transaction tx2 = jtaTm.getTransaction();
+
+ assertNotSame(tx1, tx2);
+
+ cache.put(2, Integer.toString(2));
+
+ assertNotNull(grid().transactions().tx());
+
+ assertEquals(ACTIVE, grid().transactions().tx().state());
+
+ assertEquals(Integer.toString(2), cache.get(2));
+
+ jtaTm.commit();
+
+ assertNull(grid().transactions().tx());
+
+ assertEquals(Integer.toString(2), cache.get(2));
+
+ jtaTm.resume(tx1);
+
+ assertNotNull(grid().transactions().tx());
+
+ assertEquals(ACTIVE, grid().transactions().tx().state());
+
+ cache.put(3, Integer.toString(3));
+
+ jtaTm.commit();
+
+ assertEquals("1", cache.get(1));
+ assertEquals("2", cache.get(2));
+ assertEquals("3", cache.get(3));
+
+ assertNull(grid().transactions().tx());
+
+ cache.removeAll();
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testJtaTxContextSwitchWithExistingTx() throws Exception {
+ for (TransactionIsolation isolation : TransactionIsolation.values()) {
+ TransactionConfiguration cfg = grid().context().config().getTransactionConfiguration();
+
+ cfg.setDefaultTxConcurrency(TransactionConcurrency.OPTIMISTIC);
+ cfg.setDefaultTxIsolation(isolation);
+
+ TransactionManager jtaTm = jotm.getTransactionManager();
+
+ IgniteCache<Integer, String> cache = jcache();
+
+ jtaTm.begin();
+
+ Transaction tx1 = jtaTm.getTransaction();
+
+ cache.put(1, Integer.toString(1));
+
+ assertNotNull(grid().transactions().tx());
+
+ assertEquals(ACTIVE, grid().transactions().tx().state());
+
+ assertEquals(Integer.toString(1), cache.get(1));
+
+ jtaTm.suspend();
+
+ jtaTm.begin();
+
+ Transaction tx2 = jtaTm.getTransaction();
+
+ assertNotSame(tx1, tx2);
+
+ cache.put(2, Integer.toString(2));
+
+ try {
+ jtaTm.resume(tx1);
+
+ fail("jtaTm.resume shouldn't success.");
+ }
+ catch (IllegalStateException ignored) {
+ // No-op.
+ }
+ finally {
+ jtaTm.rollback(); //rolling back tx2
+ }
+
+ jtaTm.resume(tx1);
+ jtaTm.rollback();
+
+ cache.removeAll();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e255a564/modules/jta/src/test/java/org/apache/ignite/testsuites/IgniteJtaTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/jta/src/test/java/org/apache/ignite/testsuites/IgniteJtaTestSuite.java b/modules/jta/src/test/java/org/apache/ignite/testsuites/IgniteJtaTestSuite.java
index 4ae5df0..0775c1a 100644
--- a/modules/jta/src/test/java/org/apache/ignite/testsuites/IgniteJtaTestSuite.java
+++ b/modules/jta/src/test/java/org/apache/ignite/testsuites/IgniteJtaTestSuite.java
@@ -21,13 +21,14 @@ import junit.framework.TestSuite;
import org.apache.ignite.internal.processors.cache.CacheJndiTmFactorySelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheJtaConfigurationValidationSelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheJtaFactoryConfigValidationSelfTest;
+import org.apache.ignite.internal.processors.cache.GridJtaLifecycleAwareSelfTest;
+import org.apache.ignite.internal.processors.cache.GridJtaTransactionManagerSelfTest;
import org.apache.ignite.internal.processors.cache.GridPartitionedCacheJtaFactorySelfTest;
import org.apache.ignite.internal.processors.cache.GridPartitionedCacheJtaFactoryUseSyncSelfTest;
import org.apache.ignite.internal.processors.cache.GridPartitionedCacheJtaLookupClassNameSelfTest;
import org.apache.ignite.internal.processors.cache.GridReplicatedCacheJtaFactorySelfTest;
import org.apache.ignite.internal.processors.cache.GridReplicatedCacheJtaFactoryUseSyncSelfTest;
import org.apache.ignite.internal.processors.cache.GridReplicatedCacheJtaLookupClassNameSelfTest;
-import org.apache.ignite.internal.processors.cache.GridJtaLifecycleAwareSelfTest;
import org.apache.ignite.testframework.IgniteTestSuite;
/**
@@ -54,6 +55,8 @@ public class IgniteJtaTestSuite extends TestSuite {
suite.addTestSuite(GridCacheJtaConfigurationValidationSelfTest.class);
suite.addTestSuite(GridCacheJtaFactoryConfigValidationSelfTest.class);
+ suite.addTestSuite(GridJtaTransactionManagerSelfTest.class);
+
// Factory
suite.addTestSuite(CacheJndiTmFactorySelfTest.class);
[10/29] ignite git commit: IGNITE-5211: Added new constructor:
QueryEntity(Class keyCls,
Class valCls). This closes #2371. This closes #2388. This closes #2407.
Posted by nt...@apache.org.
IGNITE-5211: Added new constructor: QueryEntity(Class keyCls, Class valCls). This closes #2371. This closes #2388. This closes #2407.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b093afb8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b093afb8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b093afb8
Branch: refs/heads/ignite-5947
Commit: b093afb8231135a4904f5fffd62f5b4c332f1d47
Parents: 4f02504
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Aug 8 12:05:36 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 12:14:07 2017 +0300
----------------------------------------------------------------------
.../org/apache/ignite/cache/QueryEntity.java | 229 +++++++
.../configuration/CacheConfiguration.java | 620 +------------------
.../cache/query/QueryEntityClassProperty.java | 116 ++++
.../cache/query/QueryEntityIndexDescriptor.java | 121 ++++
.../cache/query/QueryEntityTypeDescriptor.java | 219 +++++++
.../h2/sql/AbstractH2CompareQueryTest.java | 4 +-
6 files changed, 693 insertions(+), 616 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 955e7d2..5180100 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -18,7 +18,9 @@
package org.apache.ignite.cache;
import java.io.Serializable;
+import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -27,10 +29,20 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityClassProperty;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityTypeDescriptor;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.processors.query.QueryUtils;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
/**
* Query entity is a description of {@link org.apache.ignite.IgniteCache cache} entry (composed of key and value)
@@ -111,6 +123,16 @@ public class QueryEntity implements Serializable {
}
/**
+ * Creates a query entity with the given key and value types.
+ *
+ * @param keyCls Key type.
+ * @param valCls Value type.
+ */
+ public QueryEntity(Class<?> keyCls, Class<?> valCls) {
+ this(convert(processKeyAndValueClasses(keyCls,valCls)));
+ }
+
+ /**
* Gets key type for this query pair.
*
* @return Key type.
@@ -351,6 +373,213 @@ public class QueryEntity implements Serializable {
return this;
}
+ /**
+ * @param desc Type descriptor.
+ * @return Type metadata.
+ */
+ private static QueryEntity convert(QueryEntityTypeDescriptor desc) {
+ QueryEntity entity = new QueryEntity();
+
+ // Key and val types.
+ entity.setKeyType(desc.keyClass().getName());
+ entity.setValueType(desc.valueClass().getName());
+
+ for (QueryEntityClassProperty prop : desc.properties().values())
+ entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
+
+ entity.setKeyFields(desc.keyProperties());
+
+ QueryIndex txtIdx = null;
+
+ Collection<QueryIndex> idxs = new ArrayList<>();
+
+ for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
+ GridQueryIndexDescriptor idx = idxEntry.getValue();
+
+ if (idx.type() == QueryIndexType.FULLTEXT) {
+ assert txtIdx == null;
+
+ txtIdx = new QueryIndex();
+
+ txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+ txtIdx.setFieldNames(idx.fields(), true);
+ txtIdx.setName(idxEntry.getKey());
+ }
+ else {
+ QueryIndex sortedIdx = new QueryIndex();
+
+ sortedIdx.setIndexType(idx.type());
+
+ LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
+
+ for (String f : idx.fields())
+ fields.put(f, !idx.descending(f));
+
+ sortedIdx.setFields(fields);
+
+ sortedIdx.setName(idxEntry.getKey());
+
+ idxs.add(sortedIdx);
+ }
+ }
+
+ if (desc.valueTextIndex()) {
+ if (txtIdx == null) {
+ txtIdx = new QueryIndex();
+
+ txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+ txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
+ }
+ else
+ txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
+ }
+
+ if (txtIdx != null)
+ idxs.add(txtIdx);
+
+ if (!F.isEmpty(idxs))
+ entity.setIndexes(idxs);
+
+ return entity;
+ }
+
+ /**
+ * @param keyCls Key class.
+ * @param valCls Value class.
+ * @return Type descriptor.
+ */
+ private static QueryEntityTypeDescriptor processKeyAndValueClasses(
+ Class<?> keyCls,
+ Class<?> valCls
+ ) {
+ QueryEntityTypeDescriptor d = new QueryEntityTypeDescriptor();
+
+ d.keyClass(keyCls);
+ d.valueClass(valCls);
+
+ processAnnotationsInClass(true, d.keyClass(), d, null);
+ processAnnotationsInClass(false, d.valueClass(), d, null);
+
+ return d;
+ }
+
+ /**
+ * Process annotations for class.
+ *
+ * @param key If given class relates to key.
+ * @param cls Class.
+ * @param type Type descriptor.
+ * @param parent Parent in case of embeddable.
+ */
+ private static void processAnnotationsInClass(boolean key, Class<?> cls, QueryEntityTypeDescriptor type,
+ @Nullable QueryEntityClassProperty parent) {
+ if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
+ if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
+ String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
+
+ type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
+ QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+ type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
+ }
+
+ return;
+ }
+
+ if (parent != null && parent.knowsClass(cls))
+ throw new CacheException("Recursive reference found in type: " + cls.getName());
+
+ if (parent == null) { // Check class annotation at top level only.
+ QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
+
+ if (txtAnnCls != null)
+ type.valueTextIndex(true);
+
+ QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
+
+ if (grpIdx != null)
+ type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
+
+ QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
+
+ if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
+ for (QueryGroupIndex idx : grpIdxList.value())
+ type.addIndex(idx.name(), QueryIndexType.SORTED);
+ }
+ }
+
+ for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
+ for (Field field : c.getDeclaredFields()) {
+ QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
+ QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
+
+ if (sqlAnn != null || txtAnn != null) {
+ QueryEntityClassProperty prop = new QueryEntityClassProperty(field);
+
+ prop.parent(parent);
+
+ // Add parent property before its possible nested properties so that
+ // resulting parent column comes before columns corresponding to those
+ // nested properties in the resulting table - that way nested
+ // properties override will happen properly (first parent, then children).
+ type.addProperty(prop, key, true);
+
+ processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
+ }
+ }
+ }
+ }
+
+ /**
+ * Processes annotation at field or method.
+ *
+ * @param key If given class relates to key.
+ * @param sqlAnn SQL annotation, can be {@code null}.
+ * @param txtAnn H2 text annotation, can be {@code null}.
+ * @param cls Entity class.
+ * @param curCls Current entity class.
+ * @param fldCls Class of field or return type for method.
+ * @param prop Current property.
+ * @param desc Class description.
+ */
+ private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
+ Class<?> cls, Class<?> curCls, Class<?> fldCls, QueryEntityClassProperty prop, QueryEntityTypeDescriptor desc) {
+ if (sqlAnn != null) {
+ processAnnotationsInClass(key, fldCls, desc, prop);
+
+ if (!sqlAnn.name().isEmpty())
+ prop.alias(sqlAnn.name());
+
+ if (sqlAnn.index()) {
+ String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
+
+ if (cls != curCls)
+ idxName = cls.getSimpleName() + "_" + idxName;
+
+ desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
+ QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+ desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
+ }
+
+ if (!F.isEmpty(sqlAnn.groups())) {
+ for (String group : sqlAnn.groups())
+ desc.addFieldToIndex(group, prop.fullName(), 0, false);
+ }
+
+ if (!F.isEmpty(sqlAnn.orderedGroups())) {
+ for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
+ desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
+ }
+ }
+
+ if (txtAnn != null)
+ desc.addFieldToTextIndex(prop.fullName());
+ }
+
+
/** {@inheritDoc} */
@Override public boolean equals(Object o) {
if (this == o)
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 670046f..2b4ec1d 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -18,21 +18,10 @@
package org.apache.ignite.configuration;
import java.io.Serializable;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.configuration.CacheEntryListenerConfiguration;
@@ -53,26 +42,17 @@ import org.apache.ignite.cache.CacheRebalanceMode;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cache.PartitionLossPolicy;
import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.cache.affinity.AffinityFunction;
import org.apache.ignite.cache.affinity.AffinityKeyMapper;
import org.apache.ignite.cache.eviction.EvictionFilter;
import org.apache.ignite.cache.eviction.EvictionPolicy;
-import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
import org.apache.ignite.cache.store.CacheStore;
import org.apache.ignite.cache.store.CacheStoreSessionListener;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.binary.BinaryContext;
-import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.processors.query.QueryUtils;
-import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.A;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
@@ -1768,14 +1748,12 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
Class<?> keyCls = newIndexedTypes[i];
Class<?> valCls = newIndexedTypes[i + 1];
- TypeDescriptor desc = processKeyAndValueClasses(keyCls, valCls);
-
- QueryEntity converted = convert(desc);
+ QueryEntity newEntity = new QueryEntity(keyCls, valCls);
boolean dup = false;
for (QueryEntity entity : qryEntities) {
- if (F.eq(entity.findValueType(), converted.findValueType())) {
+ if (F.eq(entity.findValueType(), newEntity.findValueType())) {
dup = true;
break;
@@ -1783,13 +1761,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
}
if (!dup)
- qryEntities.add(converted);
+ qryEntities.add(newEntity);
// Set key configuration if needed.
- String affFieldName = desc.affinityFieldName();
+ String affFieldName = BinaryContext.affinityFieldName(keyCls);
if (affFieldName != null) {
- CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(converted.getKeyType(), affFieldName);
+ CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(newEntity.getKeyType(), affFieldName);
if (F.isEmpty(keyCfg))
keyCfg = new CacheKeyConfiguration[] { newKeyCfg };
@@ -2041,82 +2019,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
return cfg;
}
- /**
- * @param desc Type descriptor.
- * @return Type metadata.
- */
- private static QueryEntity convert(TypeDescriptor desc) {
- QueryEntity entity = new QueryEntity();
-
- // Key and val types.
- entity.setKeyType(desc.keyClass().getName());
- entity.setValueType(desc.valueClass().getName());
-
- for (ClassProperty prop : desc.props.values())
- entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
-
- entity.setKeyFields(desc.keyProps);
-
- QueryIndex txtIdx = null;
-
- Collection<QueryIndex> idxs = new ArrayList<>();
-
- for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
- GridQueryIndexDescriptor idx = idxEntry.getValue();
-
- if (idx.type() == QueryIndexType.FULLTEXT) {
- assert txtIdx == null;
-
- txtIdx = new QueryIndex();
-
- txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
- txtIdx.setFieldNames(idx.fields(), true);
- txtIdx.setName(idxEntry.getKey());
- }
- else {
- Collection<String> grp = new ArrayList<>();
-
- for (String fieldName : idx.fields())
- grp.add(idx.descending(fieldName) ? fieldName + " desc" : fieldName);
-
- QueryIndex sortedIdx = new QueryIndex();
-
- sortedIdx.setIndexType(idx.type());
-
- LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
-
- for (String f : idx.fields())
- fields.put(f, !idx.descending(f));
-
- sortedIdx.setFields(fields);
-
- sortedIdx.setName(idxEntry.getKey());
-
- idxs.add(sortedIdx);
- }
- }
-
- if (desc.valueTextIndex()) {
- if (txtIdx == null) {
- txtIdx = new QueryIndex();
-
- txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
- txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
- }
- else
- txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
- }
-
- if (txtIdx != null)
- idxs.add(txtIdx);
-
- if (!F.isEmpty(idxs))
- entity.setIndexes(idxs);
-
- return entity;
- }
/**
* @param cls Class.
@@ -2128,141 +2030,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
return QueryUtils.isSqlType(cls) ? cls : Object.class;
}
- /**
- * @param keyCls Key class.
- * @param valCls Value class.
- * @return Type descriptor.
- */
- static TypeDescriptor processKeyAndValueClasses(
- Class<?> keyCls,
- Class<?> valCls
- ) {
- TypeDescriptor d = new TypeDescriptor();
-
- d.keyClass(keyCls);
- d.valueClass(valCls);
-
- d.affinityFieldName(BinaryContext.affinityFieldName(keyCls));
-
- processAnnotationsInClass(true, d.keyCls, d, null);
- processAnnotationsInClass(false, d.valCls, d, null);
-
- return d;
- }
-
- /**
- * Process annotations for class.
- *
- * @param key If given class relates to key.
- * @param cls Class.
- * @param type Type descriptor.
- * @param parent Parent in case of embeddable.
- */
- private static void processAnnotationsInClass(boolean key, Class<?> cls, TypeDescriptor type,
- @Nullable ClassProperty parent) {
- if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
- if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
- String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
-
- type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
- QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
- type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
- }
-
- return;
- }
-
- if (parent != null && parent.knowsClass(cls))
- throw new CacheException("Recursive reference found in type: " + cls.getName());
-
- if (parent == null) { // Check class annotation at top level only.
- QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
-
- if (txtAnnCls != null)
- type.valueTextIndex(true);
-
- QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
-
- if (grpIdx != null)
- type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
-
- QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
-
- if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
- for (QueryGroupIndex idx : grpIdxList.value())
- type.addIndex(idx.name(), QueryIndexType.SORTED);
- }
- }
-
- for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
- for (Field field : c.getDeclaredFields()) {
- QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
- QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
-
- if (sqlAnn != null || txtAnn != null) {
- ClassProperty prop = new ClassProperty(field);
-
- prop.parent(parent);
-
- // Add parent property before its possible nested properties so that
- // resulting parent column comes before columns corresponding to those
- // nested properties in the resulting table - that way nested
- // properties override will happen properly (first parent, then children).
- type.addProperty(prop, key, true);
-
- processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
- }
- }
- }
- }
-
- /**
- * Processes annotation at field or method.
- *
- * @param key If given class relates to key.
- * @param sqlAnn SQL annotation, can be {@code null}.
- * @param txtAnn H2 text annotation, can be {@code null}.
- * @param cls Entity class.
- * @param curCls Current entity class.
- * @param fldCls Class of field or return type for method.
- * @param prop Current property.
- * @param desc Class description.
- */
- private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
- Class<?> cls, Class<?> curCls, Class<?> fldCls, ClassProperty prop, TypeDescriptor desc) {
- if (sqlAnn != null) {
- processAnnotationsInClass(key, fldCls, desc, prop);
-
- if (!sqlAnn.name().isEmpty())
- prop.alias(sqlAnn.name());
-
- if (sqlAnn.index()) {
- String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
-
- if (cls != curCls)
- idxName = cls.getSimpleName() + "_" + idxName;
-
- desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
- QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
- desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
- }
-
- if (!F.isEmpty(sqlAnn.groups())) {
- for (String group : sqlAnn.groups())
- desc.addFieldToIndex(group, prop.fullName(), 0, false);
- }
-
- if (!F.isEmpty(sqlAnn.orderedGroups())) {
- for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
- desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
- }
- }
-
- if (txtAnn != null)
- desc.addFieldToTextIndex(prop.fullName());
- }
/** {@inheritDoc} */
@Override public CacheConfiguration<K, V> setStatisticsEnabled(boolean enabled) {
@@ -2375,381 +2142,4 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
return "IgniteAllNodesPredicate []";
}
}
-
- /**
- * Descriptor of type.
- */
- private static class TypeDescriptor {
- /** Value field names and types with preserved order. */
- @GridToStringInclude
- private final Map<String, Class<?>> fields = new LinkedHashMap<>();
-
- /** */
- @GridToStringExclude
- private final Map<String, ClassProperty> props = new LinkedHashMap<>();
-
- /** */
- @GridToStringInclude
- private final Set<String> keyProps = new HashSet<>();
-
- /** */
- @GridToStringInclude
- private final Map<String, IndexDescriptor> indexes = new HashMap<>();
-
- /** */
- private IndexDescriptor fullTextIdx;
-
- /** */
- private Class<?> keyCls;
-
- /** */
- private Class<?> valCls;
-
- /** */
- private boolean valTextIdx;
-
- /** Affinity field name. */
- private String affFieldName;
-
- /**
- * @return Indexes.
- */
- public Map<String, GridQueryIndexDescriptor> indexes() {
- return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
- }
-
- /**
- * Adds index.
- *
- * @param idxName Index name.
- * @param type Index type.
- * @param inlineSize Inline size.
- * @return Index descriptor.
- */
- public IndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
- IndexDescriptor idx = new IndexDescriptor(type, inlineSize);
-
- if (indexes.put(idxName, idx) != null)
- throw new CacheException("Index with name '" + idxName + "' already exists.");
-
- return idx;
- }
-
- /**
- * Adds index.
- *
- * @param idxName Index name.
- * @param type Index type.
- * @return Index descriptor.
- */
- public IndexDescriptor addIndex(String idxName, QueryIndexType type) {
- return addIndex(idxName, type, -1);
- }
-
- /**
- * Adds field to index.
- *
- * @param idxName Index name.
- * @param field Field name.
- * @param orderNum Fields order number in index.
- * @param descending Sorting order.
- */
- public void addFieldToIndex(String idxName, String field, int orderNum,
- boolean descending) {
- IndexDescriptor desc = indexes.get(idxName);
-
- if (desc == null)
- desc = addIndex(idxName, QueryIndexType.SORTED);
-
- desc.addField(field, orderNum, descending);
- }
-
- /**
- * Adds field to text index.
- *
- * @param field Field name.
- */
- public void addFieldToTextIndex(String field) {
- if (fullTextIdx == null) {
- fullTextIdx = new IndexDescriptor(QueryIndexType.FULLTEXT);
-
- indexes.put(null, fullTextIdx);
- }
-
- fullTextIdx.addField(field, 0, false);
- }
-
- /**
- * @return Value class.
- */
- public Class<?> valueClass() {
- return valCls;
- }
-
- /**
- * Sets value class.
- *
- * @param valCls Value class.
- */
- void valueClass(Class<?> valCls) {
- this.valCls = valCls;
- }
-
- /**
- * @return Key class.
- */
- public Class<?> keyClass() {
- return keyCls;
- }
-
- /**
- * Set key class.
- *
- * @param keyCls Key class.
- */
- void keyClass(Class<?> keyCls) {
- this.keyCls = keyCls;
- }
-
- /**
- * @return Affinity field name.
- */
- @Nullable public String affinityFieldName() {
- return affFieldName;
- }
-
- /**
- * @param affFieldName Affinity field name.
- */
- private void affinityFieldName(@Nullable String affFieldName) {
- this.affFieldName = affFieldName;
- }
-
- /**
- * Adds property to the type descriptor.
- *
- * @param prop Property.
- * @param key Property ownership flag (key or not).
- * @param failOnDuplicate Fail on duplicate flag.
- */
- void addProperty(ClassProperty prop, boolean key, boolean failOnDuplicate) {
- String name = prop.fullName();
-
- if (props.put(name, prop) != null && failOnDuplicate)
- throw new CacheException("Property with name '" + name + "' already exists.");
-
- fields.put(name, prop.type());
-
- if (key)
- keyProps.add(name);
- }
-
- /**
- * @return {@code true} If we need to have a fulltext index on value.
- */
- public boolean valueTextIndex() {
- return valTextIdx;
- }
-
- /**
- * Sets if this value should be text indexed.
- *
- * @param valTextIdx Flag value.
- */
- public void valueTextIndex(boolean valTextIdx) {
- this.valTextIdx = valTextIdx;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(TypeDescriptor.class, this);
- }
- }
-
- /**
- * Index descriptor.
- */
- private static class IndexDescriptor implements GridQueryIndexDescriptor {
- /** Fields sorted by order number. */
- private final Collection<T2<String, Integer>> fields = new TreeSet<>(
- new Comparator<T2<String, Integer>>() {
- @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
- if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
- return o1.get1().compareTo(o2.get1());
-
- return o1.get2() < o2.get2() ? -1 : 1;
- }
- });
-
- /** Fields which should be indexed in descending order. */
- private Collection<String> descendings;
-
- /** */
- private final QueryIndexType type;
-
- /** */
- private final int inlineSize;
-
- /**
- * @param type Type.
- * @param inlineSize Inline size.
- */
- private IndexDescriptor(QueryIndexType type, int inlineSize) {
- assert type != null;
-
- this.type = type;
- this.inlineSize = inlineSize;
- }
-
- /**
- * @param type Type.
- */
- private IndexDescriptor(QueryIndexType type) {
- this(type, -1);
- }
-
- /** {@inheritDoc} */
- @Override public String name() {
- return null;
- }
-
- /** {@inheritDoc} */
- @Override public Collection<String> fields() {
- Collection<String> res = new ArrayList<>(fields.size());
-
- for (T2<String, Integer> t : fields)
- res.add(t.get1());
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public boolean descending(String field) {
- return descendings != null && descendings.contains(field);
- }
-
- /**
- * Adds field to this index.
- *
- * @param field Field name.
- * @param orderNum Field order number in this index.
- * @param descending Sort order.
- */
- public void addField(String field, int orderNum, boolean descending) {
- fields.add(new T2<>(field, orderNum));
-
- if (descending) {
- if (descendings == null)
- descendings = new HashSet<>();
-
- descendings.add(field);
- }
- }
-
- /** {@inheritDoc} */
- @Override public QueryIndexType type() {
- return type;
- }
-
- /** {@inheritDoc} */
- @Override public int inlineSize() {
- return inlineSize;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(IndexDescriptor.class, this);
- }
- }
-
- /**
- * Description of type property.
- */
- private static class ClassProperty {
- /** */
- private final Member member;
-
- /** */
- private ClassProperty parent;
-
- /** */
- private String name;
-
- /** */
- private String alias;
-
- /**
- * Constructor.
- *
- * @param member Element.
- */
- ClassProperty(Member member) {
- this.member = member;
-
- name = member.getName();
-
- if (member instanceof Method) {
- if (member.getName().startsWith("get") && member.getName().length() > 3)
- name = member.getName().substring(3);
-
- if (member.getName().startsWith("is") && member.getName().length() > 2)
- name = member.getName().substring(2);
- }
-
- ((AccessibleObject)member).setAccessible(true);
- }
-
- /**
- * @param alias Alias.
- */
- public void alias(String alias) {
- this.alias = alias;
- }
-
- /**
- * @return Alias.
- */
- String alias() {
- return F.isEmpty(alias) ? name : alias;
- }
-
- /**
- * @return Type.
- */
- public Class<?> type() {
- return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
- }
-
- /**
- * @param parent Parent property if this is embeddable element.
- */
- public void parent(ClassProperty parent) {
- this.parent = parent;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(ClassProperty.class, this);
- }
-
- /**
- * @param cls Class.
- * @return {@code true} If this property or some parent relates to member of the given class.
- */
- public boolean knowsClass(Class<?> cls) {
- return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
- }
-
- /**
- * @return Full name with all parents in dot notation.
- */
- public String fullName() {
- assert name != null;
-
- if (parent == null)
- return name;
-
- return parent.fullName() + '.' + name;
- }
- }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
new file mode 100644
index 0000000..e21b73c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
@@ -0,0 +1,116 @@
+/*
+ * 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.cache.query;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Description of type property.
+ */
+public class QueryEntityClassProperty {
+ /** */
+ private final Member member;
+
+ /** */
+ private QueryEntityClassProperty parent;
+
+ /** */
+ private String name;
+
+ /** */
+ private String alias;
+
+ /**
+ * Constructor.
+ *
+ * @param member Element.
+ */
+ public QueryEntityClassProperty(Member member) {
+ this.member = member;
+
+ name = member.getName();
+
+ if (member instanceof Method) {
+ if (member.getName().startsWith("get") && member.getName().length() > 3)
+ name = member.getName().substring(3);
+
+ if (member.getName().startsWith("is") && member.getName().length() > 2)
+ name = member.getName().substring(2);
+ }
+
+ ((AccessibleObject)member).setAccessible(true);
+ }
+
+ /**
+ * @param alias Alias.
+ */
+ public void alias(String alias) {
+ this.alias = alias;
+ }
+
+ /**
+ * @return Alias.
+ */
+ public String alias() {
+ return F.isEmpty(alias) ? name : alias;
+ }
+
+ /**
+ * @return Type.
+ */
+ public Class<?> type() {
+ return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
+ }
+
+ /**
+ * @param parent Parent property if this is embeddable element.
+ */
+ public void parent(QueryEntityClassProperty parent) {
+ this.parent = parent;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryEntityClassProperty.class, this);
+ }
+
+ /**
+ * @param cls Class.
+ * @return {@code true} If this property or some parent relates to member of the given class.
+ */
+ public boolean knowsClass(Class<?> cls) {
+ return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
+ }
+
+ /**
+ * @return Full name with all parents in dot notation.
+ */
+ public String fullName() {
+ assert name != null;
+
+ if (parent == null)
+ return name;
+
+ return parent.fullName() + '.' + name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
new file mode 100644
index 0000000..2fb5837
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
@@ -0,0 +1,121 @@
+/*
+ * 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.cache.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.TreeSet;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Index descriptor.
+ */
+public class QueryEntityIndexDescriptor implements GridQueryIndexDescriptor {
+ /** Fields sorted by order number. */
+ private final Collection<T2<String, Integer>> fields = new TreeSet<>(
+ new Comparator<T2<String, Integer>>() {
+ @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
+ if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
+ return o1.get1().compareTo(o2.get1());
+
+ return o1.get2() < o2.get2() ? -1 : 1;
+ }
+ });
+ /** */
+ private final QueryIndexType type;
+ /** */
+ private final int inlineSize;
+ /** Fields which should be indexed in descending order. */
+ private Collection<String> descendings;
+
+ /**
+ * @param type Type.
+ * @param inlineSize Inline size.
+ */
+ QueryEntityIndexDescriptor(QueryIndexType type, int inlineSize) {
+ assert type != null;
+
+ this.type = type;
+ this.inlineSize = inlineSize;
+ }
+
+ /**
+ * @param type Type.
+ */
+ QueryEntityIndexDescriptor(QueryIndexType type) {
+ this(type, -1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<String> fields() {
+ Collection<String> res = new ArrayList<>(fields.size());
+
+ for (T2<String, Integer> t : fields)
+ res.add(t.get1());
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean descending(String field) {
+ return descendings != null && descendings.contains(field);
+ }
+
+ /**
+ * Adds field to this index.
+ *
+ * @param field Field name.
+ * @param orderNum Field order number in this index.
+ * @param descending Sort order.
+ */
+ public void addField(String field, int orderNum, boolean descending) {
+ fields.add(new T2<>(field, orderNum));
+
+ if (descending) {
+ if (descendings == null)
+ descendings = new HashSet<>();
+
+ descendings.add(field);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public QueryIndexType type() {
+ return type;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int inlineSize() {
+ return inlineSize;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryEntityIndexDescriptor.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
new file mode 100644
index 0000000..47ab263
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
@@ -0,0 +1,219 @@
+/*
+ * 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.cache.query;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Descriptor of type.
+ */
+public class QueryEntityTypeDescriptor {
+ /** Value field names and types with preserved order. */
+ @GridToStringInclude
+ private final Map<String, Class<?>> fields = new LinkedHashMap<>();
+
+ /** */
+ @GridToStringExclude
+ private final Map<String, QueryEntityClassProperty> props = new LinkedHashMap<>();
+
+ /** */
+ @GridToStringInclude
+ private final Set<String> keyProps = new HashSet<>();
+
+ /** */
+ @GridToStringInclude
+ private final Map<String, QueryEntityIndexDescriptor> indexes = new HashMap<>();
+
+ /** */
+ private QueryEntityIndexDescriptor fullTextIdx;
+
+ /** */
+ private Class<?> keyCls;
+
+ /** */
+ private Class<?> valCls;
+
+ /** */
+ private boolean valTextIdx;
+
+ /**
+ * @return Indexes.
+ */
+ public Map<String, GridQueryIndexDescriptor> indexes() {
+ return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
+ }
+
+ /**
+ * Adds index.
+ *
+ * @param idxName Index name.
+ * @param type Index type.
+ * @param inlineSize Inline size.
+ * @return Index descriptor.
+ */
+ public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
+ QueryEntityIndexDescriptor idx = new QueryEntityIndexDescriptor(type, inlineSize);
+
+ if (indexes.put(idxName, idx) != null)
+ throw new CacheException("Index with name '" + idxName + "' already exists.");
+
+ return idx;
+ }
+
+ /**
+ * Adds index.
+ *
+ * @param idxName Index name.
+ * @param type Index type.
+ * @return Index descriptor.
+ */
+ public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type) {
+ return addIndex(idxName, type, -1);
+ }
+
+ /**
+ * Adds field to index.
+ *
+ * @param idxName Index name.
+ * @param field Field name.
+ * @param orderNum Fields order number in index.
+ * @param descending Sorting order.
+ */
+ public void addFieldToIndex(String idxName, String field, int orderNum,
+ boolean descending) {
+ QueryEntityIndexDescriptor desc = indexes.get(idxName);
+
+ if (desc == null)
+ desc = addIndex(idxName, QueryIndexType.SORTED);
+
+ desc.addField(field, orderNum, descending);
+ }
+
+ /**
+ * Adds field to text index.
+ *
+ * @param field Field name.
+ */
+ public void addFieldToTextIndex(String field) {
+ if (fullTextIdx == null) {
+ fullTextIdx = new QueryEntityIndexDescriptor(QueryIndexType.FULLTEXT);
+
+ indexes.put(null, fullTextIdx);
+ }
+
+ fullTextIdx.addField(field, 0, false);
+ }
+
+ /**
+ * @return Value class.
+ */
+ public Class<?> valueClass() {
+ return valCls;
+ }
+
+ /**
+ * Sets value class.
+ *
+ * @param valCls Value class.
+ */
+ public void valueClass(Class<?> valCls) {
+ this.valCls = valCls;
+ }
+
+ /**
+ * @return Key class.
+ */
+ public Class<?> keyClass() {
+ return keyCls;
+ }
+
+ /**
+ * Set key class.
+ *
+ * @param keyCls Key class.
+ */
+ public void keyClass(Class<?> keyCls) {
+ this.keyCls = keyCls;
+ }
+
+ /**
+ * Adds property to the type descriptor.
+ *
+ * @param prop Property.
+ * @param key Property ownership flag (key or not).
+ * @param failOnDuplicate Fail on duplicate flag.
+ */
+ public void addProperty(QueryEntityClassProperty prop, boolean key, boolean failOnDuplicate) {
+ String name = prop.fullName();
+
+ if (props.put(name, prop) != null && failOnDuplicate)
+ throw new CacheException("Property with name '" + name + "' already exists.");
+
+ fields.put(name, prop.type());
+
+ if (key)
+ keyProps.add(name);
+ }
+
+ /**
+ * @return Class properties.
+ */
+ public Map<String, QueryEntityClassProperty> properties() {
+ return props;
+ }
+
+ /**
+ * @return Properties keys.
+ */
+ public Set<String> keyProperties() {
+ return keyProps;
+ }
+
+ /**
+ * @return {@code true} If we need to have a fulltext index on value.
+ */
+ public boolean valueTextIndex() {
+ return valTextIdx;
+ }
+
+ /**
+ * Sets if this value should be text indexed.
+ *
+ * @param valTextIdx Flag value.
+ */
+ public void valueTextIndex(boolean valTextIdx) {
+ this.valTextIdx = valTextIdx;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryEntityTypeDescriptor.class, this);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/b093afb8/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
index 5475311..1ddd252 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
@@ -25,6 +25,7 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -34,6 +35,7 @@ import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
@@ -94,7 +96,7 @@ public abstract class AbstractH2CompareQueryTest extends GridCommonAbstractTest
cc.setCacheMode(mode);
cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
cc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
- cc.setIndexedTypes(clsK, clsV);
+ cc.setQueryEntities(Collections.singleton(new QueryEntity(clsK, clsV)));
return cc;
}
[05/29] ignite git commit: IGNITE-5126: Batch support for this JDBC
driver. This closes #2162.
Posted by nt...@apache.org.
IGNITE-5126: Batch support for this JDBC driver. This closes #2162.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0f22223b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0f22223b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0f22223b
Branch: refs/heads/ignite-5947
Commit: 0f22223b7ca25313083e4dc35e7842931a655abd
Parents: 3fdf453
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Fri Aug 4 11:46:14 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Aug 4 12:04:07 2017 +0300
----------------------------------------------------------------------
.../jdbc/suite/IgniteJdbcDriverTestSuite.java | 2 +
.../ignite/jdbc/thin/JdbcThinBatchSelfTest.java | 333 +++++++++++++++++++
.../jdbc/thin/JdbcThinPreparedStatement.java | 16 +-
.../internal/jdbc/thin/JdbcThinStatement.java | 46 ++-
.../internal/jdbc/thin/JdbcThinTcpIo.java | 20 ++
.../odbc/jdbc/JdbcBatchExecuteRequest.java | 109 ++++++
.../odbc/jdbc/JdbcBatchExecuteResult.java | 96 ++++++
.../processors/odbc/jdbc/JdbcQuery.java | 95 ++++++
.../processors/odbc/jdbc/JdbcRequest.java | 8 +
.../odbc/jdbc/JdbcRequestHandler.java | 66 +++-
.../processors/odbc/jdbc/JdbcResult.java | 11 +
11 files changed, 794 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
index 8ca3d45..cf7ee8f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
@@ -33,6 +33,7 @@ import org.apache.ignite.jdbc.JdbcPreparedStatementSelfTest;
import org.apache.ignite.jdbc.JdbcResultSetSelfTest;
import org.apache.ignite.jdbc.JdbcStatementSelfTest;
import org.apache.ignite.jdbc.thin.JdbcThinAutoCloseServerCursorTest;
+import org.apache.ignite.jdbc.thin.JdbcThinBatchSelfTest;
import org.apache.ignite.jdbc.thin.JdbcThinComplexQuerySelfTest;
import org.apache.ignite.jdbc.thin.JdbcThinConnectionSelfTest;
import org.apache.ignite.jdbc.thin.JdbcThinDeleteStatementSelfTest;
@@ -121,6 +122,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
suite.addTest(new TestSuite(JdbcThinMergeStatementSelfTest.class));
suite.addTest(new TestSuite(JdbcThinDeleteStatementSelfTest.class));
suite.addTest(new TestSuite(JdbcThinAutoCloseServerCursorTest.class));
+ suite.addTest(new TestSuite(JdbcThinBatchSelfTest.class));
// New thin JDBC driver, DDL tests
suite.addTest(new TestSuite(JdbcThinDynamicIndexAtomicPartitionedNearSelfTest.class));
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
new file mode 100644
index 0000000..5781e00
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
@@ -0,0 +1,333 @@
+/*
+ * 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.jdbc.thin;
+
+import java.sql.BatchUpdateException;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.concurrent.Callable;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ * Statement test.
+ */
+public class JdbcThinBatchSelfTest extends JdbcThinAbstractDmlStatementSelfTest {
+ /** SQL query. */
+ private static final String SQL_PREPARED = "insert into Person(_key, id, firstName, lastName, age) values " +
+ "(?, ?, ?, ?, ?)";
+
+ /** Statement. */
+ private Statement stmt;
+
+ /** Prepared statement. */
+ private PreparedStatement pstmt;
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ stmt = conn.createStatement();
+
+ pstmt = conn.prepareStatement(SQL_PREPARED);
+
+ assertNotNull(stmt);
+ assertFalse(stmt.isClosed());
+
+ assertNotNull(pstmt);
+ assertFalse(pstmt.isClosed());
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ if (stmt != null && !stmt.isClosed())
+ stmt.close();
+
+ if (pstmt != null && !pstmt.isClosed())
+ pstmt.close();
+
+ assertTrue(pstmt.isClosed());
+ assertTrue(stmt.isClosed());
+
+ super.afterTest();
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatch() throws SQLException {
+ final int BATCH_SIZE = 10;
+
+ for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+ stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+ + generateValues(idx, i + 1));
+ }
+
+ int [] updCnts = stmt.executeBatch();
+
+ assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+ for (int i = 0; i < BATCH_SIZE; ++i)
+ assertEquals("Invalid update count",i + 1, updCnts[i]);
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchOnClosedStatement() throws SQLException {
+ final Statement stmt2 = conn.createStatement();
+ final PreparedStatement pstmt2 = conn.prepareStatement("");
+
+ stmt2.close();
+ pstmt2.close();
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt2.addBatch("");
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt2.clearBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt2.executeBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ pstmt2.addBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ pstmt2.clearBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ pstmt2.executeBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Statement is closed.");
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchException() throws SQLException {
+ final int BATCH_SIZE = 7;
+
+ for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+ stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+ + generateValues(idx, i + 1));
+ }
+
+ stmt.addBatch("select * from Person");
+
+ stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+ + generateValues(100, 1));
+
+ try {
+ stmt.executeBatch();
+
+ fail("BatchUpdateException must be thrown");
+ } catch(BatchUpdateException e) {
+ int [] updCnts = e.getUpdateCounts();
+
+ assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+ for (int i = 0; i < BATCH_SIZE; ++i)
+ assertEquals("Invalid update count",i + 1, updCnts[i]);
+
+ if (!e.getMessage().contains("Query produced result set [qry=select * from Person, args=[]]")) {
+ log.error("Invalid exception: ", e);
+
+ fail();
+ }
+ }
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchClear() throws SQLException {
+ final int BATCH_SIZE = 7;
+
+ for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+ stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+ + generateValues(idx, i + 1));
+ }
+
+ stmt.clearBatch();
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ stmt.executeBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Batch is empty.");
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchPrepared() throws SQLException {
+ final int BATCH_SIZE = 10;
+
+ for (int i = 0; i < BATCH_SIZE; ++i) {
+ int paramCnt = 1;
+
+ pstmt.setString(paramCnt++, "p" + i);
+ pstmt.setInt(paramCnt++, i);
+ pstmt.setString(paramCnt++, "Name" + i);
+ pstmt.setString(paramCnt++, "Lastname" + i);
+ pstmt.setInt(paramCnt++, 20 + i);
+
+ pstmt.addBatch();
+ }
+
+ int [] updCnts = pstmt.executeBatch();
+
+ assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+ for (int i = 0; i < BATCH_SIZE; ++i)
+ assertEquals("Invalid update count",1, updCnts[i]);
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchExceptionPrepared() throws SQLException {
+ final int BATCH_SIZE = 7;
+
+ for (int i = 0; i < BATCH_SIZE; ++i) {
+ int paramCnt = 1;
+
+ pstmt.setString(paramCnt++, "p" + i);
+ pstmt.setInt(paramCnt++, i);
+ pstmt.setString(paramCnt++, "Name" + i);
+ pstmt.setString(paramCnt++, "Lastname" + i);
+ pstmt.setInt(paramCnt++, 20 + i);
+
+ pstmt.addBatch();
+ }
+
+ int paramCnt = 1;
+ pstmt.setString(paramCnt++, "p" + 100);
+ pstmt.setString(paramCnt++, "x");
+ pstmt.setString(paramCnt++, "Name" + 100);
+ pstmt.setString(paramCnt++, "Lastname" + 100);
+ pstmt.setInt(paramCnt++, 20 + 100);
+
+ pstmt.addBatch();
+
+ try {
+ pstmt.executeBatch();
+
+ fail("BatchUpdateException must be thrown");
+ } catch(BatchUpdateException e) {
+ int [] updCnts = e.getUpdateCounts();
+
+ assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+ for (int i = 0; i < BATCH_SIZE; ++i)
+ assertEquals("Invalid update count",1, updCnts[i]);
+
+ if (!e.getMessage().contains("Failed to execute SQL query.")) {
+ log.error("Invalid exception: ", e);
+
+ fail();
+ }
+ }
+ }
+
+ /**
+ * @throws SQLException If failed.
+ */
+ public void testBatchClearPrepared() throws SQLException {
+ final int BATCH_SIZE = 10;
+
+ for (int i = 0; i < BATCH_SIZE; ++i) {
+ int paramCnt = 1;
+
+ pstmt.setString(paramCnt++, "p" + i);
+ pstmt.setInt(paramCnt++, i);
+ pstmt.setString(paramCnt++, "Name" + i);
+ pstmt.setString(paramCnt++, "Lastname" + i);
+ pstmt.setInt(paramCnt++, 20 + i);
+
+ pstmt.addBatch();
+ }
+
+ pstmt.clearBatch();
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ pstmt.executeBatch();
+
+ return null;
+ }
+ }, SQLException.class, "Batch is empty.");
+ }
+
+ /**
+ * @param beginIndex Begin row index.
+ * @param cnt Count of rows.
+ * @return String contains values for 'cnt' rows.
+ */
+ private String generateValues(int beginIndex, int cnt) {
+ StringBuilder sb = new StringBuilder();
+
+ int lastIdx = beginIndex + cnt - 1;
+
+ for (int i = beginIndex; i < lastIdx; ++i)
+ sb.append(valuesRow(i)).append(',');
+
+ sb.append(valuesRow(lastIdx));
+
+ return sb.toString();
+ }
+
+ /**
+ * @param idx Index of the row.
+ * @return String with row values.
+ */
+ private String valuesRow(int idx) {
+ return String.format("('p%d', %d, 'Name%d', 'Lastname%d', %d)", idx, idx, idx, idx, 20 + idx);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
index 0c78a13..455c80f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
@@ -40,6 +40,7 @@ import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
/**
* JDBC prepared statement implementation.
@@ -230,7 +231,20 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
@Override public void addBatch() throws SQLException {
ensureNotClosed();
- throw new SQLFeatureNotSupportedException("Updates are not supported.");
+ if (batch == null) {
+ batch = new ArrayList<>();
+
+ batch.add(new JdbcQuery(sql, args.toArray(new Object[args.size()])));
+ }
+ else
+ batch.add(new JdbcQuery(null, args.toArray(new Object[args.size()])));
+
+ args = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addBatch(String sql) throws SQLException {
+ throw new SQLException("The method 'addBatch(String)' is called on PreparedStatement instance.");
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
index 2cad223..b01350a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
@@ -18,15 +18,20 @@
package org.apache.ignite.internal.jdbc.thin;
import java.io.IOException;
+import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.List;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult;
import static java.sql.ResultSet.CONCUR_READ_ONLY;
@@ -62,6 +67,9 @@ public class JdbcThinStatement implements Statement {
/** */
private boolean alreadyRead;
+ /** Batch. */
+ protected List<JdbcQuery> batch;
+
/**
* Creates new statement.
*
@@ -323,21 +331,53 @@ public class JdbcThinStatement implements Statement {
@Override public void addBatch(String sql) throws SQLException {
ensureNotClosed();
- throw new SQLFeatureNotSupportedException("Updates are not supported.");
+ if (batch == null)
+ batch = new ArrayList<>();
+
+ batch.add(new JdbcQuery(sql, null));
}
/** {@inheritDoc} */
@Override public void clearBatch() throws SQLException {
ensureNotClosed();
- throw new SQLFeatureNotSupportedException("Updates are not supported.");
+ batch = null;
}
/** {@inheritDoc} */
@Override public int[] executeBatch() throws SQLException {
ensureNotClosed();
- throw new SQLFeatureNotSupportedException("Updates are not supported.");
+ if (rs != null) {
+ rs.close();
+
+ rs = null;
+ }
+
+ alreadyRead = false;
+
+ if (batch == null || batch.isEmpty())
+ throw new SQLException("Batch is empty.");
+
+ try {
+ JdbcBatchExecuteResult res = conn.io().batchExecute(conn.getSchema(), batch);
+
+ if (res.errorCode() != SqlListenerResponse.STATUS_SUCCESS)
+ throw new BatchUpdateException(res.errorMessage(), null, res.errorCode(), res.updateCounts());
+
+ return res.updateCounts();
+ }
+ catch (IOException e) {
+ conn.close();
+
+ throw new SQLException("Failed to query Ignite.", e);
+ }
+ catch (IgniteCheckedException e) {
+ throw new SQLException("Failed to query Ignite.", e);
+ }
+ finally {
+ batch = null;
+ }
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index be62a8d..f54d5fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -32,6 +32,9 @@ import org.apache.ignite.internal.processors.odbc.SqlListenerNioListener;
import org.apache.ignite.internal.processors.odbc.SqlListenerProtocolVersion;
import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryCloseRequest;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteRequest;
import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult;
@@ -58,6 +61,9 @@ public class JdbcThinTcpIo {
/** Initial output for query message. */
private static final int QUERY_EXEC_MSG_INIT_CAP = 256;
+ /** Maximum batch query count. */
+ private static final int MAX_BATCH_QRY_CNT = 32;
+
/** Initial output for query fetch message. */
private static final int QUERY_FETCH_MSG_SIZE = 13;
@@ -289,6 +295,20 @@ public class JdbcThinTcpIo {
}
/**
+ * @param schema Schema.
+ * @param batch Batch queries.
+ * @return Result.
+ * @throws IOException On error.
+ * @throws IgniteCheckedException On error.
+ */
+ public JdbcBatchExecuteResult batchExecute(String schema, List<JdbcQuery> batch)
+ throws IOException, IgniteCheckedException {
+ int cnt = Math.min(MAX_BATCH_QRY_CNT, batch.size());
+
+ return sendRequest(new JdbcBatchExecuteRequest(schema, batch), QUERY_EXEC_MSG_INIT_CAP * cnt);
+ }
+
+ /**
* @param req ODBC request.
* @throws IOException On error.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
new file mode 100644
index 0000000..9f71bff
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.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.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * JDBC batch execute request.
+ */
+public class JdbcBatchExecuteRequest extends JdbcRequest {
+ /** Cache name. */
+ private String schema;
+
+ /** Sql query. */
+ @GridToStringInclude(sensitive = true)
+ private List<JdbcQuery> queries;
+
+ /**
+ * Default constructor.
+ */
+ public JdbcBatchExecuteRequest() {
+ super(BATCH_EXEC);
+ }
+
+ /**
+ * @param schema Schema.
+ * @param queries Queries.
+ */
+ public JdbcBatchExecuteRequest(String schema, List<JdbcQuery> queries) {
+ super(BATCH_EXEC);
+
+ assert !F.isEmpty(queries);
+
+ this.schema = schema;
+ this.queries = queries;
+ }
+
+ /**
+ * @return Schema.
+ */
+ @Nullable public String schema() {
+ return schema;
+ }
+
+ /**
+ * @return Queries.
+ */
+ public List<JdbcQuery> queries() {
+ return queries;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+ super.writeBinary(writer);
+
+ writer.writeString(schema);
+ writer.writeInt(queries.size());
+
+ for (JdbcQuery q : queries)
+ q.writeBinary(writer);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+ super.readBinary(reader);
+
+ schema = reader.readString();
+
+ int n = reader.readInt();
+
+ queries = new ArrayList<>(n);
+
+ for (int i = 0; i < n; ++i) {
+ JdbcQuery qry = new JdbcQuery();
+
+ qry.readBinary(reader);
+
+ queries.add(qry);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(JdbcBatchExecuteRequest.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
new file mode 100644
index 0000000..7977c22
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
@@ -0,0 +1,96 @@
+/*
+ * 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.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+
+/**
+ * JDBC batch execute result.
+ */
+public class JdbcBatchExecuteResult extends JdbcResult {
+ /** Update counts. */
+ private int [] updateCnts;
+
+ /** Batch update error code. */
+ private int errCode;
+
+ /** Batch update error message. */
+ private String errMsg;
+
+ /**
+ * Condtructor.
+ */
+ public JdbcBatchExecuteResult() {
+ super(BATCH_EXEC);
+ }
+
+ /**
+ * @param updateCnts Update counts for batch.
+ * @param errCode Error code.
+ * @param errMsg Error message.
+ */
+ public JdbcBatchExecuteResult(int [] updateCnts, int errCode, String errMsg) {
+ super(BATCH_EXEC);
+
+ this.updateCnts = updateCnts;
+ this.errCode = errCode;
+ this.errMsg = errMsg;
+ }
+
+ /**
+ * @return Update count for DML queries.
+ */
+ public int[] updateCounts() {
+ return updateCnts;
+ }
+
+ /**
+ * @return Batch error code.
+ */
+ public int errorCode() {
+ return errCode;
+ }
+
+ /**
+ * @return Batch error message.
+ */
+ public String errorMessage() {
+ return errMsg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+ super.writeBinary(writer);
+
+ writer.writeInt(errCode);
+ writer.writeString(errMsg);
+ writer.writeIntArray(updateCnts);
+ }
+
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+ super.readBinary(reader);
+
+ errCode = reader.readInt();
+ errMsg = reader.readString();
+ updateCnts = reader.readIntArray();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
new file mode 100644
index 0000000..f7ffb99
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
@@ -0,0 +1,95 @@
+/*
+ * 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.odbc.jdbc;
+
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC SQL query with parameters.
+ */
+public class JdbcQuery implements JdbcRawBinarylizable {
+ /** Query SQL. */
+ private String sql;
+
+ /** Arguments. */
+ private Object[] args;
+
+ /**
+ * Default constructor is used for serialization.
+ */
+ public JdbcQuery() {
+ // No-op.
+ }
+
+ /**
+ * @param sql Query SQL.
+ * @param args Arguments.
+ */
+ public JdbcQuery(String sql, Object[] args) {
+ this.sql = sql;
+ this.args = args;
+ }
+
+ /**
+ * @return Query SQL string.
+ */
+ public String sql() {
+ return sql;
+ }
+
+ /**
+ * @return Query arguments.
+ */
+ public Object[] args() {
+ return args;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBinary(BinaryWriterExImpl writer) {
+ writer.writeString(sql);
+
+ if (args == null || args.length == 0)
+ writer.writeInt(0);
+ else {
+ writer.writeInt(args.length);
+
+ for (Object arg : args)
+ SqlListenerUtils.writeObject(writer, arg, false);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readBinary(BinaryReaderExImpl reader) {
+ sql = reader.readString();
+
+ int argsNum = reader.readInt();
+
+ args = new Object[argsNum];
+
+ for (int i = 0; i < argsNum; ++i)
+ args[i] = SqlListenerUtils.readObject(reader, false);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(JdbcQuery.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
index d6f8fd3..0e144cc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
@@ -39,6 +39,9 @@ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinaryliza
/** Get columns meta query. */
public static final byte QRY_META = 5;
+ /** Batch queries. */
+ public static final byte BATCH_EXEC = 6;
+
/** Request type. */
private byte type;
@@ -97,6 +100,11 @@ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinaryliza
break;
+ case BATCH_EXEC:
+ req = new JdbcBatchExecuteRequest();
+
+ break;
+
default:
throw new IgniteException("Unknown SQL listener request ID: [request ID=" + reqType + ']');
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index 94ac433..60c08f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -17,6 +17,11 @@
package org.apache.ignite.internal.processors.odbc.jdbc;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
@@ -31,10 +36,7 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
+import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.BATCH_EXEC;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_CLOSE;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_EXEC;
import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_FETCH;
@@ -129,6 +131,9 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
case QRY_META:
return getQueryMeta((JdbcQueryMetadataRequest)req);
+
+ case BATCH_EXEC:
+ return executeBatch((JdbcBatchExecuteRequest)req);
}
return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, "Unsupported JDBC request [req=" + req + ']');
@@ -307,4 +312,57 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString());
}
}
+
+ /**
+ * @param req Request.
+ * @return Response.
+ */
+ private SqlListenerResponse executeBatch(JdbcBatchExecuteRequest req) {
+ String schemaName = req.schema();
+
+ if (F.isEmpty(schemaName))
+ schemaName = QueryUtils.DFLT_SCHEMA;
+
+ int successQueries = 0;
+ int updCnts[] = new int[req.queries().size()];
+
+ try {
+ String sql = null;
+
+ for (JdbcQuery q : req.queries()) {
+ if (q.sql() != null)
+ sql = q.sql();
+
+ SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+
+ qry.setArgs(q.args());
+
+ qry.setDistributedJoins(distributedJoins);
+ qry.setEnforceJoinOrder(enforceJoinOrder);
+ qry.setCollocated(collocated);
+ qry.setReplicatedOnly(replicatedOnly);
+
+ qry.setSchema(schemaName);
+
+ QueryCursorImpl<List<?>> qryCur = (QueryCursorImpl<List<?>>)ctx.query()
+ .querySqlFieldsNoCache(qry, true);
+
+ if (qryCur.isQuery())
+ throw new IgniteCheckedException("Query produced result set [qry=" + q.sql() + ", args=" +
+ Arrays.toString(q.args()) + ']');
+
+ List<List<?>> items = qryCur.getAll();
+
+ updCnts[successQueries++] = ((Long)items.get(0).get(0)).intValue();
+ }
+
+ return new JdbcResponse(new JdbcBatchExecuteResult(updCnts, SqlListenerResponse.STATUS_SUCCESS, null));
+ }
+ catch (Exception e) {
+ U.error(log, "Failed to execute batch query [reqId=" + req.requestId() + ", req=" + req + ']', e);
+
+ return new JdbcResponse(new JdbcBatchExecuteResult(Arrays.copyOf(updCnts, successQueries),
+ SqlListenerResponse.STATUS_FAILED, e.toString()));
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0f22223b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
index 2d7666e..48affe9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
@@ -35,6 +35,9 @@ public class JdbcResult implements JdbcRawBinarylizable {
/** Get columns meta query result. */
public static final byte QRY_META = 4;
+ /** Batch queries. */
+ public static final byte BATCH_EXEC = 6;
+
/** Success status. */
private byte type;
@@ -70,14 +73,22 @@ public class JdbcResult implements JdbcRawBinarylizable {
switch(resId) {
case QRY_EXEC:
res = new JdbcQueryExecuteResult();
+
break;
case QRY_FETCH:
res = new JdbcQueryFetchResult();
+
break;
case QRY_META:
res = new JdbcQueryMetadataResult();
+
+ break;
+
+ case BATCH_EXEC:
+ res = new JdbcBatchExecuteResult();
+
break;
default:
[11/29] ignite git commit: IGNITE-5982: GridMapQueryExecutor was
split into several pieces.
Posted by nt...@apache.org.
IGNITE-5982: GridMapQueryExecutor was split into several pieces.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/879f1910
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/879f1910
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/879f1910
Branch: refs/heads/ignite-5947
Commit: 879f19106b22e66d5f6ea94424d961d049397410
Parents: b093afb
Author: devozerov <vo...@gridgain.com>
Authored: Tue Aug 8 15:16:58 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 15:17:58 2017 +0300
----------------------------------------------------------------------
.../query/h2/twostep/GridMapQueryExecutor.java | 501 ++-----------------
.../query/h2/twostep/MapNodeResults.java | 108 ++++
.../query/h2/twostep/MapQueryResult.java | 258 ++++++++++
.../query/h2/twostep/MapQueryResults.java | 155 ++++++
.../h2/twostep/MapReplicatedReservation.java | 38 ++
.../query/h2/twostep/MapRequestKey.java | 65 +++
.../query/h2/twostep/MapReservationKey.java | 73 +++
7 files changed, 730 insertions(+), 468 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index fcf5f10..19b628b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -17,7 +17,6 @@
package org.apache.ignite.internal.processors.query.h2.twostep;
-import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.AbstractCollection;
@@ -31,7 +30,6 @@ import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicReferenceArray;
import javax.cache.CacheException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
@@ -39,7 +37,6 @@ import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cache.query.QueryCancelledException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.events.CacheQueryExecutedEvent;
-import org.apache.ignite.events.CacheQueryReadEvent;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.Event;
import org.apache.ignite.events.EventType;
@@ -57,35 +54,29 @@ import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
import org.apache.ignite.internal.processors.cache.query.GridCacheQueryMarshallable;
import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
import org.apache.ignite.internal.processors.cache.query.QueryTable;
-import org.apache.ignite.internal.processors.query.GridQueryCancel;
import org.apache.ignite.internal.processors.query.h2.H2Utils;
import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
import org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2RetryException;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
-import org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryCancelRequest;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryFailResponse;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageRequest;
import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageResponse;
import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2QueryRequest;
-import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
import org.apache.ignite.internal.util.GridSpinBusyLock;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.h2.jdbc.JdbcResultSet;
-import org.h2.result.ResultInterface;
import org.h2.value.Value;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED;
-import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
import static org.apache.ignite.internal.managers.communication.GridIoPolicy.QUERY_POOL;
import static org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion.NONE;
import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
@@ -94,30 +85,13 @@ import static org.apache.ignite.internal.processors.query.h2.opt.DistributedJoin
import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.MAP;
import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.REPLICATED;
import static org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory.toMessages;
-import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
/**
* Map query executor.
*/
+@SuppressWarnings("ForLoopReplaceableByForEach")
public class GridMapQueryExecutor {
/** */
- private static final Field RESULT_FIELD;
-
- /*
- * Initialize.
- */
- static {
- try {
- RESULT_FIELD = JdbcResultSet.class.getDeclaredField("result");
-
- RESULT_FIELD.setAccessible(true);
- }
- catch (NoSuchFieldException e) {
- throw new IllegalStateException("Check H2 version in classpath.", e);
- }
- }
-
- /** */
private IgniteLogger log;
/** */
@@ -127,14 +101,13 @@ public class GridMapQueryExecutor {
private IgniteH2Indexing h2;
/** */
- private ConcurrentMap<UUID, NodeResults> qryRess = new ConcurrentHashMap8<>();
+ private ConcurrentMap<UUID, MapNodeResults> qryRess = new ConcurrentHashMap8<>();
/** */
private final GridSpinBusyLock busyLock;
/** */
- private final ConcurrentMap<T2<String, AffinityTopologyVersion>, GridReservable> reservations =
- new ConcurrentHashMap8<>();
+ private final ConcurrentMap<MapReservationKey, GridReservable> reservations = new ConcurrentHashMap8<>();
/**
* @param busyLock Busy lock.
@@ -162,7 +135,7 @@ public class GridMapQueryExecutor {
GridH2QueryContext.clearAfterDeadNode(locNodeId, nodeId);
- NodeResults nodeRess = qryRess.remove(nodeId);
+ MapNodeResults nodeRess = qryRess.remove(nodeId);
if (nodeRess == null)
return;
@@ -172,6 +145,7 @@ public class GridMapQueryExecutor {
}, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
ctx.io().addMessageListener(GridTopic.TOPIC_QUERY, new GridMessageListener() {
+ @SuppressWarnings("deprecation")
@Override public void onMessage(UUID nodeId, Object msg, byte plc) {
if (!busyLock.enterBusy())
return;
@@ -228,7 +202,7 @@ public class GridMapQueryExecutor {
private void onCancel(ClusterNode node, GridQueryCancelRequest msg) {
long qryReqId = msg.queryRequestId();
- NodeResults nodeRess = resultsForNode(node.id());
+ MapNodeResults nodeRess = resultsForNode(node.id());
boolean clear = GridH2QueryContext.clear(ctx.localNodeId(), node.id(), qryReqId, MAP);
@@ -245,13 +219,13 @@ public class GridMapQueryExecutor {
* @param nodeId Node ID.
* @return Results for node.
*/
- private NodeResults resultsForNode(UUID nodeId) {
- NodeResults nodeRess = qryRess.get(nodeId);
+ private MapNodeResults resultsForNode(UUID nodeId) {
+ MapNodeResults nodeRess = qryRess.get(nodeId);
if (nodeRess == null) {
- nodeRess = new NodeResults();
+ nodeRess = new MapNodeResults();
- NodeResults old = qryRess.putIfAbsent(nodeId, nodeRess);
+ MapNodeResults old = qryRess.putIfAbsent(nodeId, nodeRess);
if (old != null)
nodeRess = old;
@@ -300,13 +274,12 @@ public class GridMapQueryExecutor {
continue;
// For replicated cache topology version does not make sense.
- final T2<String,AffinityTopologyVersion> grpKey =
- new T2<>(cctx.name(), cctx.isReplicated() ? null : topVer);
+ final MapReservationKey grpKey = new MapReservationKey(cctx.name(), cctx.isReplicated() ? null : topVer);
GridReservable r = reservations.get(grpKey);
if (explicitParts == null && r != null) { // Try to reserve group partition if any and no explicits.
- if (r != ReplicatedReservation.INSTANCE) {
+ if (r != MapReplicatedReservation.INSTANCE) {
if (!r.reserve())
return false; // We need explicit partitions here -> retry.
@@ -327,7 +300,7 @@ public class GridMapQueryExecutor {
}
// Mark that we checked this replicated cache.
- reservations.putIfAbsent(grpKey, ReplicatedReservation.INSTANCE);
+ reservations.putIfAbsent(grpKey, MapReplicatedReservation.INSTANCE);
}
}
else { // Reserve primary partitions for partitioned cache (if no explicit given).
@@ -381,6 +354,7 @@ public class GridMapQueryExecutor {
return Collections.emptySet();
return new AbstractCollection<Integer>() {
+ @SuppressWarnings("NullableProblems")
@Override public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
/** */
@@ -537,9 +511,9 @@ public class GridMapQueryExecutor {
GridCacheContext<?, ?> mainCctx =
!F.isEmpty(cacheIds) ? ctx.cache().context().cacheContext(cacheIds.get(0)) : null;
- NodeResults nodeRess = resultsForNode(node.id());
+ MapNodeResults nodeRess = resultsForNode(node.id());
- QueryResults qr = null;
+ MapQueryResults qr = null;
List<GridReservable> reserved = new ArrayList<>();
@@ -553,7 +527,7 @@ public class GridMapQueryExecutor {
}
}
- qr = new QueryResults(reqId, qrys.size(), mainCctx != null ? mainCctx.name() : null);
+ qr = new MapQueryResults(h2, reqId, qrys.size(), mainCctx != null ? mainCctx.name() : null);
if (nodeRess.put(reqId, segmentId, qr) != null)
throw new IllegalStateException();
@@ -619,7 +593,7 @@ public class GridMapQueryExecutor {
rs = h2.executeSqlQueryWithTimer(conn, qry.query(),
F.asList(qry.parameters(params)), true,
timeout,
- qr.cancels[qryIdx]);
+ qr.queryCancel(qryIdx));
if (evt) {
assert mainCctx != null;
@@ -644,7 +618,7 @@ public class GridMapQueryExecutor {
qr.addResult(qryIdx, qry, node.id(), rs, params);
- if (qr.canceled) {
+ if (qr.cancelled()) {
qr.result(qryIdx).close();
throw new QueryCancelledException();
@@ -724,7 +698,7 @@ public class GridMapQueryExecutor {
* @param req Request.
*/
private void onNextPageRequest(ClusterNode node, GridQueryNextPageRequest req) {
- NodeResults nodeRess = qryRess.get(node.id());
+ MapNodeResults nodeRess = qryRess.get(node.id());
if (nodeRess == null) {
sendError(node, req.queryRequestId(), new CacheException("No node result found for request: " + req));
@@ -736,11 +710,11 @@ public class GridMapQueryExecutor {
return;
}
- QueryResults qr = nodeRess.get(req.queryRequestId(), req.segmentId());
+ MapQueryResults qr = nodeRess.get(req.queryRequestId(), req.segmentId());
if (qr == null)
sendError(node, req.queryRequestId(), new CacheException("No query result found for request: " + req));
- else if (qr.canceled)
+ else if (qr.cancelled())
sendError(node, req.queryRequestId(), new QueryCancelledException());
else
sendNextPage(nodeRess, node, qr, req.query(), req.segmentId(), req.pageSize());
@@ -754,16 +728,16 @@ public class GridMapQueryExecutor {
* @param segmentId Index segment ID.
* @param pageSize Page size.
*/
- private void sendNextPage(NodeResults nodeRess, ClusterNode node, QueryResults qr, int qry, int segmentId,
+ private void sendNextPage(MapNodeResults nodeRess, ClusterNode node, MapQueryResults qr, int qry, int segmentId,
int pageSize) {
- QueryResult res = qr.result(qry);
+ MapQueryResult res = qr.result(qry);
assert res != null;
- if (res.closed)
+ if (res.closed())
return;
- int page = res.page;
+ int page = res.page();
List<Value[]> rows = new ArrayList<>(Math.min(64, pageSize));
@@ -773,16 +747,16 @@ public class GridMapQueryExecutor {
res.close();
if (qr.isAllClosed())
- nodeRess.remove(qr.qryReqId, segmentId, qr);
+ nodeRess.remove(qr.queryRequestId(), segmentId, qr);
}
try {
boolean loc = node.isLocal();
- GridQueryNextPageResponse msg = new GridQueryNextPageResponse(qr.qryReqId, segmentId, qry, page,
- page == 0 ? res.rowCnt : -1,
- res.cols,
- loc ? null : toMessages(rows, new ArrayList<Message>(res.cols)),
+ GridQueryNextPageResponse msg = new GridQueryNextPageResponse(qr.queryRequestId(), segmentId, qry, page,
+ page == 0 ? res.rowCount() : -1,
+ res.columnCount(),
+ loc ? null : toMessages(rows, new ArrayList<Message>(res.columnCount())),
loc ? rows : null);
if (loc)
@@ -828,418 +802,9 @@ public class GridMapQueryExecutor {
*/
public void onCacheStop(String cacheName) {
// Drop group reservations.
- for (T2<String,AffinityTopologyVersion> grpKey : reservations.keySet()) {
- if (F.eq(grpKey.get1(), cacheName))
+ for (MapReservationKey grpKey : reservations.keySet()) {
+ if (F.eq(grpKey.cacheName(), cacheName))
reservations.remove(grpKey);
}
}
-
-
- /**
- *
- */
- private static class NodeResults {
- /** */
- private final ConcurrentMap<RequestKey, QueryResults> res = new ConcurrentHashMap8<>();
-
- /** */
- private final GridBoundedConcurrentLinkedHashMap<Long, Boolean> qryHist =
- new GridBoundedConcurrentLinkedHashMap<>(1024, 1024, 0.75f, 64, PER_SEGMENT_Q);
-
- /**
- * @param reqId Query Request ID.
- * @return {@code False} if query was already cancelled.
- */
- boolean cancelled(long reqId) {
- return qryHist.get(reqId) != null;
- }
-
- /**
- * @param reqId Query Request ID.
- * @return {@code True} if cancelled.
- */
- boolean onCancel(long reqId) {
- Boolean old = qryHist.putIfAbsent(reqId, Boolean.FALSE);
-
- return old == null;
- }
-
- /**
- * @param reqId Query Request ID.
- * @param segmentId Index segment ID.
- * @return query partial results.
- */
- public QueryResults get(long reqId, int segmentId) {
- return res.get(new RequestKey(reqId, segmentId));
- }
-
- /**
- * Cancel all thread of given request.
- * @param reqID Request ID.
- */
- public void cancelRequest(long reqID) {
- for (RequestKey key : res.keySet()) {
- if (key.reqId == reqID) {
- QueryResults removed = res.remove(key);
-
- if (removed != null)
- removed.cancel(true);
- }
-
- }
- }
-
- /**
- * @param reqId Query Request ID.
- * @param segmentId Index segment ID.
- * @param qr Query Results.
- * @return {@code True} if removed.
- */
- public boolean remove(long reqId, int segmentId, QueryResults qr) {
- return res.remove(new RequestKey(reqId, segmentId), qr);
- }
-
- /**
- * @param reqId Query Request ID.
- * @param segmentId Index segment ID.
- * @param qr Query Results.
- * @return previous value.
- */
- public QueryResults put(long reqId, int segmentId, QueryResults qr) {
- return res.put(new RequestKey(reqId, segmentId), qr);
- }
-
- /**
- * Cancel all node queries.
- */
- public void cancelAll() {
- for (QueryResults ress : res.values())
- ress.cancel(true);
- }
-
- /**
- *
- */
- private static class RequestKey {
- /** */
- private long reqId;
-
- /** */
- private int segmentId;
-
- /** Constructor */
- RequestKey(long reqId, int segmentId) {
- this.reqId = reqId;
- this.segmentId = segmentId;
- }
-
- /** {@inheritDoc} */
- @Override public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
-
- RequestKey other = (RequestKey)o;
-
- return reqId == other.reqId && segmentId == other.segmentId;
-
- }
-
- /** {@inheritDoc} */
- @Override public int hashCode() {
- int result = (int)(reqId ^ (reqId >>> 32));
- result = 31 * result + segmentId;
- return result;
- }
- }
- }
-
- /**
- *
- */
- private class QueryResults {
- /** */
- private final long qryReqId;
-
- /** */
- private final AtomicReferenceArray<QueryResult> results;
-
- /** */
- private final GridQueryCancel[] cancels;
-
- /** */
- private final String cacheName;
-
- /** */
- private volatile boolean canceled;
-
- /**
- * @param qryReqId Query request ID.
- * @param qrys Number of queries.
- * @param cacheName Cache name.
- */
- @SuppressWarnings("unchecked")
- private QueryResults(long qryReqId, int qrys, @Nullable String cacheName) {
- this.qryReqId = qryReqId;
- this.cacheName = cacheName;
-
- results = new AtomicReferenceArray<>(qrys);
- cancels = new GridQueryCancel[qrys];
-
- for (int i = 0; i < cancels.length; i++)
- cancels[i] = new GridQueryCancel();
- }
-
- /**
- * @param qry Query result index.
- * @return Query result.
- */
- QueryResult result(int qry) {
- return results.get(qry);
- }
-
- /**
- * @param qry Query result index.
- * @param q Query object.
- * @param qrySrcNodeId Query source node.
- * @param rs Result set.
- */
- void addResult(int qry, GridCacheSqlQuery q, UUID qrySrcNodeId, ResultSet rs, Object[] params) {
- if (!results.compareAndSet(qry, null, new QueryResult(rs, ctx, cacheName, qrySrcNodeId, q, params)))
- throw new IllegalStateException();
- }
-
- /**
- * @return {@code true} If all results are closed.
- */
- boolean isAllClosed() {
- for (int i = 0; i < results.length(); i++) {
- QueryResult res = results.get(i);
-
- if (res == null || !res.closed)
- return false;
- }
-
- return true;
- }
-
- /**
- * Cancels the query.
- */
- void cancel(boolean forceQryCancel) {
- if (canceled)
- return;
-
- canceled = true;
-
- for (int i = 0; i < results.length(); i++) {
- QueryResult res = results.get(i);
-
- if (res != null) {
- res.close();
-
- continue;
- }
-
- if (forceQryCancel) {
- GridQueryCancel cancel = cancels[i];
-
- if (cancel != null)
- cancel.cancel();
- }
- }
- }
- }
-
- /**
- * Result for a single part of the query.
- */
- private class QueryResult implements AutoCloseable {
- /** */
- private final ResultInterface res;
-
- /** */
- private final ResultSet rs;
-
- /** Kernal context. */
- private final GridKernalContext ctx;
-
- /** */
- private final String cacheName;
-
- /** */
- private final GridCacheSqlQuery qry;
-
- /** */
- private final UUID qrySrcNodeId;
-
- /** */
- private final int cols;
-
- /** */
- private int page;
-
- /** */
- private final int rowCnt;
-
- /** */
- private boolean cpNeeded;
-
- /** */
- private volatile boolean closed;
-
- /** */
- private final Object[] params;
-
- /**
- * @param rs Result set.
- * @param ctx Kernal context.
- * @param cacheName Cache name.
- * @param qrySrcNodeId Query source node.
- * @param qry Query.
- * @param params Query params.
- */
- private QueryResult(ResultSet rs, GridKernalContext ctx, @Nullable String cacheName,
- UUID qrySrcNodeId, GridCacheSqlQuery qry, Object[] params) {
- this.ctx = ctx;
- this.cacheName = cacheName;
- this.qry = qry;
- this.params = params;
- this.qrySrcNodeId = qrySrcNodeId;
- this.cpNeeded = F.eq(ctx.localNodeId(), qrySrcNodeId);
-
- if (rs != null) {
- this.rs = rs;
- try {
- res = (ResultInterface)RESULT_FIELD.get(rs);
- }
- catch (IllegalAccessException e) {
- throw new IllegalStateException(e); // Must not happen.
- }
-
- rowCnt = res.getRowCount();
- cols = res.getVisibleColumnCount();
- }
- else {
- this.rs = null;
- this.res = null;
- this.cols = -1;
- this.rowCnt = -1;
-
- closed = true;
- }
- }
-
- /**
- * @param rows Collection to fetch into.
- * @param pageSize Page size.
- * @return {@code true} If there are no more rows available.
- */
- synchronized boolean fetchNextPage(List<Value[]> rows, int pageSize) {
- if (closed)
- return true;
-
- boolean readEvt = cacheName != null && ctx.event().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
-
- page++;
-
- for (int i = 0 ; i < pageSize; i++) {
- if (!res.next())
- return true;
-
- Value[] row = res.currentRow();
-
- if (cpNeeded) {
- boolean copied = false;
-
- for (int j = 0; j < row.length; j++) {
- Value val = row[j];
-
- if (val instanceof GridH2ValueCacheObject) {
- GridH2ValueCacheObject valCacheObj = (GridH2ValueCacheObject)val;
-
- row[j] = new GridH2ValueCacheObject(valCacheObj.getCacheObject(), h2.objectContext()) {
- @Override public Object getObject() {
- return getObject(true);
- }
- };
-
- copied = true;
- }
- }
-
- if (i == 0 && !copied)
- cpNeeded = false; // No copy on read caches, skip next checks.
- }
-
- assert row != null;
-
- if (readEvt) {
- ctx.event().record(new CacheQueryReadEvent<>(
- ctx.discovery().localNode(),
- "SQL fields query result set row read.",
- EVT_CACHE_QUERY_OBJECT_READ,
- CacheQueryType.SQL.name(),
- cacheName,
- null,
- qry.query(),
- null,
- null,
- params,
- qrySrcNodeId,
- null,
- null,
- null,
- null,
- row(row)));
- }
-
- rows.add(res.currentRow());
- }
-
- return false;
- }
-
- /**
- * @param row Values array row.
- * @return Objects list row.
- */
- private List<?> row(Value[] row) {
- List<Object> res = new ArrayList<>(row.length);
-
- for (Value v : row)
- res.add(v.getObject());
-
- return res;
- }
-
- /** {@inheritDoc} */
- @Override public synchronized void close() {
- if (closed)
- return;
-
- closed = true;
-
- U.close(rs, log);
- }
- }
-
- /**
- * Fake reservation object for replicated caches.
- */
- private static class ReplicatedReservation implements GridReservable {
- /** */
- static final ReplicatedReservation INSTANCE = new ReplicatedReservation();
-
- /** {@inheritDoc} */
- @Override public boolean reserve() {
- throw new IllegalStateException();
- }
-
- /** {@inheritDoc} */
- @Override public void release() {
- throw new IllegalStateException();
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java
new file mode 100644
index 0000000..d5ea357
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.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.twostep;
+
+import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
+import org.jsr166.ConcurrentHashMap8;
+
+import java.util.concurrent.ConcurrentMap;
+
+import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
+
+/**
+ * Mapper node results.
+ */
+class MapNodeResults {
+ /** */
+ private final ConcurrentMap<MapRequestKey, MapQueryResults> res = new ConcurrentHashMap8<>();
+
+ /** */
+ private final GridBoundedConcurrentLinkedHashMap<Long, Boolean> qryHist =
+ new GridBoundedConcurrentLinkedHashMap<>(1024, 1024, 0.75f, 64, PER_SEGMENT_Q);
+
+ /**
+ * @param reqId Query Request ID.
+ * @return {@code False} if query was already cancelled.
+ */
+ boolean cancelled(long reqId) {
+ return qryHist.get(reqId) != null;
+ }
+
+ /**
+ * @param reqId Query Request ID.
+ * @return {@code True} if cancelled.
+ */
+ boolean onCancel(long reqId) {
+ Boolean old = qryHist.putIfAbsent(reqId, Boolean.FALSE);
+
+ return old == null;
+ }
+
+ /**
+ * @param reqId Query Request ID.
+ * @param segmentId Index segment ID.
+ * @return query partial results.
+ */
+ public MapQueryResults get(long reqId, int segmentId) {
+ return res.get(new MapRequestKey(reqId, segmentId));
+ }
+
+ /**
+ * Cancel all thread of given request.
+ * @param reqId Request ID.
+ */
+ public void cancelRequest(long reqId) {
+ for (MapRequestKey key : res.keySet()) {
+ if (key.requestId() == reqId) {
+ MapQueryResults removed = res.remove(key);
+
+ if (removed != null)
+ removed.cancel(true);
+ }
+ }
+ }
+
+ /**
+ * @param reqId Query Request ID.
+ * @param segmentId Index segment ID.
+ * @param qr Query Results.
+ * @return {@code True} if removed.
+ */
+ public boolean remove(long reqId, int segmentId, MapQueryResults qr) {
+ return res.remove(new MapRequestKey(reqId, segmentId), qr);
+ }
+
+ /**
+ * @param reqId Query Request ID.
+ * @param segmentId Index segment ID.
+ * @param qr Query Results.
+ * @return previous value.
+ */
+ public MapQueryResults put(long reqId, int segmentId, MapQueryResults qr) {
+ return res.put(new MapRequestKey(reqId, segmentId), qr);
+ }
+
+ /**
+ * Cancel all node queries.
+ */
+ public void cancelAll() {
+ for (MapQueryResults ress : res.values())
+ ress.cancel(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
new file mode 100644
index 0000000..4799e03
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
@@ -0,0 +1,258 @@
+/*
+ * 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.twostep;
+
+import org.apache.ignite.events.CacheQueryReadEvent;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.h2.jdbc.JdbcResultSet;
+import org.h2.result.ResultInterface;
+import org.h2.value.Value;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Field;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
+
+/**
+ * Mapper result for a single part of the query.
+ */
+class MapQueryResult implements AutoCloseable {
+ /** */
+ private static final Field RESULT_FIELD;
+
+ /*
+ * Initialize.
+ */
+ static {
+ try {
+ RESULT_FIELD = JdbcResultSet.class.getDeclaredField("result");
+
+ RESULT_FIELD.setAccessible(true);
+ }
+ catch (NoSuchFieldException e) {
+ throw new IllegalStateException("Check H2 version in classpath.", e);
+ }
+ }
+
+ /** Indexing. */
+ private final IgniteH2Indexing h2;
+
+ /** */
+ private final ResultInterface res;
+
+ /** */
+ private final ResultSet rs;
+
+ /** */
+ private final String cacheName;
+
+ /** */
+ private final GridCacheSqlQuery qry;
+
+ /** */
+ private final UUID qrySrcNodeId;
+
+ /** */
+ private final int cols;
+
+ /** */
+ private int page;
+
+ /** */
+ private final int rowCnt;
+
+ /** */
+ private boolean cpNeeded;
+
+ /** */
+ private volatile boolean closed;
+
+ /** */
+ private final Object[] params;
+
+ /**
+ * @param rs Result set.
+ * @param cacheName Cache name.
+ * @param qrySrcNodeId Query source node.
+ * @param qry Query.
+ * @param params Query params.
+ */
+ MapQueryResult(IgniteH2Indexing h2, ResultSet rs, @Nullable String cacheName,
+ UUID qrySrcNodeId, GridCacheSqlQuery qry, Object[] params) {
+ this.h2 = h2;
+ this.cacheName = cacheName;
+ this.qry = qry;
+ this.params = params;
+ this.qrySrcNodeId = qrySrcNodeId;
+ this.cpNeeded = F.eq(h2.kernalContext().localNodeId(), qrySrcNodeId);
+
+ if (rs != null) {
+ this.rs = rs;
+ try {
+ res = (ResultInterface)RESULT_FIELD.get(rs);
+ }
+ catch (IllegalAccessException e) {
+ throw new IllegalStateException(e); // Must not happen.
+ }
+
+ rowCnt = res.getRowCount();
+ cols = res.getVisibleColumnCount();
+ }
+ else {
+ this.rs = null;
+ this.res = null;
+ this.cols = -1;
+ this.rowCnt = -1;
+
+ closed = true;
+ }
+ }
+
+ /**
+ * @return Page number.
+ */
+ int page() {
+ return page;
+ }
+
+ /**
+ * @return Row count.
+ */
+ int rowCount() {
+ return rowCnt;
+ }
+
+ /**
+ * @return Column ocunt.
+ */
+ int columnCount() {
+ return cols;
+ }
+
+ /**
+ * @return Closed flag.
+ */
+ boolean closed() {
+ return closed;
+ }
+
+ /**
+ * @param rows Collection to fetch into.
+ * @param pageSize Page size.
+ * @return {@code true} If there are no more rows available.
+ */
+ synchronized boolean fetchNextPage(List<Value[]> rows, int pageSize) {
+ if (closed)
+ return true;
+
+ boolean readEvt = cacheName != null && h2.kernalContext().event().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
+
+ page++;
+
+ for (int i = 0 ; i < pageSize; i++) {
+ if (!res.next())
+ return true;
+
+ Value[] row = res.currentRow();
+
+ if (cpNeeded) {
+ boolean copied = false;
+
+ for (int j = 0; j < row.length; j++) {
+ Value val = row[j];
+
+ if (val instanceof GridH2ValueCacheObject) {
+ GridH2ValueCacheObject valCacheObj = (GridH2ValueCacheObject)val;
+
+ row[j] = new GridH2ValueCacheObject(valCacheObj.getCacheObject(), h2.objectContext()) {
+ @Override public Object getObject() {
+ return getObject(true);
+ }
+ };
+
+ copied = true;
+ }
+ }
+
+ if (i == 0 && !copied)
+ cpNeeded = false; // No copy on read caches, skip next checks.
+ }
+
+ assert row != null;
+
+ if (readEvt) {
+ GridKernalContext ctx = h2.kernalContext();
+
+ ctx.event().record(new CacheQueryReadEvent<>(
+ ctx.discovery().localNode(),
+ "SQL fields query result set row read.",
+ EVT_CACHE_QUERY_OBJECT_READ,
+ CacheQueryType.SQL.name(),
+ cacheName,
+ null,
+ qry.query(),
+ null,
+ null,
+ params,
+ qrySrcNodeId,
+ null,
+ null,
+ null,
+ null,
+ row(row)));
+ }
+
+ rows.add(res.currentRow());
+ }
+
+ return false;
+ }
+
+ /**
+ * @param row Values array row.
+ * @return Objects list row.
+ */
+ private List<?> row(Value[] row) {
+ List<Object> res = new ArrayList<>(row.length);
+
+ for (Value v : row)
+ res.add(v.getObject());
+
+ return res;
+ }
+
+ /** {@inheritDoc} */
+ @Override public synchronized void close() {
+ if (closed)
+ return;
+
+ closed = true;
+
+ U.closeQuiet(rs);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
new file mode 100644
index 0000000..7ad1d14
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
@@ -0,0 +1,155 @@
+/*
+ * 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.twostep;
+
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
+import org.apache.ignite.internal.processors.query.GridQueryCancel;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.jetbrains.annotations.Nullable;
+
+import java.sql.ResultSet;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+/**
+ * Mapper query results.
+ */
+class MapQueryResults {
+ /** H@ indexing. */
+ private final IgniteH2Indexing h2;
+
+ /** */
+ private final long qryReqId;
+
+ /** */
+ private final AtomicReferenceArray<MapQueryResult> results;
+
+ /** */
+ private final GridQueryCancel[] cancels;
+
+ /** */
+ private final String cacheName;
+
+ /** */
+ private volatile boolean cancelled;
+
+ /**
+ * @param qryReqId Query request ID.
+ * @param qrys Number of queries.
+ * @param cacheName Cache name.
+ */
+ @SuppressWarnings("unchecked")
+ MapQueryResults(IgniteH2Indexing h2, long qryReqId, int qrys,
+ @Nullable String cacheName) {
+ this.h2 = h2;
+ this.qryReqId = qryReqId;
+ this.cacheName = cacheName;
+
+ results = new AtomicReferenceArray<>(qrys);
+ cancels = new GridQueryCancel[qrys];
+
+ for (int i = 0; i < cancels.length; i++)
+ cancels[i] = new GridQueryCancel();
+ }
+
+ /**
+ * @param qry Query result index.
+ * @return Query result.
+ */
+ MapQueryResult result(int qry) {
+ return results.get(qry);
+ }
+
+ /**
+ * Get cancel token for query.
+ *
+ * @param qryIdx Query index.
+ * @return Cancel token.
+ */
+ GridQueryCancel queryCancel(int qryIdx) {
+ return cancels[qryIdx];
+ }
+
+ /**
+ * @param qry Query result index.
+ * @param q Query object.
+ * @param qrySrcNodeId Query source node.
+ * @param rs Result set.
+ */
+ void addResult(int qry, GridCacheSqlQuery q, UUID qrySrcNodeId, ResultSet rs, Object[] params) {
+ MapQueryResult res = new MapQueryResult(h2, rs, cacheName, qrySrcNodeId, q, params);
+
+ if (!results.compareAndSet(qry, null, res))
+ throw new IllegalStateException();
+ }
+
+ /**
+ * @return {@code true} If all results are closed.
+ */
+ boolean isAllClosed() {
+ for (int i = 0; i < results.length(); i++) {
+ MapQueryResult res = results.get(i);
+
+ if (res == null || !res.closed())
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Cancels the query.
+ */
+ void cancel(boolean forceQryCancel) {
+ if (cancelled)
+ return;
+
+ cancelled = true;
+
+ for (int i = 0; i < results.length(); i++) {
+ MapQueryResult res = results.get(i);
+
+ if (res != null) {
+ res.close();
+
+ continue;
+ }
+
+ if (forceQryCancel) {
+ GridQueryCancel cancel = cancels[i];
+
+ if (cancel != null)
+ cancel.cancel();
+ }
+ }
+ }
+
+ /**
+ * @return Cancel flag.
+ */
+ boolean cancelled() {
+ return cancelled;
+ }
+
+ /**
+ * @return Query request ID.
+ */
+ long queryRequestId() {
+ return qryReqId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
new file mode 100644
index 0000000..dd8237b
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
@@ -0,0 +1,38 @@
+/*
+ * 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.twostep;
+
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
+
+/**
+ * Mapper fake reservation object for replicated caches.
+ */
+class MapReplicatedReservation implements GridReservable {
+ /** */
+ static final MapReplicatedReservation INSTANCE = new MapReplicatedReservation();
+
+ /** {@inheritDoc} */
+ @Override public boolean reserve() {
+ throw new IllegalStateException();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void release() {
+ throw new IllegalStateException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
new file mode 100644
index 0000000..6feb8ea
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
@@ -0,0 +1,65 @@
+/*
+ * 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.twostep;
+
+/**
+ * Mapper request key.
+ */
+class MapRequestKey {
+ /** */
+ private long reqId;
+
+ /** */
+ private int segmentId;
+
+ /** Constructor */
+ MapRequestKey(long reqId, int segmentId) {
+ this.reqId = reqId;
+ this.segmentId = segmentId;
+ }
+
+ /**
+ * @return Request ID.
+ */
+ public long requestId() {
+ return reqId;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ MapRequestKey other = (MapRequestKey)o;
+
+ return reqId == other.reqId && segmentId == other.segmentId;
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = (int)(reqId ^ (reqId >>> 32));
+
+ res = 31 * res + segmentId;
+
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/879f1910/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
new file mode 100644
index 0000000..9d2d7ba
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
@@ -0,0 +1,73 @@
+/*
+ * 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.twostep;
+
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Mapper reservation key.
+ */
+public class MapReservationKey {
+ /** Cache name. */
+ private final String cacheName;
+
+ /** Topology version. */
+ private final AffinityTopologyVersion topVer;
+
+ /**
+ * Constructor.
+ *
+ * @param cacheName Cache name.
+ * @param topVer Topology version.
+ */
+ public MapReservationKey(String cacheName, AffinityTopologyVersion topVer) {
+ this.cacheName = cacheName;
+ this.topVer = topVer;
+ }
+
+ /**
+ * @return Cache name.
+ */
+ public String cacheName() {
+ return cacheName;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ MapReservationKey other = (MapReservationKey)o;
+
+ return F.eq(cacheName, other.cacheName) && F.eq(topVer, other.topVer);
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ int res = cacheName != null ? cacheName.hashCode() : 0;
+
+ res = 31 * res + (topVer != null ? topVer.hashCode() : 0);
+
+ return res;
+ }
+}
[17/29] ignite git commit: IGNITE-6012 Refactored
GridJettyRestHandler.processRequest(): replace mapper.writeValueAsString with
writeValue(stream, v). (cherry picked from commit 3a390c8)
Posted by nt...@apache.org.
IGNITE-6012 Refactored GridJettyRestHandler.processRequest(): replace mapper.writeValueAsString with writeValue(stream, v).
(cherry picked from commit 3a390c8)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8b246194
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8b246194
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8b246194
Branch: refs/heads/ignite-5947
Commit: 8b2461942c18f228c0107020aa28c03711bdceda
Parents: 5c20978
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Aug 11 11:07:26 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Aug 11 11:22:27 2017 +0700
----------------------------------------------------------------------
.../http/jetty/GridJettyRestHandler.java | 31 +++++++-------------
1 file changed, 10 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/8b246194/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
----------------------------------------------------------------------
diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
index c864a10..327c13a 100644
--- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
+++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java
@@ -34,6 +34,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -356,41 +357,29 @@ public class GridJettyRestHandler extends AbstractHandler {
U.error(log, "Failed to process HTTP request [action=" + act + ", req=" + req + ']', e);
- cmdRes = new GridRestResponse(STATUS_FAILED, e.getMessage());
-
if (e instanceof Error)
throw (Error)e;
- }
-
- String json;
- try {
- json = jsonMapper.writeValueAsString(cmdRes);
+ cmdRes = new GridRestResponse(STATUS_FAILED, e.getMessage());
}
- catch (JsonProcessingException e1) {
- U.error(log, "Failed to convert response to JSON: " + cmdRes, e1);
- GridRestResponse resFailed = new GridRestResponse(STATUS_FAILED, e1.getMessage());
+ try {
+ ServletOutputStream os = res.getOutputStream();
try {
- json = jsonMapper.writeValueAsString(resFailed);
+ jsonMapper.writeValue(os, cmdRes);
}
- catch (JsonProcessingException e2) {
- json = "{\"successStatus\": \"1\", \"error:\" \"" + e2.getMessage() + "\"}}";
- }
- }
-
- try {
- if (log.isDebugEnabled())
- log.debug("Parsed command response into JSON object: " + json);
+ catch (JsonProcessingException e) {
+ U.error(log, "Failed to convert response to JSON: " + cmdRes, e);
- res.getWriter().write(json);
+ jsonMapper.writeValue(os, F.asMap("successStatus", STATUS_FAILED, "error", e.getMessage()));
+ }
if (log.isDebugEnabled())
log.debug("Processed HTTP request [action=" + act + ", jsonRes=" + cmdRes + ", req=" + req + ']');
}
catch (IOException e) {
- U.error(log, "Failed to send HTTP response: " + json, e);
+ U.error(log, "Failed to send HTTP response: " + cmdRes, e);
}
}
[04/29] ignite git commit: Merge branch ignite-2.1.3 into ignite-2.1.4
Posted by nt...@apache.org.
Merge branch ignite-2.1.3 into ignite-2.1.4
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/772d462b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/772d462b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/772d462b
Branch: refs/heads/ignite-5947
Commit: 772d462b68c7de8517d1f61e2e05ec8eefb18eac
Parents: e255a56 6bdad4d
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Aug 3 11:55:15 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Aug 3 11:55:15 2017 +0700
----------------------------------------------------------------------
.../apache/ignite/IgniteSystemProperties.java | 6 +
.../IgniteDiagnosticPrepareContext.java | 3 +-
.../apache/ignite/internal/IgniteKernal.java | 3 +-
.../mem/file/MappedFileMemoryProvider.java | 3 +-
.../GridCachePartitionExchangeManager.java | 2 +-
.../processors/cache/GridCacheProcessor.java | 16 +-
.../processors/cache/GridCacheUtils.java | 7 +-
.../cache/IgniteCacheOffheapManagerImpl.java | 26 ++-
.../processors/cache/IgniteCacheProxyImpl.java | 24 ++-
.../GridDhtPartitionsExchangeFuture.java | 20 +-
.../GridCacheDatabaseSharedManager.java | 7 +-
.../persistence/freelist/FreeListImpl.java | 18 +-
.../wal/FileWriteAheadLogManager.java | 37 +++-
.../reader/StandaloneWalRecordsIterator.java | 4 +-
.../cluster/GridClusterStateProcessor.java | 3 +-
.../datastructures/GridCacheLockImpl.java | 13 +-
.../processors/odbc/SqlListenerProcessor.java | 3 +-
.../ignite/internal/util/nio/GridNioServer.java | 7 +-
.../internal/visor/debug/VisorThreadInfo.java | 10 +-
.../internal/visor/query/VisorQueryTask.java | 2 +-
.../visor/query/VisorScanQueryTask.java | 2 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 38 ++--
.../cache/store/jdbc/model/BinaryTest.java | 1 -
.../processors/cache/IgniteCacheGroupsTest.java | 22 +-
.../IgnitePdsCacheRebalancingAbstractTest.java | 2 +
.../TxOptimisticDeadlockDetectionTest.java | 2 +
.../ignite/tests/p2p/JobStealingTask.java | 12 +-
.../org/apache/ignite/tests/p2p/NodeFilter.java | 30 +++
.../hadoop/jobtracker/HadoopJobTracker.java | 24 ++-
.../hadoop/shuffle/HadoopShuffleJob.java | 5 +-
.../processors/query/h2/IgniteH2Indexing.java | 21 +-
.../cache/index/H2DynamicTableSelfTest.java | 32 +++
.../apache/ignite/stream/mqtt/MqttStreamer.java | 6 +-
.../include/ignite/binary/binary_writer.h | 4 +-
.../ignite/impl/binary/binary_reader_impl.h | 50 +++--
.../ignite/impl/binary/binary_type_impl.h | 67 ++++++
.../ignite/impl/binary/binary_writer_impl.h | 43 ++--
.../src/impl/binary/binary_reader_impl.cpp | 63 +++---
.../src/impl/binary/binary_writer_impl.cpp | 41 ++--
.../core-test/config/cache-query-default.xml | 29 +++
.../src/binary_reader_writer_raw_test.cpp | 36 ++++
.../core-test/src/binary_reader_writer_test.cpp | 135 +++++++++---
.../cpp/core-test/src/cache_query_test.cpp | 215 ++++++++++++++++++-
.../cpp/core-test/src/cluster_test.cpp | 13 ++
.../ignite/cache/query/query_fields_row.h | 28 +++
.../ignite/cache/query/query_sql_fields.h | 13 +-
.../platforms/cpp/core/include/ignite/ignite.h | 15 ++
.../ignite/impl/cache/query/query_argument.h | 63 ++++++
.../impl/cache/query/query_fields_row_impl.h | 29 +++
.../ignite/impl/cluster/cluster_group_impl.h | 15 ++
.../cpp/core/include/ignite/impl/ignite_impl.h | 24 ++-
modules/platforms/cpp/core/src/ignite.cpp | 10 +
.../src/impl/cluster/cluster_group_impl.cpp | 26 ++-
.../platforms/cpp/core/src/impl/ignite_impl.cpp | 4 +
.../spi/deployment/uri/UriDeploymentSpi.java | 3 +-
modules/web-console/backend/app/mongo.js | 2 +-
modules/web-console/backend/app/settings.js | 3 +-
modules/web-console/backend/index.js | 16 +-
modules/web-console/backend/middlewares/api.js | 39 ++--
.../web-console/backend/services/activities.js | 12 +-
modules/web-console/frontend/app/app.js | 10 +-
.../components/grid-item-selected/component.js | 28 +++
.../components/grid-item-selected/controller.js | 38 ++++
.../app/components/grid-item-selected/index.js | 24 +++
.../components/grid-item-selected/template.pug | 17 ++
.../list-of-registered-users.tpl.pug | 4 +-
.../app/components/ui-grid-hovering/cell.js | 48 +++++
.../app/components/ui-grid-hovering/hovering.js | 31 +++
.../app/components/ui-grid-hovering/index.js | 30 +++
.../app/components/ui-grid-hovering/style.scss | 22 ++
.../app/components/ui-grid-hovering/viewport.js | 42 ++++
.../frontend/app/controllers/auth.controller.js | 9 +-
.../app/modules/agent/AgentManager.service.js | 24 +--
.../app/modules/agent/AgentModal.service.js | 8 +-
.../configuration/generator/Maven.service.js | 13 +-
.../frontend/app/modules/demo/Demo.module.js | 22 +-
.../frontend/app/modules/sql/sql.controller.js | 11 +-
.../states/configuration/clusters/hadoop.pug | 2 +-
.../configuration/summary/summary.worker.js | 4 +-
.../frontend/app/modules/states/errors.state.js | 2 +-
.../app/modules/states/password.state.js | 2 +
.../app/modules/states/profile.state.js | 2 +-
.../frontend/app/modules/states/signin.state.js | 6 +-
.../app/modules/user/AclRoute.provider.js | 50 -----
.../frontend/app/modules/user/user.module.js | 35 ++-
.../frontend/app/services/Messages.service.js | 7 +
.../web-console/frontend/views/signin.tpl.pug | 2 +-
.../views/templates/agent-download.tpl.pug | 2 -
88 files changed, 1480 insertions(+), 424 deletions(-)
----------------------------------------------------------------------
[09/29] ignite git commit: Merge branch ignite-2.1.3 into
ignite-2.1.4.
Posted by nt...@apache.org.
Merge branch ignite-2.1.3 into ignite-2.1.4.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4f025044
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4f025044
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4f025044
Branch: refs/heads/ignite-5947
Commit: 4f02504475fd1e5cc3b9f4754856e44d20fdc1cb
Parents: 4e0385f 0eedf46
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Aug 7 09:41:22 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Aug 7 09:41:22 2017 +0700
----------------------------------------------------------------------
.../binary/datagrid/CacheClientBinaryQueryExample.java | 3 +++
.../hide-on-state-change/hide-on-state-change.directive.js | 8 ++------
modules/web-console/frontend/views/index.pug | 8 ++++++++
3 files changed, 13 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
[13/29] ignite git commit: IGNITE-5452: GridTimeoutProcessor can hang
on stop. This closes #2279.
Posted by nt...@apache.org.
IGNITE-5452: GridTimeoutProcessor can hang on stop. This closes #2279.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ab18fdfc
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ab18fdfc
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ab18fdfc
Branch: refs/heads/ignite-5947
Commit: ab18fdfcc4f6db1e54fb1f3b68ba7fbc31a7f6e7
Parents: 7c77b86
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Fri Jul 14 20:14:47 2017 +0300
Committer: Denis Mekhanikov <dm...@gmail.com>
Committed: Wed Aug 9 13:38:58 2017 +0300
----------------------------------------------------------------------
.../timeout/GridTimeoutProcessor.java | 18 +-
.../IgniteTxRemoveTimeoutObjectsTest.java | 194 +++++++++++++++++++
.../timeout/GridTimeoutProcessorSelfTest.java | 68 +++++--
.../testsuites/IgniteCacheTestSuite3.java | 4 +-
4 files changed, 265 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ab18fdfc/modules/core/src/main/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessor.java
index 9deca9a..8c71f76 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessor.java
@@ -37,7 +37,7 @@ import org.apache.ignite.thread.IgniteThread;
*/
public class GridTimeoutProcessor extends GridProcessorAdapter {
/** */
- private final IgniteThread timeoutWorker;
+ private final TimeoutWorker timeoutWorker;
/** Time-based sorted set for timeout objects. */
private final GridConcurrentSkipListSet<GridTimeoutObject> timeoutObjs =
@@ -62,13 +62,12 @@ public class GridTimeoutProcessor extends GridProcessorAdapter {
public GridTimeoutProcessor(GridKernalContext ctx) {
super(ctx);
- timeoutWorker = new IgniteThread(ctx.config().getIgniteInstanceName(), "grid-timeout-worker",
- new TimeoutWorker());
+ timeoutWorker = new TimeoutWorker();
}
/** {@inheritDoc} */
@Override public void start() {
- timeoutWorker.start();
+ new IgniteThread(timeoutWorker).start();
if (log.isDebugEnabled())
log.debug("Timeout processor started.");
@@ -76,7 +75,7 @@ public class GridTimeoutProcessor extends GridProcessorAdapter {
/** {@inheritDoc} */
@Override public void stop(boolean cancel) throws IgniteCheckedException {
- U.interrupt(timeoutWorker);
+ timeoutWorker.cancel();
U.join(timeoutWorker);
if (log.isDebugEnabled())
@@ -159,6 +158,13 @@ public class GridTimeoutProcessor extends GridProcessorAdapter {
timeoutObj.onTimeout();
}
catch (Throwable e) {
+ if (isCancelled() && !(e instanceof Error)){
+ if (log.isDebugEnabled())
+ log.debug("Error when executing timeout callback: " + timeoutObj);
+
+ return;
+ }
+
U.error(log, "Error when executing timeout callback: " + timeoutObj, e);
if (e instanceof Error)
@@ -170,7 +176,7 @@ public class GridTimeoutProcessor extends GridProcessorAdapter {
}
synchronized (mux) {
- while (true) {
+ while (!isCancelled()) {
// Access of the first element must be inside of
// synchronization block, so we don't miss out
// on thread notification events sent from
http://git-wip-us.apache.org/repos/asf/ignite/blob/ab18fdfc/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteTxRemoveTimeoutObjectsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteTxRemoveTimeoutObjectsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteTxRemoveTimeoutObjectsTest.java
new file mode 100644
index 0000000..c0f9940
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteTxRemoveTimeoutObjectsTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.cache.distributed;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.transactions.Transaction;
+import org.apache.ignite.transactions.TransactionTimeoutException;
+
+import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
+import static org.apache.ignite.transactions.TransactionIsolation.SERIALIZABLE;
+
+/**
+ * Test correctness of rollback a transaction with timeout during the grid stop.
+ */
+public class IgniteTxRemoveTimeoutObjectsTest extends GridCacheAbstractSelfTest {
+ /** */
+ private static final int PUT_CNT = 1000;
+
+ /** {@inheritDoc} */
+ @Override protected int gridCount() {
+ return 3;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 60_000;
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testTxRemoveTimeoutObjects() throws Exception {
+ IgniteCache<Integer, Integer> cache0 = grid(0).cache(DEFAULT_CACHE_NAME);
+ IgniteCache<Integer, Integer> cache1 = grid(1).cache(DEFAULT_CACHE_NAME);
+
+ // start additional grid to be closed.
+ IgniteCache<Integer, Integer> cacheAdditional = startGrid(gridCount()).cache(DEFAULT_CACHE_NAME);
+
+ for (int i = 0; i < PUT_CNT; i++)
+ cache0.put(i, Integer.MAX_VALUE);
+
+ logTimeoutObjectsFrequency();
+
+ info("Tx1 started");
+ try (Transaction tx = grid(gridCount()).transactions().txStart(PESSIMISTIC, SERIALIZABLE, 100, PUT_CNT)) {
+ try {
+ for (int i = 0; i < PUT_CNT; i++) {
+ cacheAdditional.put(i, Integer.MIN_VALUE);
+
+ if (i % 100 == 0)
+ logTimeoutObjectsFrequency();
+ }
+
+ U.sleep(200);
+
+ tx.commit();
+
+ fail("A timeout should have happened.");
+ }
+ catch (Exception e) {
+ assertTrue(X.hasCause(e, TransactionTimeoutException.class));
+ }
+ }
+
+ assertDoesNotContainLockTimeoutObjects();
+
+ logTimeoutObjectsFrequency();
+
+ stopGrid(gridCount());
+
+ awaitPartitionMapExchange();
+
+ info("Grid2 closed.");
+
+ assertDoesNotContainLockTimeoutObjects();
+
+ logTimeoutObjectsFrequency();
+
+ // Check that the values have not changed and lock can be acquired.
+ try (Transaction tx2 = grid(1).transactions().txStart(PESSIMISTIC, SERIALIZABLE)) {
+ info("Tx2 started");
+
+ for (int i = 0; i < PUT_CNT; i++) {
+ assertEquals(cache1.get(i).intValue(), Integer.MAX_VALUE);
+ cache1.put(i, i);
+
+ if (i % (PUT_CNT / 5) == 0)
+ logTimeoutObjectsFrequency();
+ }
+
+ tx2.commit();
+ }
+
+ info("Tx2 stopped");
+
+ // Check that that changes committed.
+ for (int i = 0; i < PUT_CNT; i++)
+ assertEquals(cache0.get(i).intValue(), i);
+ }
+
+ /**
+ * Fails if at least one grid contains LockTimeoutObjects.
+ */
+ private void assertDoesNotContainLockTimeoutObjects() {
+ for (Ignite ignite : G.allGrids()) {
+ for (GridTimeoutObject object : getTimeoutObjects((IgniteEx)ignite)) {
+ if (object.getClass().getSimpleName().equals("LockTimeoutObject"))
+ fail("Grids contain LockTimeoutObjects.");
+ }
+ }
+ }
+
+ /**
+ * Print the number of each timeout object type on each grid to the log.
+ */
+ private void logTimeoutObjectsFrequency() {
+ StringBuilder sb = new StringBuilder("Timeout objects frequency [");
+
+ for (Ignite ignite : G.allGrids()) {
+ IgniteEx igniteEx = (IgniteEx)ignite;
+
+ Map<String, Integer> objFreqMap = new HashMap<>();
+
+ Set<GridTimeoutObject> objs = getTimeoutObjects(igniteEx);
+
+ for (GridTimeoutObject obj : objs) {
+ String clsName = obj.getClass().getSimpleName();
+
+ Integer cnt = objFreqMap.get(clsName);
+
+ if (cnt == null)
+ objFreqMap.put(clsName, 1);
+ else
+ objFreqMap.put(clsName, cnt + 1);
+ }
+
+ sb.append("[")
+ .append(igniteEx.name()).append(": size=")
+ .append(objs.size()).append(", ");
+
+ for (Map.Entry<String, Integer> entry : objFreqMap.entrySet()) {
+ sb.append(entry.getKey()).append("=")
+ .append(entry.getValue())
+ .append(", ");
+ }
+
+ sb.delete(sb.length() - 2, sb.length())
+ .append("]; ");
+ }
+
+ sb.delete(sb.length() - 2, sb.length())
+ .append("]");
+
+ info(sb.toString()
+ .replaceAll("distributed.IgniteTxRollbackOnStopTest", "Grid"));
+ }
+
+ /**
+ * @param igniteEx IgniteEx.
+ * @return Set of timeout objects that process on current IgniteEx.
+ */
+ private Set<GridTimeoutObject> getTimeoutObjects(IgniteEx igniteEx) {
+ GridTimeoutProcessor timeout = igniteEx.context().timeout();
+
+ return GridTestUtils.getFieldValue(timeout, timeout.getClass(), "timeoutObjs");
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/ab18fdfc/modules/core/src/test/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessorSelfTest.java
index eb248cf..606b102 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessorSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/timeout/GridTimeoutProcessorSelfTest.java
@@ -41,6 +41,11 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
private GridTestKernalContext ctx;
/** {@inheritDoc} */
+ @Override protected long getTestTimeout() {
+ return 60_000;
+ }
+
+ /** {@inheritDoc} */
@Override protected void beforeTest() throws Exception {
ctx = newContext();
@@ -84,7 +89,9 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
}
/** {@inheritDoc} */
- @Override public long endTime() { return endTime; }
+ @Override public long endTime() {
+ return endTime;
+ }
/** {@inheritDoc} */
@Override public void onTimeout() {
@@ -152,10 +159,14 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
private final long endTime = System.currentTimeMillis() + RAND.nextInt(1000) + 500;
/** {@inheritDoc} */
- @Override public IgniteUuid timeoutId() { return id; }
+ @Override public IgniteUuid timeoutId() {
+ return id;
+ }
/** {@inheritDoc} */
- @Override public long endTime() { return endTime; }
+ @Override public long endTime() {
+ return endTime;
+ }
/** {@inheritDoc} */
@Override public void onTimeout() {
@@ -307,9 +318,8 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
assert timeObjs.size() == max;
// Remove timeout objects so that they aren't able to times out (supposing the cycle takes less than 500 ms).
- for (GridTimeoutObject obj : timeObjs) {
+ for (GridTimeoutObject obj : timeObjs)
ctx.timeout().removeTimeoutObject(obj);
- }
Thread.sleep(1000);
@@ -350,7 +360,9 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
}
/** {@inheritDoc} */
- @Override public long endTime() { return endTime; }
+ @Override public long endTime() {
+ return endTime;
+ }
/** {@inheritDoc} */
@Override public void onTimeout() {
@@ -370,9 +382,8 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
// Remove timeout objects so that they aren't able to times out
// (supposing the cycle takes less than 500 ms).
- for (GridTimeoutObject obj : timeObjs) {
+ for (GridTimeoutObject obj : timeObjs)
ctx.timeout().removeTimeoutObject(obj);
- }
}
}, threads, "timeout-test-worker");
@@ -381,6 +392,9 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
assert callCnt.get() == 0;
}
+ /**
+ * @throws Exception If test failed.
+ */
public void testAddRemoveInterleaving() throws Exception {
final AtomicInteger callCnt = new AtomicInteger(0);
@@ -430,9 +444,8 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
// Remove timeout objects so that they aren't able to times out
// (supposing the cycle takes less than 500 ms).
- for (GridTimeoutObject obj : timeObjs) {
+ for (GridTimeoutObject obj : timeObjs)
ctx.timeout().removeTimeoutObject(obj);
- }
}
}, 100, "timeout-test-worker");
@@ -516,10 +529,14 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
private int cnt;
/** {@inheritDoc} */
- @Override public IgniteUuid timeoutId() { return id; }
+ @Override public IgniteUuid timeoutId() {
+ return id;
+ }
/** {@inheritDoc} */
- @Override public long endTime() { return endTime; }
+ @Override public long endTime() {
+ return endTime;
+ }
/** {@inheritDoc} */
@Override public void onTimeout() {
@@ -608,4 +625,31 @@ public class GridTimeoutProcessorSelfTest extends GridCommonAbstractTest {
assert latch.await(3000, MILLISECONDS);
}
+
+ /**
+ * Test that eaten {@link InterruptedException} will not hang on the closing of the grid.
+ *
+ * @throws Exception If test failed.
+ */
+ public void testCancelingWithClearedInterruptedFlag() throws Exception {
+ final CountDownLatch onTimeoutCalled = new CountDownLatch(1);
+
+ ctx.timeout().addTimeoutObject(new GridTimeoutObjectAdapter(10) {
+ /** {@inheritDoc} */
+ @Override public void onTimeout() {
+ try {
+ onTimeoutCalled.countDown();
+
+ // Wait for CacheProcessor has stopped and cause InterruptedException
+ // which clears interrupted flag.
+ Thread.sleep(Long.MAX_VALUE);
+ }
+ catch (InterruptedException ignore) {
+ // No-op.
+ }
+ }
+ });
+
+ onTimeoutCalled.await();
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/ab18fdfc/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index 58e9dc3..a6be07e 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -36,9 +36,9 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheGroupsTest;
import org.apache.ignite.internal.processors.cache.IgniteCacheInterceptorSelfTestSuite;
import org.apache.ignite.internal.processors.cache.IgniteCacheScanPredicateDeploymentSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.CacheAsyncOperationsTest;
-import org.apache.ignite.internal.processors.cache.distributed.CacheGroupsPreloadTest;
import org.apache.ignite.internal.processors.cache.distributed.GridCacheMixedModeSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.IgniteTxGetAfterStopTest;
+import org.apache.ignite.internal.processors.cache.distributed.IgniteTxRemoveTimeoutObjectsTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridCacheDaemonNodePartitionedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridCachePartitionedOnlyP2PDisabledByteArrayValuesSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridCachePartitionedOnlyP2PEnabledByteArrayValuesSelfTest;
@@ -199,6 +199,8 @@ public class IgniteCacheTestSuite3 extends TestSuite {
suite.addTestSuite(CacheAsyncOperationsTest.class);
+ suite.addTestSuite(IgniteTxRemoveTimeoutObjectsTest.class);
+
return suite;
}
}
[23/29] ignite git commit: GG-12629 Backport IGNITE-5961 to 8.1.4
Posted by nt...@apache.org.
GG-12629 Backport IGNITE-5961 to 8.1.4
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2f38065c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2f38065c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2f38065c
Branch: refs/heads/ignite-5947
Commit: 2f38065cd10fd61d51771d14188380dc7cc74ed7
Parents: c23a2dc
Author: Ivan Rakov <iv...@gmail.com>
Authored: Mon Aug 14 16:44:50 2017 +0300
Committer: Ivan Rakov <iv...@gmail.com>
Committed: Mon Aug 14 16:45:26 2017 +0300
----------------------------------------------------------------------
.../internal/pagemem/store/PageStore.java | 5 +
.../cache/persistence/file/FilePageStore.java | 56 +++++----
.../persistence/file/FilePageStoreFactory.java | 35 ++++++
.../persistence/file/FilePageStoreManager.java | 17 +--
.../cache/persistence/file/FilePageStoreV2.java | 53 +++++++++
.../file/FileVersionCheckingFactory.java | 116 +++++++++++++++++++
...gnitePdsRecoveryAfterFileCorruptionTest.java | 2 +-
7 files changed, 252 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
index 4698a6b..f6e577c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
@@ -95,4 +95,9 @@ public interface PageStore {
* @throws IgniteCheckedException If sync failed (IO error occurred).
*/
public void ensure() throws IgniteCheckedException;
+
+ /**
+ * @return Page store version.
+ */
+ public int version();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
index a7ca13c..e6c5379 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
@@ -45,10 +45,10 @@ public class FilePageStore implements PageStore {
private static final long SIGNATURE = 0xF19AC4FE60C530B8L;
/** File version. */
- private static final int VERSION = 1;
+ public static final int VERSION = 1;
/** Allocated field offset. */
- public static final int HEADER_SIZE = 8/*SIGNATURE*/ + 4/*VERSION*/ + 1/*type*/ + 4/*page size*/;
+ static final int HEADER_SIZE = 8/*SIGNATURE*/ + 4/*VERSION*/ + 1/*type*/ + 4/*page size*/;
/** */
private final File cfgFile;
@@ -57,7 +57,7 @@ public class FilePageStore implements PageStore {
private final byte type;
/** Database configuration. */
- private final MemoryConfiguration dbCfg;
+ protected final MemoryConfiguration dbCfg;
/** Factory to provide I/O interfaces for read/write operations with files */
private final FileIOFactory ioFactory;
@@ -103,20 +103,36 @@ public class FilePageStore implements PageStore {
/** {@inheritDoc} */
@Override public boolean exists() {
- return cfgFile.exists() && cfgFile.length() > HEADER_SIZE;
+ return cfgFile.exists() && cfgFile.length() > headerSize();
}
/**
+ * Size of page store header.
+ */
+ public int headerSize() {
+ return HEADER_SIZE;
+ }
+
+ /**
+ * Page store version.
+ */
+ public int version() {
+ return VERSION;
+ }
+
+ /**
+ * Creates header for current version file store. Doesn't init the store.
+ *
* @param type Type.
* @param pageSize Page size.
* @return Byte buffer instance.
*/
- public static ByteBuffer header(byte type, int pageSize) {
- ByteBuffer hdr = ByteBuffer.allocate(HEADER_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+ public ByteBuffer header(byte type, int pageSize) {
+ ByteBuffer hdr = ByteBuffer.allocate(headerSize()).order(ByteOrder.LITTLE_ENDIAN);
hdr.putLong(SIGNATURE);
- hdr.putInt(VERSION);
+ hdr.putInt(version());
hdr.put(type);
@@ -142,7 +158,7 @@ public class FilePageStore implements PageStore {
}
//there is 'super' page in every file
- return HEADER_SIZE + dbCfg.getPageSize();
+ return headerSize() + dbCfg.getPageSize();
}
/**
@@ -150,7 +166,7 @@ public class FilePageStore implements PageStore {
*/
private long checkFile() throws IgniteCheckedException {
try {
- ByteBuffer hdr = ByteBuffer.allocate(HEADER_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+ ByteBuffer hdr = ByteBuffer.allocate(headerSize()).order(ByteOrder.LITTLE_ENDIAN);
while (hdr.remaining() > 0)
fileIO.read(hdr);
@@ -166,9 +182,9 @@ public class FilePageStore implements PageStore {
int ver = hdr.getInt();
- if (VERSION != ver)
+ if (version() != ver)
throw new IgniteCheckedException("Failed to verify store file (invalid file version)" +
- " [expectedVersion=" + VERSION +
+ " [expectedVersion=" + version() +
", fileVersion=" + ver + "]");
byte type = hdr.get();
@@ -187,10 +203,10 @@ public class FilePageStore implements PageStore {
long fileSize = cfgFile.length();
- if (fileSize == HEADER_SIZE) // Every file has a special meta page.
- fileSize = pageSize + HEADER_SIZE;
+ if (fileSize == headerSize()) // Every file has a special meta page.
+ fileSize = pageSize + headerSize();
- if ((fileSize - HEADER_SIZE) % pageSize != 0)
+ if ((fileSize - headerSize()) % pageSize != 0)
throw new IgniteCheckedException("Failed to verify store file (invalid file size)" +
" [fileSize=" + U.hexLong(fileSize) +
", pageSize=" + U.hexLong(pageSize) + ']');
@@ -346,9 +362,9 @@ public class FilePageStore implements PageStore {
init();
try {
- assert buf.remaining() == HEADER_SIZE;
+ assert buf.remaining() == headerSize();
- int len = HEADER_SIZE;
+ int len = headerSize();
long off = 0;
@@ -425,7 +441,7 @@ public class FilePageStore implements PageStore {
long off = pageOffset(pageId);
- assert (off >= 0 && off + pageSize <= allocated.get() + HEADER_SIZE) || recover :
+ assert (off >= 0 && off + pageSize <= allocated.get() + headerSize()) || recover :
"off=" + U.hexLong(off) + ", allocated=" + U.hexLong(allocated.get()) + ", pageId=" + U.hexLong(pageId);
assert pageBuf.capacity() == pageSize;
@@ -463,7 +479,7 @@ public class FilePageStore implements PageStore {
/** {@inheritDoc} */
@Override public long pageOffset(long pageId) {
- return (long) PageIdUtils.pageIndex(pageId) * pageSize + HEADER_SIZE;
+ return (long) PageIdUtils.pageIndex(pageId) * pageSize + headerSize();
}
/** {@inheritDoc} */
@@ -494,7 +510,7 @@ public class FilePageStore implements PageStore {
long off = allocPage();
- return off / pageSize;
+ return (off - headerSize()) / pageSize;
}
/**
@@ -519,6 +535,6 @@ public class FilePageStore implements PageStore {
if (!inited)
return 0;
- return (int)(allocated.get() / pageSize);
+ return (int)(allocated.get() - headerSize()) / pageSize;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
new file mode 100644
index 0000000..d97ab26
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
@@ -0,0 +1,35 @@
+/*
+* 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.cache.persistence.file;
+
+import java.io.File;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageIdAllocator;
+
+/**
+ *
+ */
+public interface FilePageStoreFactory {
+ /**
+ * Creates instance of FilePageStore based on given file.
+ *
+ * @param type Data type, can be {@link PageIdAllocator#FLAG_IDX} or {@link PageIdAllocator#FLAG_DATA}.
+ * @param file File Page store file.
+ */
+ public FilePageStore createPageStore(byte type, File file) throws IgniteCheckedException;
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index e2ad070..0041ea6 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -365,21 +365,16 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
if (dirExisted && !idxFile.exists())
grpsWithoutIdx.add(grpDesc.groupId());
- FilePageStore idxStore = new FilePageStore(
- PageMemory.FLAG_IDX,
- idxFile,
- pstCfg.getFileIOFactory(),
- cctx.kernalContext().config().getMemoryConfiguration());
+ FileVersionCheckingFactory pageStoreFactory = new FileVersionCheckingFactory(
+ pstCfg.getFileIOFactory(), igniteCfg.getMemoryConfiguration());
+
+ FilePageStore idxStore = pageStoreFactory.createPageStore(PageMemory.FLAG_IDX, idxFile);
FilePageStore[] partStores = new FilePageStore[grpDesc.config().getAffinity().partitions()];
for (int partId = 0; partId < partStores.length; partId++) {
- FilePageStore partStore = new FilePageStore(
- PageMemory.FLAG_DATA,
- new File(cacheWorkDir, String.format(PART_FILE_TEMPLATE, partId)),
- pstCfg.getFileIOFactory(),
- cctx.kernalContext().config().getMemoryConfiguration()
- );
+ FilePageStore partStore = pageStoreFactory.createPageStore(
+ PageMemory.FLAG_DATA, new File(cacheWorkDir, String.format(PART_FILE_TEMPLATE, partId)));
partStores[partId] = partStore;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
new file mode 100644
index 0000000..5d044ec
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
@@ -0,0 +1,53 @@
+/*
+* 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.cache.persistence.file;
+
+import java.io.File;
+import org.apache.ignite.configuration.MemoryConfiguration;
+
+/**
+ *
+ */
+public class FilePageStoreV2 extends FilePageStore {
+ /** File version. */
+ public static final int VERSION = 2;
+
+ /** Header size. */
+ private final int hdrSize;
+
+ /**
+ * @param type Type.
+ * @param file File.
+ * @param factory Factory.
+ * @param cfg Config.
+ */
+ public FilePageStoreV2(byte type, File file, FileIOFactory factory, MemoryConfiguration cfg) {
+ super(type, file, factory, cfg);
+
+ hdrSize = cfg.getPageSize();
+ }
+
+ /** {@inheritDoc} */
+ @Override public int headerSize() {
+ return hdrSize;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int version() {
+ return VERSION;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
new file mode 100644
index 0000000..53bd802
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
@@ -0,0 +1,116 @@
+/*
+* 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.cache.persistence.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.MemoryConfiguration;
+
+/**
+ * Checks version in files if it's present on the disk, creates store with latest version otherwise.
+ */
+public class FileVersionCheckingFactory implements FilePageStoreFactory {
+ /** Property to override latest version. Should be used only in tests. */
+ public static final String LATEST_VERSION_OVERRIDE_PROPERTY = "file.page.store.latest.version.override";
+
+ /** Latest page store version. */
+ public final static int LATEST_VERSION = 2;
+
+ /** Factory to provide I/O interfaces for read/write operations with files. */
+ private final FileIOFactory fileIOFactory;
+
+ /** Memory configuration. */
+ private final MemoryConfiguration memCfg;
+
+ /**
+ * @param fileIOFactory File io factory.
+ * @param memCfg Memory configuration.
+ */
+ public FileVersionCheckingFactory(
+ FileIOFactory fileIOFactory, MemoryConfiguration memCfg) {
+ this.fileIOFactory = fileIOFactory;
+ this.memCfg = memCfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public FilePageStore createPageStore(byte type, File file) throws IgniteCheckedException {
+ if (!file.exists())
+ return createPageStore(type, file, latestVersion());
+
+ try (FileIO fileIO = fileIOFactory.create(file, "r")) {
+ int minHdr = FilePageStore.HEADER_SIZE;
+
+ if (fileIO.size() < minHdr)
+ return createPageStore(type, file, latestVersion());
+
+ ByteBuffer hdr = ByteBuffer.allocate(minHdr).order(ByteOrder.LITTLE_ENDIAN);
+
+ while (hdr.remaining() > 0)
+ fileIO.read(hdr);
+
+ hdr.rewind();
+
+ hdr.getLong(); // Read signature
+
+ int ver = hdr.getInt();
+
+ return createPageStore(type, file, ver);
+ }
+ catch (IOException e) {
+ throw new IgniteCheckedException("Error while creating file page store [file=" + file + "]:", e);
+ }
+ }
+
+ /**
+ * Resolves latest page store version.
+ */
+ public int latestVersion() {
+ int latestVer = LATEST_VERSION;
+
+ try {
+ latestVer = Integer.parseInt(System.getProperty(LATEST_VERSION_OVERRIDE_PROPERTY));
+ } catch (NumberFormatException e) {
+ // No override.
+ }
+
+ return latestVer;
+ }
+
+ /**
+ * Instantiates specific version of FilePageStore.
+ *
+ * @param type Type.
+ * @param file File.
+ * @param ver Version.
+ */
+ public FilePageStore createPageStore(byte type, File file, int ver) throws IgniteCheckedException {
+ switch (ver) {
+ case FilePageStore.VERSION:
+ return new FilePageStore(type, file, fileIOFactory, memCfg);
+
+ case FilePageStoreV2.VERSION:
+ return new FilePageStoreV2(type, file, fileIOFactory, memCfg);
+
+ default:
+ throw new IllegalArgumentException("Unknown version of file page store: " + ver);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/2f38065c/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
index c248c35..11d5eef 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
@@ -194,7 +194,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
long size = fileIO.size();
- fileIO.write(ByteBuffer.allocate((int)size - FilePageStore.HEADER_SIZE), FilePageStore.HEADER_SIZE);
+ fileIO.write(ByteBuffer.allocate((int)size - filePageStore.headerSize()), filePageStore.headerSize());
fileIO.force();
}
[07/29] ignite git commit: IGNITE-5923: ODBC: SQLGetTypeInfo now
works with SQL_ALL_TYPES
Posted by nt...@apache.org.
IGNITE-5923: ODBC: SQLGetTypeInfo now works with SQL_ALL_TYPES
(cherry picked from commit 48c914d)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0b3a9a71
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0b3a9a71
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0b3a9a71
Branch: refs/heads/ignite-5947
Commit: 0b3a9a7176f5ae44a96ecf700c8147193dfbf064
Parents: d1a74a4
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Aug 4 13:18:00 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Aug 4 17:46:10 2017 +0300
----------------------------------------------------------------------
modules/platforms/cpp/odbc-test/Makefile.am | 1 +
.../cpp/odbc-test/include/complex_type.h | 271 +++++++++----------
.../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 +
.../project/vs/odbc-test.vcxproj.filters | 3 +
.../cpp/odbc-test/src/meta_queries_test.cpp | 189 +++++++++++++
modules/platforms/cpp/odbc/src/odbc.cpp | 2 +-
.../cpp/odbc/src/query/type_info_query.cpp | 2 +-
modules/platforms/cpp/odbc/src/statement.cpp | 2 +-
8 files changed, 332 insertions(+), 139 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index 56ae56a..1d65468 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -61,6 +61,7 @@ ignite_odbc_tests_SOURCES = \
src/column_test.cpp \
src/configuration_test.cpp \
src/row_test.cpp \
+ src/meta_queries_test.cpp \
src/utility_test.cpp \
src/queries_test.cpp \
src/test_utils.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc-test/include/complex_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/complex_type.h b/modules/platforms/cpp/odbc-test/include/complex_type.h
index 8a1bd59..ea01554 100644
--- a/modules/platforms/cpp/odbc-test/include/complex_type.h
+++ b/modules/platforms/cpp/odbc-test/include/complex_type.h
@@ -1,137 +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.
- */
-
-#ifndef _IGNITE_ODBC_TEST_COMPLEX_TYPE
-#define _IGNITE_ODBC_TEST_COMPLEX_TYPE
-
-#include <string>
-
-#include "ignite/ignite.h"
-#include "ignite/ignition.h"
-
-namespace ignite
-{
- struct TestObject
- {
- TestObject() :
- f1(412),
- f2("Lorem ipsum")
- {
- // No-op.
- }
-
- int32_t f1;
- std::string f2;
- };
-
- struct ComplexType
- {
- ComplexType() :
- i32Field(0)
- {
- // No-op.
- }
-
- int32_t i32Field;
- TestObject objField;
- std::string strField;
- };
-
- bool operator==(TestObject const& lhs, TestObject const& rhs)
- {
- return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2;
- }
-
- bool operator==(ComplexType const& lhs, ComplexType const& rhs)
- {
- return lhs.i32Field == rhs.i32Field && lhs.objField == rhs.objField && lhs.strField == rhs.strField;
- }
-
- std::ostream& operator<<(std::ostream& str, TestObject const& obj)
- {
- str << "TestObject::f1: " << obj.f1
- << "TestObject::f2: " << obj.f2;
- return str;
- }
-
- std::ostream& operator<<(std::ostream& str, ComplexType const& obj)
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_ODBC_TEST_COMPLEX_TYPE
+#define _IGNITE_ODBC_TEST_COMPLEX_TYPE
+
+#include <string>
+
+#include "ignite/ignite.h"
+
+namespace ignite
+{
+ struct TestObject
{
- str << "ComplexType::i32Field: " << obj.i32Field
- << "ComplexType::objField: " << obj.objField
- << "ComplexType::strField: " << obj.strField;
- return str;
- }
-}
-
-namespace ignite
-{
- namespace binary
- {
-
- IGNITE_BINARY_TYPE_START(ignite::TestObject)
-
- typedef ignite::TestObject TestObject;
-
- IGNITE_BINARY_GET_TYPE_ID_AS_HASH(TestObject)
- IGNITE_BINARY_GET_TYPE_NAME_AS_IS(TestObject)
- IGNITE_BINARY_GET_FIELD_ID_AS_HASH
- IGNITE_BINARY_IS_NULL_FALSE(TestObject)
- IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestObject)
-
- static void Write(BinaryWriter& writer, const TestObject& obj)
- {
- writer.WriteInt32("f1", obj.f1);
- writer.WriteString("f2", obj.f2);
- }
-
- static void Read(BinaryReader& reader, TestObject& dst)
- {
- dst.f1 = reader.ReadInt32("f1");
- dst.f2 = reader.ReadString("f2");
- }
-
- IGNITE_BINARY_TYPE_END
-
- IGNITE_BINARY_TYPE_START(ignite::ComplexType)
-
- typedef ignite::ComplexType ComplexType;
-
- IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType)
- IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType)
- IGNITE_BINARY_GET_FIELD_ID_AS_HASH
- IGNITE_BINARY_IS_NULL_FALSE(ComplexType)
- IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType)
-
- static void Write(BinaryWriter& writer, const ComplexType& obj)
- {
- writer.WriteInt32("i32Field", obj.i32Field);
- writer.WriteObject("objField", obj.objField);
- writer.WriteString("strField", obj.strField);
- }
-
- static void Read(BinaryReader& reader, ComplexType& dst)
- {
- dst.i32Field = reader.ReadInt32("i32Field");
- dst.objField = reader.ReadObject<TestObject>("objField");
- dst.strField = reader.ReadString("strField");
- }
-
- IGNITE_BINARY_TYPE_END
- }
-};
-
-#endif // _IGNITE_ODBC_TEST_COMPLEX_TYPE
+ TestObject() :
+ f1(412),
+ f2("Lorem ipsum")
+ {
+ // No-op.
+ }
+
+ friend bool operator==(TestObject const& lhs, TestObject const& rhs)
+ {
+ return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2;
+ }
+
+ friend std::ostream& operator<<(std::ostream& str, TestObject const& obj)
+ {
+ str << "TestObject::f1: " << obj.f1
+ << "TestObject::f2: " << obj.f2;
+ return str;
+ }
+
+ int32_t f1;
+ std::string f2;
+ };
+
+ struct ComplexType
+ {
+ ComplexType() :
+ i32Field(0)
+ {
+ // No-op.
+ }
+
+ friend bool operator==(ComplexType const& lhs, ComplexType const& rhs)
+ {
+ return lhs.i32Field == rhs.i32Field && lhs.objField == rhs.objField && lhs.strField == rhs.strField;
+ }
+
+ friend std::ostream& operator<<(std::ostream& str, ComplexType const& obj)
+ {
+ str << "ComplexType::i32Field: " << obj.i32Field
+ << "ComplexType::objField: " << obj.objField
+ << "ComplexType::strField: " << obj.strField;
+ return str;
+ }
+
+ int32_t i32Field;
+ TestObject objField;
+ std::string strField;
+ };
+}
+
+namespace ignite
+{
+ namespace binary
+ {
+
+ IGNITE_BINARY_TYPE_START(ignite::TestObject)
+
+ typedef ignite::TestObject TestObject;
+
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(TestObject)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(TestObject)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_IS_NULL_FALSE(TestObject)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestObject)
+
+ static void Write(BinaryWriter& writer, const TestObject& obj)
+ {
+ writer.WriteInt32("f1", obj.f1);
+ writer.WriteString("f2", obj.f2);
+ }
+
+ static void Read(BinaryReader& reader, TestObject& dst)
+ {
+ dst.f1 = reader.ReadInt32("f1");
+ dst.f2 = reader.ReadString("f2");
+ }
+
+ IGNITE_BINARY_TYPE_END
+
+ IGNITE_BINARY_TYPE_START(ignite::ComplexType)
+
+ typedef ignite::ComplexType ComplexType;
+
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_IS_NULL_FALSE(ComplexType)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType)
+
+ static void Write(BinaryWriter& writer, const ComplexType& obj)
+ {
+ writer.WriteInt32("i32Field", obj.i32Field);
+ writer.WriteObject("objField", obj.objField);
+ writer.WriteString("strField", obj.strField);
+ }
+
+ static void Read(BinaryReader& reader, ComplexType& dst)
+ {
+ dst.i32Field = reader.ReadInt32("i32Field");
+ dst.objField = reader.ReadObject<TestObject>("objField");
+ dst.strField = reader.ReadString("strField");
+ }
+
+ IGNITE_BINARY_TYPE_END
+ }
+};
+
+#endif // _IGNITE_ODBC_TEST_COMPLEX_TYPE
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index c332aad..ceecb3d 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -168,6 +168,7 @@
<ClCompile Include="..\..\src\configuration_test.cpp" />
<ClCompile Include="..\..\src\connection_info_test.cpp" />
<ClCompile Include="..\..\src\cursor_test.cpp" />
+ <ClCompile Include="..\..\src\meta_queries_test.cpp" />
<ClCompile Include="..\..\src\queries_test.cpp" />
<ClCompile Include="..\..\src\parser_test.cpp" />
<ClCompile Include="..\..\src\row_test.cpp" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 65f2ebf..91c029e 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -121,6 +121,9 @@
<ClCompile Include="..\..\..\odbc\src\log.cpp">
<Filter>Externals</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\meta_queries_test.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\test_type.h">
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
new file mode 100644
index 0000000..5b7ae59
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignition.h"
+
+#include "ignite/common/fixed_size_array.h"
+#include "ignite/impl/binary/binary_utils.h"
+
+#include "test_type.h"
+#include "complex_type.h"
+#include "test_utils.h"
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+using namespace ignite_test;
+using namespace ignite::binary;
+using namespace ignite::impl::binary;
+using namespace ignite::impl::interop;
+
+using namespace boost::unit_test;
+
+/**
+ * Test setup fixture.
+ */
+struct MetaQueriesTestSuiteFixture
+{
+ /**
+ * Establish connection to node.
+ *
+ * @param connectStr Connection string.
+ */
+ void Connect(const std::string& connectStr)
+ {
+ // Allocate an environment handle
+ SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+
+ BOOST_REQUIRE(env != NULL);
+
+ // We want ODBC 3 support
+ SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+
+ // Allocate a connection handle
+ SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
+
+ BOOST_REQUIRE(dbc != NULL);
+
+ // Connect string
+ std::vector<SQLCHAR> connectStr0;
+
+ connectStr0.reserve(connectStr.size() + 1);
+ std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
+
+ SQLCHAR outstr[ODBC_BUFFER_SIZE];
+ SQLSMALLINT outstrlen;
+
+ // Connecting to ODBC server.
+ SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
+ outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+ if (!SQL_SUCCEEDED(ret))
+ {
+ Ignition::Stop(grid.GetName(), true);
+
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
+ }
+
+ // Allocate a statement handle
+ SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
+
+ BOOST_REQUIRE(stmt != NULL);
+ }
+
+ void Disconnect()
+ {
+ // Releasing statement handle.
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+ // Disconneting from the server.
+ SQLDisconnect(dbc);
+
+ // Releasing allocated handles.
+ SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+ SQLFreeHandle(SQL_HANDLE_ENV, env);
+ }
+
+ static Ignite StartAdditionalNode(const char* name)
+ {
+#ifdef IGNITE_TESTS_32
+ return StartNode("queries-test-noodbc-32.xml", name);
+#else
+ return StartNode("queries-test-noodbc.xml", name);
+#endif
+ }
+
+ /**
+ * Constructor.
+ */
+ MetaQueriesTestSuiteFixture() :
+ cache1(0),
+ cache2(0),
+ env(NULL),
+ dbc(NULL),
+ stmt(NULL)
+ {
+#ifdef IGNITE_TESTS_32
+ grid = StartNode("queries-test-32.xml", "NodeMain");
+#else
+ grid = StartNode("queries-test.xml", "NodeMain");
+#endif
+
+ cache1 = grid.GetCache<int64_t, TestType>("cache");
+ cache2 = grid.GetCache<int64_t, ComplexType>("cache2");
+ }
+
+ /**
+ * Destructor.
+ */
+ ~MetaQueriesTestSuiteFixture()
+ {
+ Disconnect();
+
+ Ignition::StopAll(true);
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+
+ /** Frist cache instance. */
+ Cache<int64_t, TestType> cache1;
+
+ /** Second cache instance. */
+ Cache<int64_t, ComplexType> cache2;
+
+ /** ODBC Environment. */
+ SQLHENV env;
+
+ /** ODBC Connect. */
+ SQLHDBC dbc;
+
+ /** ODBC Statement. */
+ SQLHSTMT stmt;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MetaQueriesTestSuite, MetaQueriesTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TestGetTypeInfoAllTypes)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index b450903..1862465 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -1019,7 +1019,7 @@ namespace ignite
{
using odbc::Statement;
- LOG_MSG("SQLGetTypeInfo called");
+ LOG_MSG("SQLGetTypeInfo called: [type=" << type << ']');
Statement *statement = reinterpret_cast<Statement*>(stmt);
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index 280477b..f6b3990 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -155,7 +155,7 @@ namespace ignite
columnsMeta.push_back(ColumnMeta(sch, tbl, "NUM_PREC_RADIX", IGNITE_TYPE_INT));
columnsMeta.push_back(ColumnMeta(sch, tbl, "INTERVAL_PRECISION", IGNITE_TYPE_SHORT));
- assert(IsSqlTypeSupported(sqlType));
+ assert(IsSqlTypeSupported(sqlType) || sqlType == SQL_ALL_TYPES);
if (sqlType == SQL_ALL_TYPES)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b3a9a71/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
index adc7d6b..38a1e2e 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -671,7 +671,7 @@ namespace ignite
SqlResult::Type Statement::InternalExecuteGetTypeInfoQuery(int16_t sqlType)
{
- if (!type_traits::IsSqlTypeSupported(sqlType))
+ if (sqlType != SQL_ALL_TYPES && !type_traits::IsSqlTypeSupported(sqlType))
{
std::stringstream builder;
builder << "Data type is not supported. [typeId=" << sqlType << ']';
[26/29] ignite git commit: IGNITE-6004: Added
QuerySqlField.inlineSize property. This closes #2420.
Posted by nt...@apache.org.
IGNITE-6004: Added QuerySqlField.inlineSize property. This closes #2420.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/621380db
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/621380db
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/621380db
Branch: refs/heads/ignite-5947
Commit: 621380dbec5d1b9dcff626bb1686ad75361f7ed8
Parents: 305c0f4
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Aug 15 11:19:37 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 15 11:20:56 2017 +0300
----------------------------------------------------------------------
.../org/apache/ignite/cache/QueryEntity.java | 15 +-
.../org/apache/ignite/cache/QueryIndex.java | 5 +-
.../query/annotations/QueryGroupIndex.java | 20 +++
.../cache/query/annotations/QuerySqlField.java | 23 +++
.../cache/query/QueryEntityTypeDescriptor.java | 17 +-
...ridCacheQuerySqlFieldInlineSizeSelfTest.java | 160 +++++++++++++++++++
.../IgniteCacheQuerySelfTestSuite.java | 3 +
7 files changed, 226 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 5180100..6440b48 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -419,6 +419,7 @@ public class QueryEntity implements Serializable {
sortedIdx.setFields(fields);
sortedIdx.setName(idxEntry.getKey());
+ sortedIdx.setInlineSize(idx.inlineSize());
idxs.add(sortedIdx);
}
@@ -480,7 +481,7 @@ public class QueryEntity implements Serializable {
String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
- QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+ QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED, QueryIndex.DFLT_INLINE_SIZE);
type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
}
@@ -500,13 +501,13 @@ public class QueryEntity implements Serializable {
QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
if (grpIdx != null)
- type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
+ type.addIndex(grpIdx.name(), QueryIndexType.SORTED, grpIdx.inlineSize());
QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
for (QueryGroupIndex idx : grpIdxList.value())
- type.addIndex(idx.name(), QueryIndexType.SORTED);
+ type.addIndex(idx.name(), QueryIndexType.SORTED, idx.inlineSize());
}
}
@@ -559,11 +560,17 @@ public class QueryEntity implements Serializable {
idxName = cls.getSimpleName() + "_" + idxName;
desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
- QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+ QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED, sqlAnn.inlineSize());
desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
}
+ if ((!F.isEmpty(sqlAnn.groups()) || !F.isEmpty(sqlAnn.orderedGroups()))
+ && sqlAnn.inlineSize() != QueryIndex.DFLT_INLINE_SIZE) {
+ throw new CacheException("Inline size cannot be set on a field with group index [" +
+ "type=" + cls.getName() + ", property=" + prop.fullName() + ']');
+ }
+
if (!F.isEmpty(sqlAnn.groups())) {
for (String group : sqlAnn.groups())
desc.addFieldToIndex(group, prop.fullName(), 0, false);
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java
index 6e73049..ac7dd8e 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java
@@ -38,6 +38,9 @@ public class QueryIndex implements Serializable {
/** */
private static final QueryIndexType DFLT_IDX_TYP = QueryIndexType.SORTED;
+ /** Default index inline size. */
+ public static final int DFLT_INLINE_SIZE = -1;
+
/** Index name. */
private String name;
@@ -49,7 +52,7 @@ public class QueryIndex implements Serializable {
private QueryIndexType type = DFLT_IDX_TYP;
/** */
- private int inlineSize = -1;
+ private int inlineSize = DFLT_INLINE_SIZE;
/**
* Creates an empty index. Should be populated via setters.
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
index b1fefae..a947d0f 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
@@ -21,6 +21,8 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.configuration.CacheConfiguration;
/**
* Describes group index.
@@ -36,6 +38,24 @@ public @interface QueryGroupIndex {
String name();
/**
+ * Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
+ * thus minimizing data page accesses, thus incraesing query performance.
+ * <p>
+ * Allowed values:
+ * <ul>
+ * <li>{@code -1} (default) - determine inline size automatically (see below)</li>
+ * <li>{@code 0} - index inline is disabled (not recommended)</li>
+ * <li>positive value - fixed index inline</li>
+ * </ul>
+ * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than
+ * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types,
+ * but <b>will not be enabled</b> for {@code String}.
+ *
+ * @return Index inline size in bytes.
+ */
+ int inlineSize() default QueryIndex.DFLT_INLINE_SIZE;
+
+ /**
* List of group indexes for type.
*/
@SuppressWarnings("PublicInnerClass")
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java
index 94dbea1..64aaa3a 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java
@@ -22,6 +22,8 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.processors.cache.query.CacheQuery;
/**
@@ -88,6 +90,27 @@ public @interface QuerySqlField {
String name() default "";
/**
+ * Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages,
+ * thus minimizing data page accesses, thus incraesing query performance.
+ * <p>
+ * Allowed values:
+ * <ul>
+ * <li>{@code -1} (default) - determine inline size automatically (see below)</li>
+ * <li>{@code 0} - index inline is disabled (not recommended)</li>
+ * <li>positive value - fixed index inline</li>
+ * </ul>
+ * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than
+ * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types,
+ * but <b>will not be enabled</b> for {@code String}.
+ * <p>
+ * When index group is used, inline size must be defined in {@link QueryGroupIndex#inlineSize()}. Any value
+ * except of {@code -1} defined on a specific column will lead to exception.
+ *
+ * @return Index inline size in bytes.
+ */
+ int inlineSize() default QueryIndex.DFLT_INLINE_SIZE;
+
+ /**
* Describes group of index and position of field in this group.
* <p>
* Opposite to {@link #groups()} this annotation gives control over order of fields in a group index.
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
index 47ab263..837a08f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.cache.CacheException;
+import org.apache.ignite.cache.QueryIndex;
import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -78,6 +79,9 @@ public class QueryEntityTypeDescriptor {
* @return Index descriptor.
*/
public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
+ if (inlineSize < 0 && inlineSize != QueryIndex.DFLT_INLINE_SIZE)
+ throw new CacheException("Illegal inline size [idxName=" + idxName + ", inlineSize=" + inlineSize + ']');
+
QueryEntityIndexDescriptor idx = new QueryEntityIndexDescriptor(type, inlineSize);
if (indexes.put(idxName, idx) != null)
@@ -87,17 +91,6 @@ public class QueryEntityTypeDescriptor {
}
/**
- * Adds index.
- *
- * @param idxName Index name.
- * @param type Index type.
- * @return Index descriptor.
- */
- public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type) {
- return addIndex(idxName, type, -1);
- }
-
- /**
* Adds field to index.
*
* @param idxName Index name.
@@ -110,7 +103,7 @@ public class QueryEntityTypeDescriptor {
QueryEntityIndexDescriptor desc = indexes.get(idxName);
if (desc == null)
- desc = addIndex(idxName, QueryIndexType.SORTED);
+ desc = addIndex(idxName, QueryIndexType.SORTED, QueryIndex.DFLT_INLINE_SIZE);
desc.addField(field, orderNum, descending);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java
new file mode 100644
index 0000000..a257160
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.cache;
+
+import java.util.concurrent.Callable;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Tests cache configuration with inlineSize property of the QuerySqlField annotation.
+ */
+@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "unchecked", "unused"})
+public class GridCacheQuerySqlFieldInlineSizeSelfTest extends GridCommonAbstractTest {
+ /**
+ * @throws Exception If failed.
+ */
+ public void testSingleFieldIndexes() throws Exception {
+ CacheConfiguration ccfg = defaultCacheConfiguration();
+
+ ccfg.setIndexedTypes(Integer.class, TestValueSingleFieldIndexes.class);
+
+ assertEquals(1, ccfg.getQueryEntities().size());
+
+ QueryEntity ent = (QueryEntity)ccfg.getQueryEntities().iterator().next();
+
+ assertEquals(2, ent.getIndexes().size());
+
+ for (QueryIndex idx : ent.getIndexes()) {
+ if(idx.getFields().containsKey("val0"))
+ assertEquals(10, idx.getInlineSize());
+ else if(idx.getFields().containsKey("val1"))
+ assertEquals(20, idx.getInlineSize());
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGroupIndex() throws Exception {
+ CacheConfiguration ccfg = defaultCacheConfiguration();
+
+ ccfg.setIndexedTypes(Integer.class, TestValueGroupIndex.class);
+
+ assertEquals(1, ccfg.getQueryEntities().size());
+
+ QueryEntity ent = (QueryEntity)ccfg.getQueryEntities().iterator().next();
+
+ assertEquals(1, ent.getIndexes().size());
+
+ QueryIndex idx = ent.getIndexes().iterator().next();
+
+ assertEquals(10, idx.getInlineSize());
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testGroupIndexInvalidAnnotaion() throws Exception {
+ final CacheConfiguration ccfg = defaultCacheConfiguration();
+
+ GridTestUtils.assertThrows(log, new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ ccfg.setIndexedTypes(Integer.class, TestValueGroupIndexInvalidAnnotation.class);
+
+ return null;
+ }
+ }, CacheException.class, "Inline size cannot be set on a field with group index");
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testNegativeInlineSize() throws Exception {
+ final CacheConfiguration ccfg = defaultCacheConfiguration();
+
+ GridTestUtils.assertThrows(
+ log, new Callable<Object>() {
+
+ @Override public Object call() throws Exception {
+ ccfg.setIndexedTypes(Integer.class, TestValueNegativeInlineSize.class);
+
+ return null;
+ }
+ },
+ CacheException.class,
+ "Illegal inline size [idxName=TestValueNegativeInlineSize_val_idx, inlineSize=-10]"
+ );
+ }
+
+ /**
+ *
+ */
+ static class TestValueSingleFieldIndexes {
+ /** */
+ @QuerySqlField(index = true, inlineSize = 10)
+ String val0;
+
+ /** */
+ @QuerySqlField(index = true, inlineSize = 20)
+ String val1;
+ }
+
+ /**
+ *
+ */
+ @QueryGroupIndex(name="idx", inlineSize = 10)
+ static class TestValueGroupIndex {
+ /** */
+ @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 0))
+ String val0;
+
+ /** */
+ @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 1))
+ String val1;
+ }
+
+ /**
+ *
+ */
+ @QueryGroupIndex(name="idx")
+ static class TestValueGroupIndexInvalidAnnotation {
+ /** */
+ @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 0))
+ String val0;
+
+ /** */
+ @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 1), inlineSize = 10)
+ String val1;
+ }
+
+ /**
+ *
+ */
+ static class TestValueNegativeInlineSize {
+ /** */
+ @QuerySqlField(index = true, inlineSize = -10)
+ String val;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index decc7d5..99b0370 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -39,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexDisabledSe
import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexingDisabledSelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheQueryInternalKeysSelfTest;
import org.apache.ignite.internal.processors.cache.GridCacheQuerySerializationSelfTest;
+import org.apache.ignite.internal.processors.cache.GridCacheQuerySqlFieldInlineSizeSelfTest;
import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuerySelfTest;
import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectLocalQueryArgumentsTest;
import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectQueryArgumentsTest;
@@ -320,6 +321,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
suite.addTestSuite(IgniteSqlRoutingTest.class);
suite.addTestSuite(LongIndexNameTest.class);
+ suite.addTestSuite(GridCacheQuerySqlFieldInlineSizeSelfTest.class);
+
return suite;
}
}
[02/29] ignite git commit: IGNITE-4800: Lucene query may fails with
NPE. Test fixed.
Posted by nt...@apache.org.
IGNITE-4800: Lucene query may fails with NPE.
Test fixed.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3fdf453e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3fdf453e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3fdf453e
Branch: refs/heads/ignite-5947
Commit: 3fdf453e89a7bd76dff6b6d0646e3821ea3921d5
Parents: 1e08c3f
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Jul 31 17:32:12 2017 +0300
Committer: Andrey V. Mashenkov <an...@gmail.com>
Committed: Mon Jul 31 17:32:12 2017 +0300
----------------------------------------------------------------------
.../cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3fdf453e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
index ed092df..162b1e5 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
@@ -42,7 +42,6 @@ import static org.apache.ignite.cache.CacheMode.PARTITIONED;
import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
/**
- * TODO https://issues.apache.org/jira/browse/IGNITE-2229
* Tests cache in-place modification logic with iterative value increment.
*/
public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstractTest {
@@ -107,6 +106,8 @@ public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstr
* @throws Exception If failed.
*/
public void testFullTextQueryNodeJoin() throws Exception {
+ fail("https://issues.apache.org/jira/browse/IGNITE-2229");
+
for (int r = 0; r < 5; r++) {
startGrids(GRID_CNT);
@@ -119,10 +120,6 @@ public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstr
Ignite started = startGrid(GRID_CNT);
- //TODO: remove next line when IGNITE-2229 issue will be fixed.
- // see https://issues.apache.org/jira/browse/IGNITE-2229
- awaitPartitionMapExchange();
-
for (int i = 0; i < 100; i++) {
QueryCursor<Cache.Entry<AffinityKey<Integer>, IndexedEntity>> res = started.cache(DEFAULT_CACHE_NAME)
.query(new TextQuery<AffinityKey<Integer>, IndexedEntity>(IndexedEntity.class, "indexed"));
[20/29] ignite git commit: IGNITE-5941 - Fixed index name length
restrictions. This closes #2408
Posted by nt...@apache.org.
IGNITE-5941 - Fixed index name length restrictions. This closes #2408
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/fde550ba
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/fde550ba
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/fde550ba
Branch: refs/heads/ignite-5947
Commit: fde550bac56fd0cc7c51c62a9c291dd4c3f3030c
Parents: 74d6ab9
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Mon Aug 14 11:32:11 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Aug 14 11:33:34 2017 +0300
----------------------------------------------------------------------
.../ignite/internal/pagemem/PageUtils.java | 26 +++
.../cache/persistence/MetadataStorage.java | 12 +-
.../cache/index/LongIndexNameTest.java | 212 +++++++++++++++++++
.../IgniteCacheQuerySelfTestSuite.java | 2 +
4 files changed, 246 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/fde550ba/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageUtils.java
index 3fa5954..362ac54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageUtils.java
@@ -37,6 +37,19 @@ public class PageUtils {
}
/**
+ *
+ * @param addr Start address.
+ * @param off Offset.
+ * @return Byte value from given address.
+ */
+ public static int getUnsignedByte(long addr, int off) {
+ assert addr > 0 : addr;
+ assert off >= 0;
+
+ return GridUnsafe.getByte(addr + off) & 0xFF;
+ }
+
+ /**
* @param addr Start address.
* @param off Offset.
* @param len Bytes length.
@@ -168,6 +181,19 @@ public class PageUtils {
* @param off Offset.
* @param v Value.
*/
+ public static void putUnsignedByte(long addr, int off, int v) {
+ assert addr > 0 : addr;
+ assert off >= 0;
+ assert v >= 0 && v <= 255;
+
+ GridUnsafe.putByte(addr + off, (byte) v);
+ }
+
+ /**
+ * @param addr Address.
+ * @param off Offset.
+ * @param v Value.
+ */
public static void putShort(long addr, int off, short v) {
assert addr > 0 : addr;
assert off >= 0;
http://git-wip-us.apache.org/repos/asf/ignite/blob/fde550ba/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/MetadataStorage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/MetadataStorage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/MetadataStorage.java
index 743f3b9..498ecdd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/MetadataStorage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/MetadataStorage.java
@@ -39,7 +39,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
*/
public class MetadataStorage implements MetaStore {
/** Max index name length (bytes num) */
- public static final int MAX_IDX_NAME_LEN = 768;
+ public static final int MAX_IDX_NAME_LEN = 255;
/** Bytes in byte. */
private static final int BYTE_LEN = 1;
@@ -197,7 +197,7 @@ public class MetadataStorage implements MetaStore {
int shift = 0;
// Compare index names.
- final byte len = PageUtils.getByte(pageAddr, off + shift);
+ final int len = PageUtils.getUnsignedByte(pageAddr, off + shift);
shift += BYTE_LEN;
@@ -256,7 +256,7 @@ public class MetadataStorage implements MetaStore {
final IndexItem row
) {
// Index name length.
- PageUtils.putByte(pageAddr, off, (byte)row.idxName.length);
+ PageUtils.putUnsignedByte(pageAddr, off, row.idxName.length);
off++;
// Index name.
@@ -282,10 +282,10 @@ public class MetadataStorage implements MetaStore {
int srcOff
) {
// Index name length.
- final byte len = PageUtils.getByte(srcPageAddr, srcOff);
+ final int len = PageUtils.getUnsignedByte(srcPageAddr, srcOff);
srcOff++;
- PageUtils.putByte(dstPageAddr, dstOff, len);
+ PageUtils.putUnsignedByte(dstPageAddr, dstOff, len);
dstOff++;
PageHandler.copyMemory(srcPageAddr, dstPageAddr, srcOff, dstOff, len);
@@ -305,7 +305,7 @@ public class MetadataStorage implements MetaStore {
*/
private static IndexItem readRow(final long pageAddr, int off) {
// Index name length.
- final int len = PageUtils.getByte(pageAddr, off) & 0xFF;
+ final int len = PageUtils.getUnsignedByte(pageAddr, off) & 0xFF;
off++;
// Index name.
http://git-wip-us.apache.org/repos/asf/ignite/blob/fde550ba/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/LongIndexNameTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/LongIndexNameTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/LongIndexNameTest.java
new file mode 100644
index 0000000..92883a4
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/LongIndexNameTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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.cache.index;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.PersistentStoreConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ *
+ */
+public class LongIndexNameTest extends GridCommonAbstractTest {
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ return super.getConfiguration(igniteInstanceName)
+ .setPersistentStoreConfiguration(new PersistentStoreConfiguration())
+ .setCacheConfiguration(new <String, Person>CacheConfiguration("cache")
+ .setQueryEntities(getIndexCfg())
+ .setAffinity(new RendezvousAffinityFunction(false, 16)));
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ super.beforeTest();
+
+ deleteWorkFiles();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ deleteWorkFiles();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testLongIndexNames() throws Exception {
+ try {
+ Ignite ignite = startGrid(0);
+
+ IgniteCache cache = insertSomeData(ignite);
+
+ QueryCursor cursor1 = cache.query(new SqlFieldsQuery("SELECT * FROM Person where name like '%Name 0'"));
+ QueryCursor cursor1Idx = cache.query(new SqlFieldsQuery("SELECT * FROM Person where name = 'Name 0'"));
+
+ QueryCursor cursor2 = cache.query(new SqlFieldsQuery("SELECT * FROM Person where age like '%0'"));
+ QueryCursor cursor2Idx = cache.query(new SqlFieldsQuery("SELECT * FROM Person where age = 0"));
+
+ assertEquals(cursor1.getAll().size(), cursor1Idx.getAll().size());
+ assertEquals(cursor2.getAll().size(), cursor2Idx.getAll().size());
+
+ ignite.close();
+
+ Thread.sleep(2_000);
+
+ ignite = startGrid(0);
+
+ cache = insertSomeData(ignite);
+
+ cursor1 = cache.query(new SqlFieldsQuery("SELECT * FROM Person where name like '%Name 0'"));
+ cursor1Idx = cache.query(new SqlFieldsQuery("SELECT * FROM Person where name = 'Name 0'"));
+
+ cursor2 = cache.query(new SqlFieldsQuery("SELECT * FROM Person where age like '%0'"));
+ cursor2Idx = cache.query(new SqlFieldsQuery("SELECT * FROM Person where age = 0"));
+
+ assertEquals(cursor1.getAll().size(), cursor1Idx.getAll().size());
+ assertEquals(cursor2.getAll().size(), cursor2Idx.getAll().size());
+
+
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ *
+ */
+ @NotNull private IgniteCache insertSomeData(Ignite ignite) {
+ if (!ignite.active())
+ ignite.active(true);
+
+ IgniteCache<String, Person> cache = ignite.cache("cache");
+
+ for (int i=0; i<10; i++)
+ cache.put(String.valueOf(System.currentTimeMillis()), new Person("Name " + i, i));
+
+ return cache;
+ }
+
+ /**
+ *
+ */
+ public static List<QueryEntity> getIndexCfg() {
+ ArrayList<QueryEntity> entities = new ArrayList<>();
+
+ QueryEntity qe = new QueryEntity(String.class.getName(), Person.class.getName());
+
+ LinkedHashMap<String, String> fieldsMap = new LinkedHashMap<>();
+ fieldsMap.put("name", String.class.getName());
+ fieldsMap.put("age", Integer.class.getName());
+
+ qe.setFields(fieldsMap);
+
+ ArrayList<QueryIndex> indices = new ArrayList<>();
+ QueryIndex index = new QueryIndex("name", true, "LONG_NAME_123456789012345678901234567890" +
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
+
+ QueryIndex index2 = new QueryIndex("age", true, "AGE_IDX");
+ indices.add(index);
+ indices.add(index2);
+
+ qe.setIndexes(indices);
+
+ entities.add(qe);
+
+ return entities;
+ }
+
+ /**
+ * @throws IgniteCheckedException If failed.
+ */
+ private void deleteWorkFiles() throws IgniteCheckedException {
+ deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+ }
+
+ /**
+ *
+ */
+ private static class Person {
+ /** */
+ private String name;
+
+ /** */
+ private int age;
+
+ /**
+ *
+ */
+ public Person() {
+ // No-op.
+ }
+
+ /**
+ * @param name Name.
+ * @param age Age.
+ */
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ /**
+ * @return Name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name Name.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return Age.
+ */
+ public int getAge() {
+ return age;
+ }
+
+ /**
+ * @param age Age.
+ */
+ public void setAge(int age) {
+ this.age = age;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/fde550ba/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 1ad0d4b..decc7d5 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -108,6 +108,7 @@ import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComple
import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalPartitionedTest;
import org.apache.ignite.internal.processors.cache.index.H2DynamicIndexingComplexServerTransactionalReplicatedTest;
import org.apache.ignite.internal.processors.cache.index.H2DynamicTableSelfTest;
+import org.apache.ignite.internal.processors.cache.index.LongIndexNameTest;
import org.apache.ignite.internal.processors.cache.index.SchemaExchangeSelfTest;
import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalAtomicQuerySelfTest;
import org.apache.ignite.internal.processors.cache.local.IgniteCacheLocalFieldsQuerySelfTest;
@@ -317,6 +318,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
suite.addTestSuite(IgniteCacheDistributedPartitionQueryConfigurationSelfTest.class);
suite.addTestSuite(IgniteSqlKeyValueFieldsTest.class);
suite.addTestSuite(IgniteSqlRoutingTest.class);
+ suite.addTestSuite(LongIndexNameTest.class);
return suite;
}
[16/29] ignite git commit: IGNITE-5902 Implemented stop caches at
once. (cherry picked from commit ebb8765)
Posted by nt...@apache.org.
IGNITE-5902 Implemented stop caches at once.
(cherry picked from commit ebb8765)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5c209785
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5c209785
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5c209785
Branch: refs/heads/ignite-5947
Commit: 5c2097856714a7803956d754735c68b21156019c
Parents: 841db65
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Aug 11 10:25:36 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Aug 11 10:28:22 2017 +0700
----------------------------------------------------------------------
.../visor/cache/VisorCacheStopTask.java | 22 ++++++++--------
.../visor/cache/VisorCacheStopTaskArg.java | 27 ++++++++++++++++++++
2 files changed, 39 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/5c209785/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTask.java
index 9f7c018..df95c5e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTask.java
@@ -17,8 +17,10 @@
package org.apache.ignite.internal.visor.cache;
-import org.apache.ignite.IgniteCache;
+import java.util.Collection;
+import java.util.HashSet;
import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.visor.VisorJob;
import org.apache.ignite.internal.visor.VisorOneNodeTask;
@@ -46,23 +48,23 @@ public class VisorCacheStopTask extends VisorOneNodeTask<VisorCacheStopTaskArg,
/**
* Create job.
*
- * @param cacheName Cache name to clear.
+ * @param arg Task argument.
* @param debug Debug flag.
*/
- private VisorCacheStopJob(VisorCacheStopTaskArg cacheName, boolean debug) {
- super(cacheName, debug);
+ private VisorCacheStopJob(VisorCacheStopTaskArg arg, boolean debug) {
+ super(arg, debug);
}
/** {@inheritDoc} */
@Override protected Void run(VisorCacheStopTaskArg arg) {
- String cacheName = arg.getCacheName();
+ Collection<String> cacheNames = F.isEmpty(arg.getCacheNames())
+ ? F.asList(arg.getCacheName())
+ : new HashSet<>(arg.getCacheNames());
- IgniteCache cache = ignite.cache(cacheName);
+ if (F.isEmpty(cacheNames))
+ throw new IllegalStateException("Cache names was not specified.");
- if (cache == null)
- throw new IllegalStateException("Failed to find cache for name: " + cacheName);
-
- cache.destroy();
+ ignite.destroyCaches(cacheNames);
return null;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/5c209785/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTaskArg.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTaskArg.java
index 4976036..77156ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTaskArg.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheStopTaskArg.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.visor.cache;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.List;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.VisorDataTransferObject;
@@ -34,6 +35,9 @@ public class VisorCacheStopTaskArg extends VisorDataTransferObject {
/** Cache name. */
private String cacheName;
+ /** Cache names. */
+ private List<String> cacheNames;
+
/**
* Default constructor.
*/
@@ -49,20 +53,43 @@ public class VisorCacheStopTaskArg extends VisorDataTransferObject {
}
/**
+ * @param cacheNames Cache names.
+ */
+ public VisorCacheStopTaskArg(List<String> cacheNames) {
+ this.cacheNames = cacheNames;
+ }
+
+ /**
* @return Cache name.
*/
public String getCacheName() {
return cacheName;
}
+ /**
+ * @return Cache names.
+ */
+ public List<String> getCacheNames() {
+ return cacheNames;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte getProtocolVersion() {
+ return V2;
+ }
+
/** {@inheritDoc} */
@Override protected void writeExternalData(ObjectOutput out) throws IOException {
U.writeString(out, cacheName);
+ U.writeCollection(out, cacheNames);
}
/** {@inheritDoc} */
@Override protected void readExternalData(byte protoVer, ObjectInput in) throws IOException, ClassNotFoundException {
cacheName = U.readString(in);
+
+ if (protoVer > V1)
+ cacheNames = U.readList(in);
}
/** {@inheritDoc} */
[27/29] ignite git commit: IGNITE-5995: ODBC fix for SQLGetData.
Posted by nt...@apache.org.
IGNITE-5995: ODBC fix for SQLGetData.
(cherry picked from commit 0d8d166)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/276e84a9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/276e84a9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/276e84a9
Branch: refs/heads/ignite-5947
Commit: 276e84a91bcea9c6b076ff674cdd16d93fbbde4d
Parents: 621380d
Author: Igor Sapego <is...@gridgain.com>
Authored: Thu Aug 10 15:31:44 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Tue Aug 15 16:53:57 2017 +0300
----------------------------------------------------------------------
.../impl/cache/query/query_fields_row_impl.h | 2 +-
.../cpp/odbc-test/include/test_utils.h | 9 ++
.../cpp/odbc-test/src/meta_queries_test.cpp | 100 +++++++++++++++++++
.../platforms/cpp/odbc-test/src/test_utils.cpp | 13 +++
.../ignite/odbc/query/column_metadata_query.h | 3 +
.../ignite/odbc/query/table_metadata_query.h | 3 +
.../include/ignite/odbc/query/type_info_query.h | 3 +
.../cpp/odbc/src/query/batch_query.cpp | 7 +-
.../odbc/src/query/column_metadata_query.cpp | 16 ++-
.../platforms/cpp/odbc/src/query/data_query.cpp | 7 +-
.../cpp/odbc/src/query/table_metadata_query.cpp | 16 ++-
.../cpp/odbc/src/query/type_info_query.cpp | 16 ++-
12 files changed, 183 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
index 63e0523..2943625 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -143,7 +143,7 @@ namespace ignite
int32_t actualLen = reader.ReadInt8Array(dst, len);
- if (actualLen == 0 || dst && len >= actualLen)
+ if (actualLen == 0 || (dst && len >= actualLen))
++processed;
return actualLen;
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc-test/include/test_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_utils.h b/modules/platforms/cpp/odbc-test/include/test_utils.h
index 6a58e54..5dc6d6e 100644
--- a/modules/platforms/cpp/odbc-test/include/test_utils.h
+++ b/modules/platforms/cpp/odbc-test/include/test_utils.h
@@ -43,6 +43,15 @@ namespace ignite_test
enum { ODBC_BUFFER_SIZE = 1024 };
/**
+ * Extract error state.
+ *
+ * @param handleType Type of the handle.
+ * @param handle Handle.
+ * @return Error state.
+ */
+ std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle);
+
+ /**
* Extract error message.
*
* @param handleType Type of the handle.
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 454a989..ff3695d 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -103,6 +103,9 @@ struct MetaQueriesTestSuiteFixture
BOOST_REQUIRE(stmt != NULL);
}
+ /**
+ * Disconnect.
+ */
void Disconnect()
{
// Releasing statement handle.
@@ -116,6 +119,11 @@ struct MetaQueriesTestSuiteFixture
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
+ /**
+ * Start additional node with the specified name.
+ *
+ * @param name Node name.
+ */
static Ignite StartAdditionalNode(const char* name)
{
#ifdef IGNITE_TESTS_32
@@ -126,6 +134,36 @@ struct MetaQueriesTestSuiteFixture
}
/**
+ * Checks single row result set for correct work with SQLGetData.
+ *
+ * @param stmt Statement.
+ */
+ void CheckSingleRowResultSetWithGetData(SQLHSTMT stmt)
+ {
+ SQLRETURN ret = SQLFetch(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ char buf[1024];
+ SQLLEN bufLen = sizeof(buf);
+
+ ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFetch(stmt);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
+
+ ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "24000");
+ }
+
+ /**
* Constructor.
*/
MetaQueriesTestSuiteFixture() :
@@ -237,4 +275,66 @@ BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
+BOOST_AUTO_TEST_CASE(TestGetDataWithGetTypeInfo)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_VARCHAR);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithTables)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR empty[] = "";
+ SQLCHAR table[] = "TestType";
+
+ SQLRETURN ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithColumns)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR empty[] = "";
+ SQLCHAR table[] = "TestType";
+ SQLCHAR column[] = "strField";
+
+ SQLRETURN ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, column, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithSelectQuery)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+ SQLCHAR insertReq[] = "insert into TestType(_key, strField) VALUES(1, 'Lorem ipsum')";
+ SQLRETURN ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLCHAR selectReq[] = "select strField from TestType";
+ ret = SQLExecDirect(stmt, selectReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ CheckSingleRowResultSetWithGetData(stmt);
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/test_utils.cpp b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
index c7aa70a..6e8fe6a 100644
--- a/modules/platforms/cpp/odbc-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
@@ -21,6 +21,19 @@
namespace ignite_test
{
+ std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle)
+ {
+ SQLCHAR sqlstate[7] = {};
+ SQLINTEGER nativeCode;
+
+ SQLCHAR message[ODBC_BUFFER_SIZE];
+ SQLSMALLINT reallen = 0;
+
+ SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeCode, message, ODBC_BUFFER_SIZE, &reallen);
+
+ return std::string(reinterpret_cast<char*>(sqlstate));
+ }
+
std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle)
{
SQLCHAR sqlstate[7] = {};
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
index 878a4be..875b1ce 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
@@ -130,6 +130,9 @@ namespace ignite
/** Query executed. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Fetched metadata. */
meta::ColumnMetaVector meta;
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
index cef963c..acd3f49 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
@@ -134,6 +134,9 @@ namespace ignite
/** Query executed. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Fetched metadata. */
meta::TableMetaVector meta;
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
index a7cee92..00cca08 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
@@ -105,6 +105,9 @@ namespace ignite
/** Executed flag. */
bool executed;
+ /** Fetched flag. */
+ bool fetched;
+
/** Requested types. */
std::vector<int8_t> types;
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index df9fb05..46447c0 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -112,7 +112,12 @@ namespace ignite
}
if (dataRetrieved)
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
if (columnIdx != 1)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
index 8ba9323..b9c08f5 100644
--- a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
@@ -83,6 +83,7 @@ namespace ignite
table(table),
column(column),
executed(false),
+ fetched(false),
meta(),
columnsMeta()
{
@@ -125,6 +126,7 @@ namespace ignite
if (result == SqlResult::AI_SUCCESS)
{
executed = true;
+ fetched = false;
cursor = meta.begin();
}
@@ -146,6 +148,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == meta.end())
return SqlResult::AI_NO_DATA;
@@ -154,8 +161,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -169,7 +174,12 @@ namespace ignite
}
if (cursor == meta.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
const meta::ColumnMeta& currentColumn = *cursor;
uint8_t columnType = currentColumn.GetDataType();
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 23d5240..f14d004 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -125,7 +125,12 @@ namespace ignite
Row* row = cursor->GetRow();
if (!row)
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
SqlResult::Type result = row->ReadColumnToBuffer(columnIdx, buffer);
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
index 401a1d2..e66b281 100644
--- a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -63,6 +63,7 @@ namespace ignite
table(table),
tableType(tableType),
executed(false),
+ fetched(false),
meta(),
columnsMeta()
{
@@ -98,6 +99,7 @@ namespace ignite
if (result == SqlResult::AI_SUCCESS)
{
executed = true;
+ fetched = false;
cursor = meta.begin();
}
@@ -119,6 +121,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == meta.end())
return SqlResult::AI_NO_DATA;
@@ -127,8 +134,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -142,7 +147,12 @@ namespace ignite
}
if (cursor == meta.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
const meta::TableMeta& currentColumn = *cursor;
http://git-wip-us.apache.org/repos/asf/ignite/blob/276e84a9/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index f6b3990..b4efca0 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -122,6 +122,7 @@ namespace ignite
Query(diag, QueryType::TYPE_INFO),
columnsMeta(),
executed(false),
+ fetched(false),
types(),
cursor(types.end())
{
@@ -185,6 +186,7 @@ namespace ignite
cursor = types.begin();
executed = true;
+ fetched = false;
return SqlResult::AI_SUCCESS;
}
@@ -203,6 +205,11 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ if (!fetched)
+ fetched = true;
+ else
+ ++cursor;
+
if (cursor == types.end())
return SqlResult::AI_NO_DATA;
@@ -211,8 +218,6 @@ namespace ignite
for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
GetColumn(it->first, it->second);
- ++cursor;
-
return SqlResult::AI_SUCCESS;
}
@@ -228,7 +233,12 @@ namespace ignite
}
if (cursor == types.end())
- return SqlResult::AI_NO_DATA;
+ {
+ diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+ "Cursor has reached end of the result set.");
+
+ return SqlResult::AI_ERROR;
+ }
int8_t currentType = *cursor;