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 <sboi...@gridgain.com> Authored: Wed Dec 10 14:31:47 2014 +0300 Committer: sboikov <sboi...@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;