You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2014/12/10 12:32:00 UTC
incubator-ignite git commit: # Ignite Added initial cache interfaces
Repository: incubator-ignite
Updated Branches:
refs/heads/master 682e47fe2 -> a4f69c406
# Ignite Added initial cache interfaces
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/a4f69c40
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/a4f69c40
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/a4f69c40
Branch: refs/heads/master
Commit: a4f69c40605b4a4f36e62ef899d19a6392dca8ae
Parents: 682e47f
Author: sboikov <sb...@gridgain.com>
Authored: Wed Dec 10 14:31:47 2014 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed Dec 10 14:31:47 2014 +0300
----------------------------------------------------------------------
.../src/main/java/org/apache/ignite/Ignite.java | 22 +-
.../java/org/apache/ignite/IgniteCache.java | 300 +++++++++++++++++++
.../apache/ignite/cache/CacheConfiguration.java | 23 ++
.../apache/ignite/cache/CacheEntryEvent.java | 36 +++
.../java/org/apache/ignite/cache/CacheFlag.java | 68 +++++
.../org/apache/ignite/cache/CachePeekMode.java | 72 +++++
.../ignite/cache/eviction/EvictableEntry.java | 39 +++
.../cache/query/QueryAffinityPredicate.java | 124 ++++++++
.../cache/query/QueryContinuousPredicate.java | 204 +++++++++++++
.../apache/ignite/cache/query/QueryCursor.java | 29 ++
.../ignite/cache/query/QueryPredicate.java | 68 +++++
.../apache/ignite/cache/query/QueryReducer.java | 22 ++
.../ignite/cache/query/QuerySqlPredicate.java | 107 +++++++
.../ignite/cache/query/QueryTextPredicate.java | 79 +++++
.../query/annotations/QueryGroupIndex.java | 50 ++++
.../cache/query/annotations/QuerySqlField.java | 125 ++++++++
.../query/annotations/QuerySqlFunction.java | 59 ++++
.../cache/query/annotations/QueryTextField.java | 25 ++
.../org/gridgain/grid/kernal/GridKernal.java | 5 +
.../java/org/gridgain/grid/GridSpringBean.java | 5 +
20 files changed, 1456 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/Ignite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/Ignite.java b/modules/core/src/main/java/org/apache/ignite/Ignite.java
index 5cc0b50..94fcce8 100644
--- a/modules/core/src/main/java/org/apache/ignite/Ignite.java
+++ b/modules/core/src/main/java/org/apache/ignite/Ignite.java
@@ -11,6 +11,7 @@ package org.apache.ignite;
import org.apache.ignite.cluster.*;
import org.apache.ignite.configuration.*;
+import org.apache.ignite.fs.IgniteFsConfiguration;
import org.apache.ignite.plugin.*;
import org.apache.ignite.product.*;
import org.gridgain.grid.*;
@@ -205,9 +206,9 @@ public interface Ignite extends AutoCloseable {
* @param <V> Value type.
* @param name Cache name.
* @return Cache instance for given name.
- * @see org.apache.ignite.fs.IgniteFsConfiguration
- * @see org.apache.ignite.fs.IgniteFsConfiguration#getDataCacheName()
- * @see org.apache.ignite.fs.IgniteFsConfiguration#getMetaCacheName()
+ * @see IgniteFsConfiguration
+ * @see IgniteFsConfiguration#getDataCacheName()
+ * @see IgniteFsConfiguration#getMetaCacheName()
*/
public <K, V> GridCache<K, V> cache(@Nullable String name);
@@ -215,14 +216,23 @@ public interface Ignite extends AutoCloseable {
* Gets all configured caches.
* Caches that are used as GGFS meta and data caches will not be returned in resulting collection.
*
- * @see org.apache.ignite.fs.IgniteFsConfiguration
- * @see org.apache.ignite.fs.IgniteFsConfiguration#getDataCacheName()
- * @see org.apache.ignite.fs.IgniteFsConfiguration#getMetaCacheName()
+ * @see IgniteFsConfiguration
+ * @see IgniteFsConfiguration#getDataCacheName()
+ * @see IgniteFsConfiguration#getMetaCacheName()
* @return All configured caches.
*/
public Collection<GridCache<?, ?>> caches();
/**
+ * Gets an instance of {@link IgniteCache} API. {@code IgniteCache} is a fully-compatible
+ * implementation of {@code JCache (JSR 107)} specification.
+ *
+ * @param name Cache name.
+ * @return Instance of the cache for the specified name.
+ */
+ public <K, V> GridCache<K, V> jcache(@Nullable String name);
+
+ /**
* Gets grid transactions facade.
*
* @return Grid transactions facade.
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
new file mode 100644
index 0000000..6a05ce5
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -0,0 +1,300 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite;
+
+import org.apache.ignite.cache.*;
+import org.apache.ignite.cache.query.*;
+import org.apache.ignite.lang.*;
+import org.gridgain.grid.cache.*;
+import org.jetbrains.annotations.*;
+
+import javax.cache.*;
+import javax.cache.expiry.*;
+import java.util.*;
+import java.util.concurrent.locks.*;
+
+/**
+ * Main entry point for all <b>Data Grid APIs.</b> You can get a named cache by calling {@link Ignite#cache(String)}
+ * method.
+ * <h1 class="header">Functionality</h1>
+ * This API extends {@link org.gridgain.grid.cache.GridCacheProjection} API which contains vast majority of cache functionality
+ * and documentation. In addition to {@link org.gridgain.grid.cache.GridCacheProjection} functionality this API provides:
+ * <ul>
+ * <li>
+ * Various {@code 'loadCache(..)'} methods to load cache either synchronously or asynchronously.
+ * These methods don't specify any keys to load, and leave it to the underlying storage to load cache
+ * data based on the optionally passed in arguments.
+ * </li>
+ * <li>
+ * Method {@link #affinity()} provides {@link org.gridgain.grid.cache.affinity.GridCacheAffinityFunction} service for information on
+ * data partitioning and mapping keys to grid nodes responsible for caching those keys.
+ * </li>
+ * <li>
+ * Method {@link #dataStructures()} provides {@link org.gridgain.grid.cache.datastructures.GridCacheDataStructures} service for
+ * creating and working with distributed concurrent data structures, such as
+ * {@link IgniteAtomicLong}, {@link IgniteAtomicReference}, {@link org.gridgain.grid.cache.datastructures.GridCacheQueue}, etc.
+ * </li>
+ * <li>
+ * Methods like {@code 'tx{Un}Synchronize(..)'} witch allow to get notifications for transaction state changes.
+ * This feature is very useful when integrating cache transactions with some other in-house transactions.
+ * </li>
+ * <li>Method {@link #metrics()} to provide metrics for the whole cache.</li>
+ * <li>Method {@link #getConfiguration()} to provide cache configuration bean.</li>
+ * </ul>
+ *
+ * @param <K> Cache key type.
+ * @param <V> Cache value type.
+ */
+public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncSupport {
+ /** {@inheritDoc} */
+ public @Override IgniteCache<K, V> enableAsync();
+
+ /** {@inheritDoc} */
+ public @Override CacheConfiguration<K, V> getConfiguration();
+
+ /**
+ * Gets a random entry out of cache. In the worst cache scenario this method
+ * has complexity of <pre>O(S * N/64)</pre> where {@code N} is the size of internal hash
+ * table and {@code S} is the number of hash table buckets to sample, which is {@code 5}
+ * by default. However, if the table is pretty dense, with density factor of {@code N/64},
+ * which is true for near fully populated caches, this method will generally perform significantly
+ * faster with complexity of O(S) where {@code S = 5}.
+ * <p>
+ * Note that this method is not available on {@link org.gridgain.grid.cache.GridCacheProjection} API since it is
+ * impossible (or very hard) to deterministically return a number value when pre-filtering
+ * and post-filtering is involved (e.g. projection level predicate filters).
+ *
+ * @return Random entry, or {@code null} if cache is empty.
+ */
+ @Nullable public Entry<K, V> randomEntry();
+
+ public IgniteCache<K, V> withExpiryPolicy(ExpiryPolicy plc);
+
+ /**
+ * Executes {@link #localLoadCache(IgniteBiPredicate, Object...)} on all cache nodes.
+ *
+ * @param p Optional predicate (may be {@code null}). If provided, will be used to
+ * filter values to be put into cache.
+ * @param args Optional user arguments to be passed into
+ * {@link org.gridgain.grid.cache.store.GridCacheStore#loadCache(IgniteBiInClosure, Object...)} method.
+ * @throws CacheException If loading failed.
+ */
+ public void loadCache(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args) throws CacheException;
+
+ /**
+ * Delegates to {@link org.gridgain.grid.cache.store.GridCacheStore#loadCache(IgniteBiInClosure,Object...)} method
+ * to load state from the underlying persistent storage. The loaded values
+ * will then be given to the optionally passed in predicate, and, if the predicate returns
+ * {@code true}, will be stored in cache. If predicate is {@code null}, then
+ * all loaded values will be stored in cache.
+ * <p>
+ * Note that this method does not receive keys as a parameter, so it is up to
+ * {@link org.gridgain.grid.cache.store.GridCacheStore} implementation to provide all the data to be loaded.
+ * <p>
+ * This method is not transactional and may end up loading a stale value into
+ * cache if another thread has updated the value immediately after it has been
+ * loaded. It is mostly useful when pre-loading the cache from underlying
+ * data store before start, or for read-only caches.
+ *
+ * @param p Optional predicate (may be {@code null}). If provided, will be used to
+ * filter values to be put into cache.
+ * @param args Optional user arguments to be passed into
+ * {@link org.gridgain.grid.cache.store.GridCacheStore#loadCache(IgniteBiInClosure, Object...)} method.
+ * @throws CacheException If loading failed.
+ */
+ public void localLoadCache(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args) throws CacheException;
+
+ /**
+ * Stores given key-value pair in cache only if cache had no previous mapping for it. If cache
+ * previously contained value for the given key, then this value is returned.
+ * In case of {@link org.gridgain.grid.cache.GridCacheMode#PARTITIONED} or {@link org.gridgain.grid.cache.GridCacheMode#REPLICATED} caches,
+ * the value will be loaded from the primary node, which in its turn may load the value
+ * from the swap storage, and consecutively, if it's not in swap,
+ * from the underlying persistent storage. If value has to be loaded from persistent
+ * storage, {@link org.gridgain.grid.cache.store.GridCacheStore#load(org.gridgain.grid.cache.GridCacheTx, Object)} method will be used.
+ * <p>
+ * If the returned value is not needed, method {@link #putIfAbsent(Object, Object)} should
+ * always be used instead of this one to avoid the overhead associated with returning of the
+ * previous value.
+ * <p>
+ * If write-through is enabled, the stored value will be persisted to {@link org.gridgain.grid.cache.store.GridCacheStore}
+ * via {@link org.gridgain.grid.cache.store.GridCacheStore#put(org.gridgain.grid.cache.GridCacheTx, Object, Object)} method.
+ * <h2 class="header">Transactions</h2>
+ * This method is transactional and will enlist the entry into ongoing transaction
+ * if there is one.
+ * <h2 class="header">Cache Flags</h2>
+ * This method is not available if any of the following flags are set on projection:
+ * {@link org.gridgain.grid.cache.GridCacheFlag#LOCAL}, {@link org.gridgain.grid.cache.GridCacheFlag#READ}.
+ *
+ * @param key Key to store in cache.
+ * @param val Value to be associated with the given key.
+ * @return Previously contained value regardless of whether put happened or not.
+ * @throws NullPointerException If either key or value are {@code null}.
+ * @throws CacheException If put operation failed.
+ * @throws org.gridgain.grid.cache.GridCacheFlagException If projection flags validation failed.
+ */
+ @Nullable public V getAndPutIfAbsent(K key, V val) throws CacheException;
+
+ /**
+ * Removes mappings from cache for entries for which the optionally passed in filters do
+ * pass. If passed in filters are {@code null}, then all entries in cache will be enrolled
+ * into transaction.
+ * <p>
+ * <b>USE WITH CARE</b> - if your cache has many entries that pass through the filter or if filter
+ * is empty, then transaction will quickly become very heavy and slow. Also, locks
+ * are acquired in undefined order, so it may cause a deadlock when used with
+ * other concurrent transactional updates.
+ * <p>
+ * If write-through is enabled, the values will be removed from {@link org.gridgain.grid.cache.store.GridCacheStore}
+ * via {@link org.gridgain.grid.cache.store.GridCacheStore#removeAll(org.gridgain.grid.cache.GridCacheTx, java.util.Collection)} method.
+ * <h2 class="header">Transactions</h2>
+ * This method is transactional and will enlist the entry into ongoing transaction
+ * if there is one.
+ * <h2 class="header">Cache Flags</h2>
+ * This method is not available if any of the following flags are set on projection:
+ * {@link org.gridgain.grid.cache.GridCacheFlag#LOCAL}, {@link org.gridgain.grid.cache.GridCacheFlag#READ}.
+ *
+ * @param filter Filter used to supply keys for remove operation (if {@code null},
+ * then nothing will be removed).
+ * @throws CacheException If remove failed.
+ * @throws org.gridgain.grid.cache.GridCacheFlagException If flags validation failed.
+ */
+ public void removeAll(IgnitePredicate<Entry<K, V>> filter) throws CacheException;
+
+ public Lock lock(K key) throws CacheException;
+
+ public Lock lockAll(Set<K> keys) throws CacheException;
+
+ /**
+ * Checks if any node owns a lock for this key.
+ * <p>
+ * This is a local in-VM operation and does not involve any network trips
+ * or access to persistent storage in any way.
+ *
+ * @param key Key to check.
+ * @return {@code True} if lock is owned by some node.
+ */
+ public boolean isLocked(K key);
+
+ /**
+ * Checks if current thread owns a lock on this key.
+ * <p>
+ * This is a local in-VM operation and does not involve any network trips
+ * or access to persistent storage in any way.
+ *
+ * @param key Key to check.
+ * @return {@code True} if key is locked by current thread.
+ */
+ public boolean isLockedByThread(K key);
+
+ public QueryCursor<Entry<K, V>> query(QueryPredicate<K, V> filter);
+
+ public <R> QueryCursor<R> query(QueryReducer<Entry<K, V>, R> rmtRdc, QueryPredicate<K, V> filter);
+
+ public QueryCursor<List<?>> queryFields(QuerySqlPredicate<K, V> filter);
+
+ public <R> QueryCursor<R> queryFields(QueryReducer<List<?>, R> rmtRdc, QuerySqlPredicate<K, V> filter);
+
+ public QueryCursor<Entry<K, V>> localQuery(QueryPredicate<K, V> filter);
+
+ public QueryCursor<List<?>> localQueryFields(QuerySqlPredicate<K, V> filter);
+
+ public Iterable<Entry<K, V>> localEntries(GridCachePeekMode... peekModes) throws CacheException;
+
+ public Map<K, V> localPartition(int part) throws CacheException;
+
+ /**
+ * Attempts to evict all entries associated with keys. Note,
+ * that entry will be evicted only if it's not used (not
+ * participating in any locks or transactions).
+ * <p>
+ * If {@link org.gridgain.grid.cache.GridCacheConfiguration#isSwapEnabled()} is set to {@code true} and
+ * {@link org.gridgain.grid.cache.GridCacheFlag#SKIP_SWAP} is not enabled, the evicted entry will
+ * be swapped to offheap, and then to disk.
+ * <h2 class="header">Cache Flags</h2>
+ * This method is not available if any of the following flags are set on projection:
+ * {@link org.gridgain.grid.cache.GridCacheFlag#READ}.
+ *
+ * @param keys Keys to evict.
+ */
+ public void localEvict(Collection<? extends K> keys);
+
+ /**
+ * Peeks at in-memory cached value using default {@link org.gridgain.grid.cache.GridCachePeekMode#SMART}
+ * peek mode.
+ * <p>
+ * This method will not load value from any persistent store or from a remote node.
+ * <h2 class="header">Transactions</h2>
+ * This method does not participate in any transactions, however, it will
+ * peek at transactional value according to the {@link org.gridgain.grid.cache.GridCachePeekMode#SMART} mode
+ * semantics. If you need to look at global cached value even from within transaction,
+ * you can use {@link org.gridgain.grid.cache.GridCache#peek(Object, java.util.Collection)} method.
+ *
+ * @param key Entry key.
+ * @return Peeked value.
+ * @throws NullPointerException If key is {@code null}.
+ */
+ @Nullable public V localPeek(K key, GridCachePeekMode... peekModes);
+
+ /**
+ * This method unswaps cache entries by given keys, if any, from swap storage
+ * into memory.
+ * <h2 class="header">Transactions</h2>
+ * This method is not transactional.
+ * <h2 class="header">Cache Flags</h2>
+ * This method is not available if any of the following flags are set on projection:
+ * {@link org.gridgain.grid.cache.GridCacheFlag#SKIP_SWAP}, {@link org.gridgain.grid.cache.GridCacheFlag#READ}.
+ *
+ * @param keys Keys to promote entries for.
+ * @throws CacheException If promote failed.
+ * @throws org.gridgain.grid.cache.GridCacheFlagException If flags validation failed.
+ */
+ public void localPromote(Set<? extends K> keys) throws CacheException;
+
+ /**
+ * Clears an entry from this cache and swap storage only if the entry
+ * is not currently locked, and is not participating in a transaction.
+ * <p>
+ * If {@link org.gridgain.grid.cache.GridCacheConfiguration#isSwapEnabled()} is set to {@code true} and
+ * {@link org.gridgain.grid.cache.GridCacheFlag#SKIP_SWAP} is not enabled, the evicted entries will
+ * also be cleared from swap.
+ * <p>
+ * Note that this operation is local as it merely clears
+ * an entry from local cache. It does not remove entries from
+ * remote caches or from underlying persistent storage.
+ * <h2 class="header">Cache Flags</h2>
+ * This method is not available if any of the following flags are set on projection:
+ * {@link org.gridgain.grid.cache.GridCacheFlag#READ}.
+ *
+ * @param keys Keys to clear.
+ * @return {@code True} if entry was successfully cleared from cache, {@code false}
+ * if entry was in use at the time of this method invocation and could not be
+ * cleared.
+ */
+ public boolean clear(Collection<? extends K> keys);
+
+ /**
+ * Gets the number of all entries cached across all nodes.
+ * <p>
+ * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+ *
+ * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
+ * @return Cache size across all nodes.
+ */
+ public int size(CachePeekMode... peekModes) throws CacheException;
+
+ /**
+ * Gets the number of all entries cached on this nodes.
+ *
+ * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
+ * @return Cache size on this node.
+ */
+ public int localSize(CachePeekMode... peekModes);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/cache/CacheConfiguration.java
new file mode 100644
index 0000000..617f65f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheConfiguration.java
@@ -0,0 +1,23 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache;
+
+import javax.cache.configuration.*;
+
+/**
+ * TODO: Add class description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+// TODO: remove 'abstract'
+public abstract class CacheConfiguration<K, V> extends Configuration<K, V> {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/CacheEntryEvent.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CacheEntryEvent.java b/modules/core/src/main/java/org/apache/ignite/cache/CacheEntryEvent.java
new file mode 100644
index 0000000..42c6158
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheEntryEvent.java
@@ -0,0 +1,36 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache;
+
+import org.apache.ignite.*;
+
+import javax.cache.event.*;
+import java.util.*;
+
+/**
+ * TODO: Add class description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public abstract class CacheEntryEvent<K, V> extends javax.cache.event.CacheEntryEvent<K, V> {
+ /** */
+ private UUID nodeId;
+
+ protected CacheEntryEvent(IgniteCache source, EventType eventType, UUID nodeId) {
+ super(source, eventType);
+
+ this.nodeId = nodeId;
+ }
+
+ public UUID getNodeId() {
+ return nodeId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/CacheFlag.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CacheFlag.java b/modules/core/src/main/java/org/apache/ignite/cache/CacheFlag.java
new file mode 100644
index 0000000..4e89e6d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CacheFlag.java
@@ -0,0 +1,68 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache;
+
+import org.jetbrains.annotations.*;
+
+/**
+ * TODO:
+ * 1. Get rid of SKIP_STORE, SKIP_SWAP, LOCAL, READ, CLONE
+ * 2. Other properties should be moved to cache configuration.
+ * 3. This enum should become obsolete and removed.
+ */
+public enum CacheFlag {
+ /** Skips store, i.e. no read-through and no write-through behavior. */
+ SKIP_STORE,
+
+ /** Skip swap space for reads and writes. */
+ SKIP_SWAP,
+
+ /** Always get data from primary node (never from backup). */
+ GET_PRIMARY,
+
+ /** Synchronous commit. */
+ SYNC_COMMIT,
+
+ /**
+ * Switches a cache projection to work in {@code 'invalidation'} mode.
+ * Instead of updating remote entries with new values, small invalidation
+ * messages will be sent to set the values to {@code null}.
+ *
+ * @see org.gridgain.grid.cache.GridCacheTx#isInvalidate()
+ * @see org.gridgain.grid.cache.GridCacheConfiguration#isInvalidate()
+ */
+ INVALIDATE,
+
+ /**
+ * Skips version check during {@link org.gridgain.grid.cache.GridCacheProjection#transform(Object, GridClosure)} writes in
+ * {@link org.gridgain.grid.cache.GridCacheAtomicityMode#ATOMIC} mode. By default, in {@code ATOMIC} mode, whenever
+ * {@code transform(...)} is called, cache values (and not the {@code transform} closure) are sent from primary
+ * node to backup nodes to ensure proper update ordering.
+ * <p>
+ * By setting this flag, version check is skipped, and the {@code transform} closure is applied on both, primary
+ * and backup nodes. Use this flag for better performance if you are sure that there are no
+ * concurrent updates happening for the same key when {@code transform(...)} method is called.
+ */
+ FORCE_TRANSFORM_BACKUP;
+
+ /** */
+ private static final CacheFlag[] VALS = values();
+
+ /**
+ * Efficiently gets enumerated value from its ordinal.
+ *
+ * @param ord Ordinal value.
+ * @return Enumerated value or {@code null} if ordinal out of range.
+ */
+ @Nullable
+ public static CacheFlag fromOrdinal(int ord) {
+ return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/CachePeekMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CachePeekMode.java b/modules/core/src/main/java/org/apache/ignite/cache/CachePeekMode.java
new file mode 100644
index 0000000..67aac63
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/CachePeekMode.java
@@ -0,0 +1,72 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+* __ ____/___________(_)______ /__ ____/______ ____(_)_______
+* _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+* / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+* \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+*/
+
+package org.apache.ignite.cache;
+
+import org.jetbrains.annotations.*;
+
+/**
+ * Enumeration of all supported cache peek modes. Peek modes can be passed into various
+ * {@code 'GridCacheProjection.peek(..)'} and {@code GridCacheEntry.peek(..)} methods,
+ * such as {@link org.gridgain.grid.cache.GridCacheProjection#peek(Object, java.util.Collection)},
+ * {@link org.gridgain.grid.cache.GridCacheEntry#peek()}, and others.
+ * <p>
+ * The following modes are supported:
+ * <ul>
+ * <li>{@link #ALL}</li>
+ * <li>{@link #NEAR}</li>
+ * <li>{@link #PRIMARY}</li>
+ * <li>{@link #BACKUP}</li>
+ * <li>{@link #ONHEAP}</li>
+ * <li>{@link #OFFHEAP}</li>
+ * <li>{@link #SWAP}</li>
+ * </ul>
+ */
+public enum CachePeekMode {
+ /** Peeks into all available cache storages. */
+ ALL,
+
+ /**
+ * Peek into near cache only (don't peek into partitioned cache).
+ * In case of {@link org.gridgain.grid.cache.GridCacheMode#LOCAL} cache, behaves as {@link #ALL} mode.
+ */
+ NEAR,
+
+ /**
+ * Peek value from primary copy of partitioned cache only (skip near cache).
+ */
+ PRIMARY,
+
+ /**
+ * Peek value from backup copies of partitioned cache only (skip near cache).
+ */
+ BACKUP,
+
+ /** Peeks value from the on-heap storage only. */
+ ONHEAP,
+
+ /** Peeks value from the off-heap storage only, without loading off-heap value into cache. */
+ OFFHEAP,
+
+ /** Peeks value from the swap storage only, without loading swapped value into cache. */
+ SWAP;
+
+ /** Enumerated values. */
+ private static final CachePeekMode[] VALS = values();
+
+ /**
+ * Efficiently gets enumerated value from its ordinal.
+ *
+ * @param ord Ordinal value.
+ * @return Enumerated value or {@code null} if ordinal out of range.
+ */
+ @Nullable public static CachePeekMode fromOrdinal(byte ord) {
+ return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java
new file mode 100644
index 0000000..e3fa614
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java
@@ -0,0 +1,39 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.eviction;
+
+import org.jetbrains.annotations.*;
+
+import javax.cache.*;
+
+/**
+ * Evictable cache entry passed into {@link org.gridgain.grid.cache.eviction.GridCacheEvictionPolicy}.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public interface EvictableEntry extends Cache.Entry {
+ /**
+ * Attaches metadata to the entry.
+ *
+ * @param meta Metadata to attach. Pass {@code null} to remove previous value.
+ * @return Previous metadata value.
+ */
+ public <T> T attachMeta(@Nullable Object meta);
+
+ /**
+ * Replaces entry metadata.
+ *
+ * @param oldMeta Old metadata value, possibly {@code null}.
+ * @param newMeta New metadata value, possibly {@code null}.
+ * @return {@code True} if metadata value was replaced.
+ */
+ public boolean replaceMeta(@Nullable Object oldMeta, @Nullable Object newMeta);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryAffinityPredicate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryAffinityPredicate.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryAffinityPredicate.java
new file mode 100644
index 0000000..07c52f9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryAffinityPredicate.java
@@ -0,0 +1,124 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import org.gridgain.grid.util.typedef.internal.*;
+
+import javax.cache.*;
+
+/**
+ * TODO: Add class description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public final class QueryAffinityPredicate<K, V> extends QueryPredicate<K, V> {
+ /** Predicate. */
+ private QueryPredicate<K, V> p;
+
+ /** Keys. */
+ private K[] keys;
+
+ /** Partitions. */
+ private int[] parts;
+
+ /**
+ * Empty constructor.
+ */
+ public QueryAffinityPredicate() {
+ // No-op.
+ }
+
+ /**
+ * Constructs affinity predicate with specified affinity keys.
+ *
+ * @param p Predicate.
+ * @param keys Affinity keys.
+ */
+ public QueryAffinityPredicate(QueryPredicate<K, V> p, K... keys) {
+ this.p = p;
+ this.keys = keys;
+ }
+
+ /**
+ * Constructs affinity predicate with specified affinity partitions.
+ *
+ * @param p Predicate.
+ * @param parts Affinity partitions.
+ */
+ public QueryAffinityPredicate(QueryPredicate<K, V> p, int[] parts) {
+ this.p = p;
+ this.parts = parts;
+ }
+
+ /**
+ * Gets wrapped predicate.
+ *
+ * @return Wrapped predicate.
+ */
+ public QueryPredicate<K, V> getPredicate() {
+ return p;
+ }
+
+ /**
+ * Sets wrapped predicate.
+ *
+ * @param p Wrapped predicate.
+ */
+ public void setPredicate(QueryPredicate<K, V> p) {
+ this.p = p;
+ }
+
+ /**
+ * Gets affinity keys.
+ *
+ * @return Affinity keys.
+ */
+ public K[] getKeys() {
+ return keys;
+ }
+
+ /**
+ * Sets affinity keys.
+ *
+ * @param keys Affinity keys.
+ */
+ public void setKeys(K... keys) {
+ this.keys = keys;
+ }
+
+ /**
+ * Gets affinity partitions.
+ *
+ * @return Affinity partitions.
+ */
+ public int[] getPartitions() {
+ return parts;
+ }
+
+ /**
+ * Sets affinity partitions.
+ *
+ * @param parts Affinity partitions.
+ */
+ public void setPartitions(int... parts) {
+ this.parts = parts;
+ }
+
+ /** {@inheritDoc} */
+ @Override public final boolean apply(Cache.Entry<K, V> entry) {
+ return p.apply(entry);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryAffinityPredicate.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryContinuousPredicate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryContinuousPredicate.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryContinuousPredicate.java
new file mode 100644
index 0000000..e508d1e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryContinuousPredicate.java
@@ -0,0 +1,204 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import org.gridgain.grid.*;
+
+import javax.cache.*;
+import javax.cache.event.*;
+
+/**
+ * API for configuring and executing continuous cache queries.
+ * <p>
+ * Continuous queries are executed as follows:
+ * <ol>
+ * <li>
+ * Query is sent to requested grid nodes. Note that for {@link org.gridgain.grid.cache.GridCacheMode#LOCAL LOCAL}
+ * and {@link org.gridgain.grid.cache.GridCacheMode#REPLICATED REPLICATED} caches query will be always executed
+ * locally.
+ * </li>
+ * <li>
+ * Each node iterates through existing cache data and registers listeners that will
+ * notify about further updates.
+ * <li>
+ * Each key-value pair is passed through optional filter and if this filter returns
+ * true, key-value pair is sent to the master node (the one that executed query).
+ * If filter is not provided, all pairs are sent.
+ * </li>
+ * <li>
+ * When master node receives key-value pairs, it notifies the local callback.
+ * </li>
+ * </ol>
+ * <h2 class="header">NOTE</h2>
+ * Under some concurrent circumstances callback may get several notifications
+ * for one cache update. This should be taken into account when implementing callback.
+ * <h1 class="header">Query usage</h1>
+ * As an example, suppose we have cache with {@code 'Person'} objects and we need
+ * to query all persons with salary above 1000.
+ * <p>
+ * Here is the {@code Person} class:
+ * <pre name="code" class="java">
+ * public class Person {
+ * // Name.
+ * private String name;
+ *
+ * // Salary.
+ * private double salary;
+ *
+ * ...
+ * }
+ * </pre>
+ * <p>
+ * You can create and execute continuous query like so:
+ * <pre name="code" class="java">
+ * // Create new continuous query.
+ * qry = cache.createContinuousQuery();
+ *
+ * // Callback that is called locally when update notifications are received.
+ * // It simply prints out information about all created persons.
+ * qry.callback(new GridPredicate2<UUID, Collection<Map.Entry<UUID, Person>>>() {
+ * @Override public boolean apply(UUID uuid, Collection<Map.Entry<UUID, Person>> entries) {
+ * for (Map.Entry<UUID, Person> e : entries) {
+ * Person p = e.getValue();
+ *
+ * X.println(">>>");
+ * X.println(">>> " + p.getFirstName() + " " + p.getLastName() +
+ * "'s salary is " + p.getSalary());
+ * X.println(">>>");
+ * }
+ *
+ * return true;
+ * }
+ * });
+ *
+ * // This query will return persons with salary above 1000.
+ * qry.filter(new GridPredicate2<UUID, Person>() {
+ * @Override public boolean apply(UUID uuid, Person person) {
+ * return person.getSalary() > 1000;
+ * }
+ * });
+ *
+ * // Execute query.
+ * qry.execute();
+ * </pre>
+ * This will execute query on all nodes that have cache you are working with and notify callback
+ * with both data that already exists in cache and further updates.
+ * <p>
+ * To stop receiving updates call {@link #close()} method:
+ * <pre name="code" class="java">
+ * qry.cancel();
+ * </pre>
+ * Note that one query instance can be executed only once. After it's cancelled, it's non-operational.
+ * If you need to repeat execution, use {@link org.gridgain.grid.cache.query.GridCacheQueries#createContinuousQuery()} method to create
+ * new query.
+ */
+// TODO: make class.
+public final class QueryContinuousPredicate<K, V> extends QueryPredicate<K, V> implements AutoCloseable {
+ /**
+ * Default buffer size. Size of {@code 1} means that all entries
+ * will be sent to master node immediately (buffering is disabled).
+ */
+ public static final int DFLT_BUF_SIZE = 1;
+
+ /** Maximum default time interval after which buffer will be flushed (if buffering is enabled). */
+ public static final long DFLT_TIME_INTERVAL = 0;
+
+ /**
+ * Default value for automatic unsubscription flag. Remote filters
+ * will be unregistered by default if master node leaves topology.
+ */
+ public static final boolean DFLT_AUTO_UNSUBSCRIBE = true;
+
+ public void setInitialPredicate(QueryPredicate<K, V> filter) {
+ // TODO: implement.
+ }
+
+ /**
+ * Sets local callback. This callback is called only in local node when new updates are received.
+ * <p> The callback predicate accepts ID of the node from where updates are received and collection
+ * of received entries. Note that for removed entries value will be {@code null}.
+ * <p>
+ * If the predicate returns {@code false}, query execution will be cancelled.
+ * <p>
+ * <b>WARNING:</b> all operations that involve any kind of JVM-local or distributed locking (e.g.,
+ * synchronization or transactional cache operations), should be executed asynchronously without
+ * blocking the thread that called the callback. Otherwise, you can get deadlocks.
+ *
+ * @param locLsnr Local callback.
+ */
+ public void setLocalListener(CacheEntryUpdatedListener<K, V> locLsnr) {
+ // TODO: implement.
+ }
+
+ /**
+ * Sets optional key-value filter. This filter is called before entry is sent to the master node.
+ * <p>
+ * <b>WARNING:</b> all operations that involve any kind of JVM-local or distributed locking
+ * (e.g., synchronization or transactional cache operations), should be executed asynchronously
+ * without blocking the thread that called the filter. Otherwise, you can get deadlocks.
+ *
+ * @param filter Key-value filter.
+ */
+ public void setRemoteFilter(CacheEntryEventFilter<K, V> filter) {
+ // TODO: implement.
+ }
+
+ /**
+ * Sets buffer size. <p> When a cache update happens, entry is first put into a buffer. Entries from buffer will be
+ * sent to the master node only if the buffer is full or time provided via {@link #timeInterval(long)} method is
+ * exceeded. <p> Default buffer size is {@code 1} which means that entries will be sent immediately (buffering is
+ * disabled).
+ *
+ * @param bufSize Buffer size.
+ */
+ public void bufferSize(int bufSize) {
+ // TODO: implement.
+ }
+
+ /**
+ * Sets time interval. <p> When a cache update happens, entry is first put into a buffer. Entries from buffer will
+ * be sent to the master node only if the buffer is full (its size can be provided via {@link #bufferSize(int)}
+ * method) or time provided via this method is exceeded. <p> Default time interval is {@code 0} which means that
+ * time check is disabled and entries will be sent only when buffer is full.
+ *
+ * @param timeInterval Time interval.
+ */
+ public void timeInterval(long timeInterval) {
+ // TODO: implement.
+ }
+
+ /**
+ * Sets automatic unsubscribe flag. <p> This flag indicates that query filters on remote nodes should be
+ * automatically unregistered if master node (node that initiated the query) leaves topology. If this flag is {@code
+ * false}, filters will be unregistered only when the query is cancelled from master node, and won't ever be
+ * unregistered if master node leaves grid. <p> Default value for this flag is {@code true}.
+ *
+ * @param autoUnsubscribe Automatic unsubscription flag.
+ */
+ public void autoUnsubscribe(boolean autoUnsubscribe) {
+ // TODO: implement.
+ }
+
+ /**
+ * Stops continuous query execution. <p> Note that one query instance can be executed only once. After it's
+ * cancelled, it's non-operational. If you need to repeat execution, use {@link
+ * org.gridgain.grid.cache.query.GridCacheQueries#createContinuousQuery()} method to create new query.
+ *
+ * @throws org.gridgain.grid.GridException In case of error.
+ */
+ @Override public void close() throws GridException {
+ // TODO: implement.
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean apply(Cache.Entry<K, V> entry) {
+ return false; // TODO: CODE: implement.
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryCursor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryCursor.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryCursor.java
new file mode 100644
index 0000000..e903206
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryCursor.java
@@ -0,0 +1,29 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import java.util.*;
+
+/**
+ * TODO: Add interface description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public interface QueryCursor<T> extends Iterable<T> {
+ /**
+ * Gets all query results and stores them in the collection.
+ * Use this method when you know in advance that query result is
+ * relatively small and will not cause memory utilization issues.
+ *
+ * @return Collection containing full query result.
+ */
+ public Collection<T> getAll();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryPredicate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryPredicate.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryPredicate.java
new file mode 100644
index 0000000..a4cd7aa
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryPredicate.java
@@ -0,0 +1,68 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import org.apache.ignite.lang.*;
+import org.gridgain.grid.util.typedef.internal.*;
+
+import javax.cache.*;
+
+/**
+ * Query predicate to pass into any of {@code Cache.query(...)} methods.
+ * Use {@link QuerySqlPredicate} and {@link QueryTextPredicate} for SQL and
+ * text queries accordingly.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public abstract class QueryPredicate<K, V> implements IgnitePredicate<Cache.Entry<K, V>> {
+ /** Page size. */
+ private int pageSize;
+
+ /**
+ * Empty constructor.
+ */
+ protected QueryPredicate() {
+ // No-op.
+ }
+
+ /**
+ * Constructs query predicate with optional page size, if {@code 0},
+ * then {@link QueryConfiguration#getPageSize()} is used.
+ *
+ * @param pageSize Optional page size.
+ */
+ protected QueryPredicate(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ /**
+ * Gets optional page size, if {@code 0}, then {@link QueryConfiguration#getPageSize()} is used.
+ *
+ * @return Optional page size.
+ */
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ /**
+ * Sets optional page size, if {@code 0}, then {@link QueryConfiguration#getPageSize()} is used.
+ *
+ * @param pageSize Optional page size.
+ */
+ public void setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryPredicate.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryReducer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryReducer.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryReducer.java
new file mode 100644
index 0000000..c1f13e2
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryReducer.java
@@ -0,0 +1,22 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+/**
+ * TODO: Add class description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public interface QueryReducer<T, R> {
+ public int collect(T entry);
+
+ public R reduce();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QuerySqlPredicate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QuerySqlPredicate.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QuerySqlPredicate.java
new file mode 100644
index 0000000..219e98d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QuerySqlPredicate.java
@@ -0,0 +1,107 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import org.gridgain.grid.util.typedef.internal.*;
+
+import javax.cache.*;
+
+/**
+ * Query SQL predicate to use with any of the {@code JCache.query(...)} and
+ * {@code JCache.queryFields(...)} methods.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public final class QuerySqlPredicate<K, V> extends QueryPredicate<K, V> {
+ /** SQL clause. */
+ private String sql;
+
+ /** Arguments. */
+ private Object[] args;
+
+ /**
+ * Empty constructor.
+ */
+ public QuerySqlPredicate() {
+ // No-op.
+ }
+
+ /**
+ * Constructs SQL predicate with given SQL clause and arguments.
+ *
+ * @param sql SQL clause.
+ * @param args Arguments.
+ */
+ public QuerySqlPredicate(String sql, Object... args) {
+ this.sql = sql;
+ this.args = args;
+ }
+
+ /**
+ * Constructs SQL predicate with given SQL clause, page size, and arguments.
+ *
+ * @param sql SQL clause.
+ * @param pageSize Optional page size, if {@code 0}, then {@link QueryConfiguration#getPageSize()} is used.
+ * @param args Arguments.
+ */
+ public QuerySqlPredicate(String sql, int pageSize, Object[] args) {
+ super(pageSize);
+
+ this.sql = sql;
+ this.args = args;
+ }
+
+ /**
+ * Gets SQL clause.
+ *
+ * @return SQL clause.
+ */
+ public String getSql() {
+ return sql;
+ }
+
+ /**
+ * Sets SQL clause.
+ *
+ * @param sql SQL clause.
+ */
+ public void setSql(String sql) {
+ this.sql = sql;
+ }
+
+ /**
+ * Gets SQL arguments.
+ *
+ * @return SQL arguments.
+ */
+ public Object[] getArgs() {
+ return args;
+ }
+
+ /**
+ * Sets SQL arguments.
+ *
+ * @param args SQL arguments.
+ */
+ public void setArgs(Object... args) {
+ this.args = args;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean apply(Cache.Entry<K, V> entry) {
+ return false; // Not used.
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QuerySqlPredicate.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/QueryTextPredicate.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/QueryTextPredicate.java b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryTextPredicate.java
new file mode 100644
index 0000000..daeadc6
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/QueryTextPredicate.java
@@ -0,0 +1,79 @@
+// @java.file.header
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query;
+
+import org.gridgain.grid.util.typedef.internal.*;
+
+import javax.cache.*;
+
+/**
+ * TODO: Add class description.
+ *
+ * @author @java.author
+ * @version @java.version
+ */
+public final class QueryTextPredicate<K, V> extends QueryPredicate<K, V> {
+ /** SQL clause. */
+ private String txt;
+
+ /** Arguments. */
+ private Object[] args;
+
+ public QueryTextPredicate(String txt, Object... args) {
+ this.txt = txt;
+ this.args = args;
+ }
+
+ /**
+ * Gets text search string.
+ *
+ * @return Text search string.
+ */
+ public String getText() {
+ return txt;
+ }
+
+ /**
+ * Sets text search string.
+ *
+ * @param txt Text search string.
+ */
+ public void setText(String txt) {
+ this.txt = txt;
+ }
+
+ /**
+ * Gets text search arguments.
+ *
+ * @return Text search arguments.
+ */
+ public Object[] getArgs() {
+ return args;
+ }
+
+ /**
+ * Sets text search arguments.
+ *
+ * @param args Text search arguments.
+ */
+ public void setArgs(Object... args) {
+ this.args = args;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean apply(Cache.Entry<K, V> entry) {
+ return false; // Not used.
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(QueryTextPredicate.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/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
new file mode 100644
index 0000000..3cf14d0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java
@@ -0,0 +1,50 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Describes group index.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface QueryGroupIndex {
+ /**
+ * Group index name.
+ *
+ * @return Name.
+ */
+ String name();
+
+ /**
+ * If this index is unique.
+ *
+ * @return True if this index is unique, false otherwise.
+ * @deprecated No longer supported, will be ignored.
+ */
+ @Deprecated
+ boolean unique() default false;
+
+ /**
+ * List of group indexes for type.
+ */
+ @SuppressWarnings("PublicInnerClass")
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ public static @interface List {
+ /**
+ * Gets array of group indexes.
+ *
+ * @return Array of group indexes.
+ */
+ QueryGroupIndex[] value();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/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
new file mode 100644
index 0000000..18c3f49
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java
@@ -0,0 +1,125 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotates fields for SQL queries. All fields that will be involved in SQL clauses must have
+ * this annotation. For more information about cache queries see {@link org.gridgain.grid.cache.query.GridCacheQuery} documentation.
+ * @see org.gridgain.grid.cache.query.GridCacheQuery
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.FIELD})
+public @interface QuerySqlField {
+ /**
+ * Specifies whether cache should maintain an index for this field or not.
+ * Just like with databases, field indexing may require additional overhead
+ * during updates, but makes select operations faster.
+ * <p>
+ * When {@gglink org.gridgain.grid.spi.indexing.h2.GridH2IndexingSpi} is set as indexing SPI and indexed field is
+ * of type {@code com.vividsolutions.jts.geom.Geometry} (or any subclass of this class) then GridGain will
+ * consider this index as spatial providing performance boost for spatial queries.
+ *
+ * @return {@code True} if index must be created for this field in database.
+ */
+ boolean index() default false;
+
+ /**
+ * Specifies whether index should be unique or not. This property only
+ * makes sense if {@link #index()} property is set to {@code true}.
+ *
+ * @return {@code True} if field index should be unique.
+ * @deprecated No longer supported, will be ignored.
+ */
+ @Deprecated
+ boolean unique() default false;
+
+ /**
+ * Specifies whether index should be in descending order or not. This property only
+ * makes sense if {@link #index()} property is set to {@code true}.
+ *
+ * @return {@code True} if field index should be in descending order.
+ */
+ boolean descending() default false;
+
+ /**
+ * Array of index groups this field belongs to. Groups are used for compound indexes,
+ * whenever index should be created on more than one field. All fields within the same
+ * group will belong to the same index.
+ * <p>
+ * Group indexes are needed because SQL engine can utilize only one index per table occurrence in a query.
+ * For example if we have two separate indexes on fields {@code a} and {@code b} of type {@code X} then
+ * query {@code select * from X where a = ? and b = ?} will use for filtering either index on field {@code a}
+ * or {@code b} but not both. For more effective query execution here it is preferable to have a single
+ * group index on both fields.
+ * <p>
+ * For more complex scenarios please refer to {@link QuerySqlField.Group} documentation.
+ *
+ * @return Array of group names.
+ */
+ String[] groups() default {};
+
+ /**
+ * Array of ordered index groups this field belongs to. For more information please refer to
+ * {@linkplain QuerySqlField.Group} documentation.
+ *
+ * @return Array of ordered group indexes.
+ * @see #groups()
+ */
+ Group[] orderedGroups() default {};
+
+ /**
+ * Property name. If not provided then field name will be used.
+ *
+ * @return Name of property.
+ */
+ String name() default "";
+
+ /**
+ * 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.
+ * This can be needed in scenarios when we have a query like
+ * {@code select * from X where a = ? and b = ? order by b desc}. If we have index {@code (a asc, b asc)}
+ * sorting on {@code b} will be performed. Here it is preferable to have index {@code (b desc, a asc)}
+ * which will still allow query to search on index using both fields and avoid sorting because index
+ * is already sorted in needed way.
+ *
+ * @see #groups()
+ * @see #orderedGroups()
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.METHOD, ElementType.FIELD})
+ @SuppressWarnings("PublicInnerClass")
+ public static @interface Group {
+ /**
+ * Group index name where this field participate.
+ *
+ * @return Group index name
+ */
+ String name();
+
+ /**
+ * Fields in this group index will be sorted on this attribute.
+ *
+ * @return Order number.
+ */
+ int order();
+
+ /**
+ * Defines sorting order for this field in group.
+ *
+ * @return True if field will be in descending order.
+ */
+ boolean descending() default false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlFunction.java
new file mode 100644
index 0000000..943a7f1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlFunction.java
@@ -0,0 +1,59 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotates public static methods in classes to be used in SQL queries as custom functions.
+ * Annotated class must be registered in H2 indexing SPI using following method
+ * {@gglink org.gridgain.grid.spi.indexing.h2.GridH2IndexingSpi#setIndexCustomFunctionClasses(java.lang.Class[])}.
+ * <p>
+ * Example usage:
+ * <pre name="code" class="java">
+ * public class MyFunctions {
+ * @GridCacheQuerySqlFunction
+ * public static int sqr(int x) {
+ * return x * x;
+ * }
+ * }
+ *
+ * // Register.
+ * indexing.setIndexCustomFunctionClasses(MyFunctions.class);
+ *
+ * // And use in queries.
+ * cache.queries().createSqlFieldsQuery("select sqr(2) where sqr(1) = 1");
+ * </pre>
+ * <p>
+ * For more information about H2 custom functions please refer to
+ * <a href="http://www.h2database.com/html/features.html#user_defined_functions">H2 documentation</a>.
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface QuerySqlFunction {
+ /**
+ * Specifies alias for the function to be used form SQL queries.
+ * If no alias provided method name will be used.
+ *
+ * @return Alias for function.
+ */
+ String alias() default "";
+
+ /**
+ * Specifies if the function is deterministic (result depends only on input parameters).
+ * <p>
+ * Deterministic function is a function which always returns the same result
+ * assuming that input parameters are the same.
+ *
+ * @return {@code true} If function is deterministic, {@code false} otherwise.
+ */
+ boolean deterministic() default false;
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryTextField.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryTextField.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryTextField.java
new file mode 100644
index 0000000..30b6be1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryTextField.java
@@ -0,0 +1,25 @@
+/* @java.file.header */
+
+/* _________ _____ __________________ _____
+ * __ ____/___________(_)______ /__ ____/______ ____(_)_______
+ * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \
+ * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / /
+ * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/
+ */
+
+package org.apache.ignite.cache.query.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation for fields or getters to be indexed for full text
+ * search using {@code H2 TEXT} indexing. For more information
+ * refer to {@link org.gridgain.grid.cache.query.GridCacheQuery} documentation.
+ * @see org.gridgain.grid.cache.query.GridCacheQuery
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
+public @interface QueryTextField {
+ // No-op.
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java b/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
index d913605..bdc80b9 100644
--- a/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
+++ b/modules/core/src/main/java/org/gridgain/grid/kernal/GridKernal.java
@@ -2926,6 +2926,11 @@ public class GridKernal extends ClusterGroupAdapter implements GridEx, IgniteMBe
}
/** {@inheritDoc} */
+ @Override public <K, V> GridCache<K, V> jcache(@Nullable String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<GridCache<?, ?>> caches() {
guard();
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/a4f69c40/modules/spring/src/main/java/org/gridgain/grid/GridSpringBean.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/main/java/org/gridgain/grid/GridSpringBean.java b/modules/spring/src/main/java/org/gridgain/grid/GridSpringBean.java
index 28efd6c..370f542 100644
--- a/modules/spring/src/main/java/org/gridgain/grid/GridSpringBean.java
+++ b/modules/spring/src/main/java/org/gridgain/grid/GridSpringBean.java
@@ -257,6 +257,11 @@ public class GridSpringBean extends GridMetadataAwareAdapter implements Ignite,
}
/** {@inheritDoc} */
+ @Override public <K, V> GridCache<K, V> jcache(@Nullable String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteTransactions transactions() {
assert g != null;