diff --git a/examples/src/main/java/org/gridgain/examples/datagrid/CacheApiExample.java b/examples/src/main/java/org/gridgain/examples/datagrid/CacheApiExample.java index a30c20f..f05331f 100644 --- a/examples/src/main/java/org/gridgain/examples/datagrid/CacheApiExample.java +++ b/examples/src/main/java/org/gridgain/examples/datagrid/CacheApiExample.java @@ -11,9 +11,9 @@ package org.gridgain.examples.datagrid; import org.apache.ignite.*; import org.apache.ignite.lang.*; -import org.gridgain.grid.*; import org.gridgain.grid.cache.*; +import javax.cache.processor.*; import java.util.concurrent.*; /** @@ -61,55 +61,62 @@ public class CacheApiExample { System.out.println(); System.out.println(">>> Cache atomic map operation examples."); - GridCache cache = Ignition.ignite().cache(CACHE_NAME); + IgniteCache cache = Ignition.ignite().jcache(CACHE_NAME); // Put and return previous value. - String v = cache.put(1, "1"); + String v = cache.getAndPut(1, "1"); assert v == null; // Put and do not return previous value (all methods ending with 'x' return boolean). // Performs better when previous value is not needed. - cache.putx(2, "2"); + cache.put(2, "2"); - // Put asynchronously (every cache operation has async counterpart). - IgniteFuture fut = cache.putAsync(3, "3"); - // Asynchronously wait for result. - fut.listenAsync(new IgniteInClosure>() { - @Override public void apply(IgniteFuture fut) { - try { - System.out.println("Put operation completed [previous-value=" + fut.get() + ']'); - } - catch (IgniteCheckedException e) { - e.printStackTrace(); - } - } - }); + // Put asynchronously (every cache operation has async counterpart). + // TODO IGNITE-60: uncomment when implemented. +// IgniteFuture fut = cache.putAsync(3, "3"); +// +// // Asynchronously wait for result. +// fut.listenAsync(new IgniteInClosure>() { +// @Override public void apply(IgniteFuture fut) { +// try { +// System.out.println("Put operation completed [previous-value=" + fut.get() + ']'); +// } +// catch (IgniteCheckedException e) { +// e.printStackTrace(); +// } +// } +// }); // Put-if-absent. - boolean b1 = cache.putxIfAbsent(4, "4"); - boolean b2 = cache.putxIfAbsent(4, "44"); + boolean b1 = cache.putIfAbsent(4, "4"); + boolean b2 = cache.putIfAbsent(4, "44"); assert b1 && !b2; // Put-with-predicate, will succeed if predicate evaluates to true. - cache.putx(5, "5"); - cache.putx(5, "55", new IgnitePredicate>() { - @Override public boolean apply(GridCacheEntry e) { + cache.put(5, "5"); + cache.putIf(5, "55", new IgnitePredicate>() { + @Override + public boolean apply(GridCacheEntry e) { return "5".equals(e.peek()); // Update only if previous value is "5". } }); - // Transform - assign new value based on previous value. - cache.putx(6, "6"); - cache.transform(6, new IgniteClosure() { - @Override public String apply(String v) { - return v + "6"; // Set new value based on previous value. + // Invoke - assign new value based on previous value. + cache.put(6, "6"); + cache.invoke(6, new EntryProcessor() { + @Override public Void process(MutableEntry entry, Object... args) { + String v = entry.getValue(); + + entry.setValue(v + "6"); // Set new value based on previous value. + + return null; } }); // Replace. - cache.putx(7, "7"); + cache.put(7, "7"); b1 = cache.replace(7, "7", "77"); b2 = cache.replace(7, "7", "777"); assert b1 & !b2; diff --git a/examples/src/main/java/org/gridgain/examples/datagrid/CachePopularNumbersExample.java b/examples/src/main/java/org/gridgain/examples/datagrid/CachePopularNumbersExample.java index 69a1216..c9b8f1d 100644 --- a/examples/src/main/java/org/gridgain/examples/datagrid/CachePopularNumbersExample.java +++ b/examples/src/main/java/org/gridgain/examples/datagrid/CachePopularNumbersExample.java @@ -12,11 +12,10 @@ package org.gridgain.examples.datagrid; import org.apache.ignite.*; import org.apache.ignite.cluster.*; import org.apache.ignite.dataload.*; -import org.apache.ignite.lang.*; -import org.gridgain.grid.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.cache.query.*; +import javax.cache.processor.*; import java.util.*; /** @@ -153,16 +152,20 @@ public class CachePopularNumbersExample { */ private static class IncrementingUpdater implements IgniteDataLoadCacheUpdater { /** */ - private static final IgniteClosure INC = new IgniteClosure() { - @Override public Long apply(Long e) { - return e == null ? 1L : e + 1; + private static final EntryProcessor INC = new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Long val = e.getValue(); + + e.setValue(val == null ? 1L : val + 1); + + return null; } }; /** {@inheritDoc} */ - @Override public void update(GridCache cache, Collection> entries) throws IgniteCheckedException { + @Override public void update(IgniteCache cache, Collection> entries) { for (Map.Entry entry : entries) - cache.transform(entry.getKey(), INC); + cache.invoke(entry.getKey(), INC); } } } diff --git a/examples/src/main/scala/org/gridgain/scalar/examples/ScalarCachePopularNumbersExample.scala b/examples/src/main/scala/org/gridgain/scalar/examples/ScalarCachePopularNumbersExample.scala index 8546ab8..567cdf0 100644 --- a/examples/src/main/scala/org/gridgain/scalar/examples/ScalarCachePopularNumbersExample.scala +++ b/examples/src/main/scala/org/gridgain/scalar/examples/ScalarCachePopularNumbersExample.scala @@ -11,9 +11,10 @@ package org.gridgain.scalar.examples +import javax.cache.processor.{MutableEntry, EntryProcessor} + import org.apache.ignite.dataload.IgniteDataLoadCacheUpdater -import org.apache.ignite.IgniteCheckedException -import org.gridgain.grid.cache.GridCache +import org.apache.ignite.{IgniteCache, IgniteCheckedException} import java.util import java.util.Timer @@ -88,17 +89,7 @@ object ScalarCachePopularNumbersExample extends App { // Reduce parallel operations since we running the whole grid locally under heavy load. val ldr = dataLoader$[Int, Long](CACHE_NAME, 2048) - val f = (i: Long) => i + 1 - - // Set custom updater to increment value for each key. - ldr.updater(new IgniteDataLoadCacheUpdater[Int, Long] { - def update(cache: GridCache[Int, Long], entries: util.Collection[Entry[Int, Long]]) = { - import scala.collection.JavaConversions._ - - for (e <- entries) - cache.transform(e.getKey, f) - } - }) + // TODO IGNITE-44: restore invoke. (0 until CNT) foreach (_ => ldr.addData(Random.nextInt(RANGE), 1L)) diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java index a59573e..f7b2c34 100644 --- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java +++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java @@ -13,11 +13,13 @@ import org.apache.ignite.cache.*; import org.apache.ignite.cache.query.*; import org.apache.ignite.lang.*; import org.apache.ignite.transactions.*; +import org.gridgain.grid.cache.*; import org.jetbrains.annotations.*; import javax.cache.*; import javax.cache.configuration.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.locks.*; @@ -298,4 +300,194 @@ public interface IgniteCache extends javax.cache.Cache, IgniteAsyncS * @return Cache size on this node. */ public int localSize(CachePeekMode... peekModes); + + /** + * Stores given key-value pair in cache. If filters are provided, then entries will + * be stored in cache only if they pass the filter. Note that filter check is atomic, + * so value stored in cache is guaranteed to be consistent with the filters. If cache + * previously contained value for the given key, then this value is returned. + * In case of {@link GridCacheMode#PARTITIONED} or {@link 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(IgniteTx, Object)} method will be used. + *

+ * If the returned value is not needed, method {@link #putIf(Object, Object, IgnitePredicate)} should + * always be used instead of this one to avoid the overhead associated with returning of the previous value. + *

+ * 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(IgniteTx, Object, Object)} method. + *

Transactions

+ * This method is transactional and will enlist the entry into ongoing transaction + * if there is one. + *

Cache Flags

+ * This method is not available if any of the following flags are set on projection: + * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @param filter Optional filter to check prior to putting value in cache. Note + * that filter check is atomic with put operation. + * @return Previous value associated with specified key, or {@code null} + * if entry did not pass the filter, or if there was no mapping for the key in swap + * or in persistent storage. + * @throws NullPointerException If either key or value are {@code null}. + * @throws GridCacheFlagException If projection flags validation failed. + */ + // TODO IGNITE-1 fix entry type. + @Nullable public V getAndPutIf(K key, V val, @Nullable IgnitePredicate> filter); + + /** + * Stores given key-value pair in cache. If filters are provided, then entries will + * be stored in cache only if they pass the filter. Note that filter check is atomic, + * so value stored in cache is guaranteed to be consistent with the filters. + *

+ * This method will return {@code true} if value is stored in cache and {@code false} otherwise. + * Unlike {@link #getAndPutIf(Object, Object, IgnitePredicate)} method, it does not return previous + * value and, therefore, does not have any overhead associated with returning a value. It + * should be used whenever return value is not required. + *

+ * 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(IgniteTx, Object, Object)} method. + *

Transactions

+ * This method is transactional and will enlist the entry into ongoing transaction + * if there is one. + *

Cache Flags

+ * This method is not available if any of the following flags are set on projection: + * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @param filter Optional filter to check prior to putting value in cache. Note + * that filter check is atomic with put operation. + * @return {@code True} if optional filter passed and value was stored in cache, + * {@code false} otherwise. Note that this method will return {@code true} if filter is not + * specified. + * @throws NullPointerException If either key or value are {@code null}. + * @throws GridCacheFlagException If projection flags validation failed. + */ + // TODO IGNITE-1 fix entry type. + public boolean putIf(K key, V val, IgnitePredicate> filter); + + /** + * Removes given key mapping from cache. If cache previously contained value for the given key, + * then this value is returned. In case of {@link GridCacheMode#PARTITIONED} or {@link GridCacheMode#REPLICATED} + * caches, the value will be loaded from the primary node, which in its turn may load the value + * from the disk-based 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(IgniteTx, Object)} method will be used. + *

+ * If the returned value is not needed, method {@link #removeIf(Object, IgnitePredicate)} should + * always be used instead of this one to avoid the overhead associated with returning of the + * previous value. + *

+ * If write-through is enabled, the value will be removed from {@link org.gridgain.grid.cache.store.GridCacheStore} + * via {@link org.gridgain.grid.cache.store.GridCacheStore#remove(IgniteTx, Object)} method. + *

Transactions

+ * This method is transactional and will enlist the entry into ongoing transaction + * if there is one. + *

Cache Flags

+ * This method is not available if any of the following flags are set on projection: + * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. + * + * @param key Key whose mapping is to be removed from cache. + * @param filter Optional filter to check prior to removing value form cache. Note + * that filter is checked atomically together with remove operation. + * @return Previous value associated with specified key, or {@code null} + * if there was no value for this key. + * @throws NullPointerException If key is {@code null}. + * @throws GridCacheFlagException If projection flags validation failed. + */ + // TODO IGNITE-1 fix entry type. + public V getAndRemoveIf(K key, IgnitePredicate> filter); + + /** + * Removes given key mapping from cache. + *

+ * This method will return {@code true} if remove did occur, which means that all optionally + * provided filters have passed and there was something to remove, {@code false} otherwise. + *

+ * If write-through is enabled, the value will be removed from {@link org.gridgain.grid.cache.store.GridCacheStore} + * via {@link org.gridgain.grid.cache.store.GridCacheStore#remove(IgniteTx, Object)} method. + *

Transactions

+ * This method is transactional and will enlist the entry into ongoing transaction + * if there is one. + *

Cache Flags

+ * This method is not available if any of the following flags are set on projection: + * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. + * + * @param key Key whose mapping is to be removed from cache. + * @param filter Optional filter to check prior to removing value form cache. Note + * that filter is checked atomically together with remove operation. + * @return {@code True} if filter passed validation and entry was removed, {@code false} otherwise. + * Note that if filter is not specified, this method will return {@code true}. + * @throws NullPointerException if the key is {@code null}. + * @throws GridCacheFlagException If projection flags validation failed. + */ + // TODO IGNITE-1 fix entry type. + public boolean removeIf(K key, IgnitePredicate> filter); + + /** + * @param map Map containing keys and entry processors to be applied to values. + * @param args Additional arguments to pass to the {@link EntryProcessor}. + * @return The map of {@link EntryProcessorResult}s of the processing per key, + * if any, defined by the {@link EntryProcessor} implementation. No mappings + * will be returned for {@link EntryProcessor}s that return a + * null value for a key. + */ + Map> invokeAll(Map> map, Object... args); + + /** + * Creates projection that will operate with portable objects. + *

+ * Projection returned by this method will force cache not to deserialize portable objects, + * so keys and values will be returned from cache API methods without changes. Therefore, + * signature of the projection can contain only following types: + *

    + *
  • {@link org.apache.ignite.portables.PortableObject} for portable classes
  • + *
  • All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)
  • + *
  • Arrays of primitives (byte[], int[], ...)
  • + *
  • {@link String} and array of {@link String}s
  • + *
  • {@link UUID} and array of {@link UUID}s
  • + *
  • {@link Date} and array of {@link Date}s
  • + *
  • {@link java.sql.Timestamp} and array of {@link java.sql.Timestamp}s
  • + *
  • Enums and array of enums
  • + *
  • + * Maps, collections and array of objects (but objects inside + * them will still be converted if they are portable) + *
  • + *
+ *

+ * For example, if you use {@link Integer} as a key and {@code Value} class as a value + * (which will be stored in portable format), you should acquire following projection + * to avoid deserialization: + *

+     * GridCacheProjection prj = cache.keepPortable();
+     *
+     * // Value is not deserialized and returned in portable format.
+     * GridPortableObject po = prj.get(1);
+     * 
+ *

+ * Note that this method makes sense only if cache is working in portable mode + * ({@link org.gridgain.grid.cache.GridCacheConfiguration#isPortableEnabled()} returns {@code true}. If not, + * this method is no-op and will return current projection. + * + * @return Projection for portable objects. + */ + public IgniteCache keepPortable(); + + /** + * Gets cache projection base on this one, but with the specified flags turned on. + *

Cache Flags

+ * The resulting projection will inherit all the flags from this projection. + * + * @param flags Flags to turn on (if empty, then no-op). + * @return New projection based on this one, but with the specified flags turned on. + */ + public IgniteCache flagsOn(@Nullable GridCacheFlag... flags); + + /** + * @return Ignite instance. + */ + public Ignite ignite(); } diff --git a/modules/core/src/main/java/org/apache/ignite/cache/CachePartialUpdateException.java b/modules/core/src/main/java/org/apache/ignite/cache/CachePartialUpdateException.java new file mode 100644 index 0000000..08ce72e --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/CachePartialUpdateException.java @@ -0,0 +1,36 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.cache; + +import org.gridgain.grid.cache.*; + +import javax.cache.*; +import java.util.*; + +/** + * Exception thrown from non-transactional cache in case when update succeeded only partially. + * One can get list of keys for which update failed with method {@link #failedKeys()}. + */ +public class CachePartialUpdateException extends CacheException { + /** + * @param e Cause. + */ + public CachePartialUpdateException(GridCachePartialUpdateException e) { + super(e.getMessage(), e); + } + + /** + * Gets collection of failed keys. + * @return Collection of failed keys. + */ + public Collection failedKeys() { + return ((GridCachePartialUpdateException)getCause()).failedKeys(); + } +} diff --git a/modules/core/src/main/java/org/apache/ignite/dataload/IgniteDataLoadCacheUpdater.java b/modules/core/src/main/java/org/apache/ignite/dataload/IgniteDataLoadCacheUpdater.java index 88483b6..9c43db4 100644 --- a/modules/core/src/main/java/org/apache/ignite/dataload/IgniteDataLoadCacheUpdater.java +++ b/modules/core/src/main/java/org/apache/ignite/dataload/IgniteDataLoadCacheUpdater.java @@ -10,18 +10,17 @@ package org.apache.ignite.dataload; import org.apache.ignite.*; -import org.gridgain.grid.cache.*; import java.io.*; import java.util.*; /** - * Updates cache with batch of entries. Usually it is enough to configure {@link org.apache.ignite.IgniteDataLoader#isolated(boolean)} + * Updates cache with batch of entries. Usually it is enough to configure {@link IgniteDataLoader#isolated(boolean)} * property and appropriate internal cache updater will be chosen automatically. But in some cases to achieve best * performance custom user-defined implementation may help. *

* Data loader can be configured to use custom implementation of updater instead of default one using - * {@link org.apache.ignite.IgniteDataLoader#updater(IgniteDataLoadCacheUpdater)} method. + * {@link IgniteDataLoader#updater(IgniteDataLoadCacheUpdater)} method. */ public interface IgniteDataLoadCacheUpdater extends Serializable { /** @@ -31,5 +30,5 @@ public interface IgniteDataLoadCacheUpdater extends Serializable { * @param entries Collection of entries. * @throws IgniteCheckedException If failed. */ - public void update(GridCache cache, Collection> entries) throws IgniteCheckedException; + public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java index 3945234..a985fde 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java @@ -13,8 +13,11 @@ import 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.gridgain.grid.kernal.*; import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.util.tostring.*; +import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; @@ -30,7 +33,7 @@ import java.util.concurrent.locks.*; /** * Cache proxy. */ -public class IgniteCacheProxy implements IgniteCache, Externalizable { +public class IgniteCacheProxy extends IgniteAsyncSupportAdapter implements IgniteCache, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -51,10 +54,14 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable * @param ctx Context. * @param delegate Delegate. * @param prj Projection. + * @param async Async support flag. */ public IgniteCacheProxy(GridCacheContext ctx, GridCacheProjectionEx delegate, - @Nullable GridCacheProjectionImpl prj) { + @Nullable GridCacheProjectionImpl prj, + boolean async) { + super(async); + assert ctx != null; assert delegate != null; @@ -65,10 +72,26 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable gate = ctx.gate(); } + /** + * @return Context. + */ + public GridCacheContext context() { + return ctx; + } + + /** + * @return Ignite instance. + */ + @Override public GridEx ignite() { + return ctx.grid(); + } + /** {@inheritDoc} */ @Override public > C getConfiguration(Class clazz) { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + if (!clazz.equals(GridCacheConfiguration.class)) + throw new IllegalArgumentException(); + + return (C)ctx.config(); } /** {@inheritDoc} */ @@ -84,7 +107,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable try { GridCacheProjectionEx prj0 = prj != null ? prj.withExpiryPolicy(plc) : delegate.withExpiryPolicy(plc); - return new IgniteCacheProxy<>(ctx, prj0, (GridCacheProjectionImpl)prj0); + return new IgniteCacheProxy<>(ctx, prj0, (GridCacheProjectionImpl)prj0, isAsync()); } finally { gate.leave(prev); @@ -98,12 +121,81 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } /** {@inheritDoc} */ - @Override public void localLoadCache(@Nullable IgniteBiPredicate p, @Nullable Object... args) throws CacheException { + @Override public void localLoadCache(@Nullable IgniteBiPredicate p, @Nullable Object... args) + throws CacheException { // TODO IGNITE-1. throw new UnsupportedOperationException(); } /** {@inheritDoc} */ + @Nullable @Override public V getAndPutIf(K key, V val, IgnitePredicate> filter) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.put(key, val, filter); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** {@inheritDoc} */ + @Override public boolean putIf(K key, V val, IgnitePredicate> filter) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.putx(key, val, filter); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** {@inheritDoc} */ + @Override public V getAndRemoveIf(K key, IgnitePredicate> filter) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.remove(key, filter); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** {@inheritDoc} */ + @Override public boolean removeIf(K key, IgnitePredicate> filter) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.removex(key, filter); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** {@inheritDoc} */ @Nullable @Override public V getAndPutIfAbsent(K key, V val) throws CacheException { try { GridCacheProjectionImpl prev = gate.enter(prj); @@ -116,7 +208,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -215,7 +307,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -257,7 +349,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -274,7 +366,61 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); + } + } + + /** + * @param keys Keys. + * @return Values map. + */ + public Map getAll(Collection keys) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.getAll(keys); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** + * Gets entry set containing internal entries. + * + * @param filter Filter. + * @return Entry set. + */ + public Set> entrySetx(IgnitePredicate>... filter) { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return delegate.entrySetx(filter); + } + finally { + gate.leave(prev); + } + } + + /** + * @param filter Filter. + */ + public void removeAll(IgnitePredicate>... filter) { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + delegate.removeAll(filter); + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + finally { + gate.leave(prev); } } @@ -305,7 +451,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -322,7 +468,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -339,7 +485,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -356,7 +502,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -373,7 +519,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -390,7 +536,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -407,7 +553,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -424,7 +570,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -441,7 +587,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -458,7 +604,7 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); } } @@ -475,7 +621,26 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable } } catch (IgniteCheckedException e) { - throw new CacheException(e); + throw cacheException(e); + } + } + + /** + * @param keys Keys to remove. + */ + public void removeAll(Collection keys) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + delegate.removeAll(keys); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); } } @@ -494,16 +659,77 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable /** {@inheritDoc} */ @Override public T invoke(K key, EntryProcessor entryProcessor, Object... args) throws EntryProcessorException { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + if (isAsync()) { + IgniteFuture> fut = delegate.invokeAsync(key, entryProcessor, args); + + IgniteFuture fut0 = fut.chain(new CX1>, T>() { + @Override public T applyx(IgniteFuture> fut) + throws IgniteCheckedException { + EntryProcessorResult res = fut.get(); + + return res != null ? res.get() : null; + } + }); + + curFut.set(fut0); + + return null; + } + else { + EntryProcessorResult res = delegate.invoke(key, entryProcessor, args); + + return res != null ? res.get() : null; + } + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } } /** {@inheritDoc} */ @Override public Map> invokeAll(Set keys, EntryProcessor entryProcessor, Object... args) { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return saveOrGet(delegate.invokeAllAsync(keys, entryProcessor, args)); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll( + Map> map, + Object... args) { + try { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + return saveOrGet(delegate.invokeAllAsync(map, args)); + } + finally { + gate.leave(prev); + } + } + catch (IgniteCheckedException e) { + throw cacheException(e); + } } /** {@inheritDoc} */ @@ -594,20 +820,81 @@ public class IgniteCacheProxy implements IgniteCache, Externalizable /** {@inheritDoc} */ @Override public IgniteCache enableAsync() { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + if (isAsync()) + return this; + + return new IgniteCacheProxy<>(ctx, delegate, prj, true); } /** {@inheritDoc} */ - @Override public boolean isAsync() { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + @SuppressWarnings("unchecked") + @Override public IgniteCache keepPortable() { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + GridCacheProjectionImpl prj0 = new GridCacheProjectionImpl<>( + (GridCacheProjection)(prj != null ? prj : delegate), + (GridCacheContext)ctx, + null, + null, + prj != null ? prj.flags() : null, + prj != null ? prj.subjectId() : null, + true, + prj != null ? prj.expiry() : null); + + return new IgniteCacheProxy<>((GridCacheContext)ctx, + prj0, + prj0, + isAsync()); + } + finally { + gate.leave(prev); + } } /** {@inheritDoc} */ - @Override public IgniteFuture future() { - // TODO IGNITE-1. - throw new UnsupportedOperationException(); + @Override public IgniteCache flagsOn(@Nullable GridCacheFlag... flags) { + GridCacheProjectionImpl prev = gate.enter(prj); + + try { + Set res = EnumSet.noneOf(GridCacheFlag.class); + + Set flags0 = prj !=null ? prj.flags() : null; + + if (flags0 != null && !flags0.isEmpty()) + res.addAll(flags0); + + res.addAll(EnumSet.copyOf(F.asList(flags))); + + GridCacheProjectionImpl prj0 = new GridCacheProjectionImpl<>( + (prj != null ? prj : delegate), + ctx, + null, + null, + res, + prj != null ? prj.subjectId() : null, + true, + prj != null ? prj.expiry() : null); + + return new IgniteCacheProxy<>(ctx, + prj0, + prj0, + isAsync()); + } + finally { + gate.leave(prev); + } + } + + /** + * @param e Checked exception. + * @return Cache exception. + */ + private CacheException cacheException(IgniteCheckedException e) { + if (e instanceof GridCachePartialUpdateException) + return new CachePartialUpdateException((GridCachePartialUpdateException)e); + + return new CacheException(e); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheEntry.java b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheEntry.java index 6e61dc1..d494903 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheEntry.java @@ -315,27 +315,6 @@ public interface GridCacheEntry extends Map.Entry, GridMetadataAware /** * This method has the same semantic as - * {@link GridCacheProjection#transform(Object, org.apache.ignite.lang.IgniteClosure)} method. - * - * @param transformer Closure to be applied to the previous value in cache. If this closure returns - * {@code null}, the associated value will be removed from cache. - * @throws IgniteCheckedException If cache update failed. - * @see GridCacheProjection#transform(Object, org.apache.ignite.lang.IgniteClosure) - */ - public void transform(IgniteClosure transformer) throws IgniteCheckedException; - - /** - * This method has the same semantic as - * {@link GridCacheProjection#transformAsync(Object, org.apache.ignite.lang.IgniteClosure)} method. - * - * @param transformer Closure to be applied to the previous value in cache. If this closure returns - * {@code null}, the associated value will be removed from cache. - * @return Transform operation future. - */ - public IgniteFuture transformAsync(IgniteClosure transformer); - - /** - * This method has the same semantic as * {@link GridCacheProjection#replace(Object, Object)} method. * * @param val See {@link GridCacheProjection#replace(Object, Object)} diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheFlag.java b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheFlag.java index d57d7f7..f4805d4 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheFlag.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheFlag.java @@ -9,9 +9,12 @@ package org.gridgain.grid.cache; +import org.apache.ignite.*; import org.apache.ignite.transactions.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; + /** * Cache projection flags that specify projection behaviour. This flags can be explicitly passed into * the following methods on {@link GridCacheProjection}: @@ -76,7 +79,7 @@ public enum GridCacheFlag { INVALIDATE, /** - * Skips version check during {@link GridCacheProjection#transform(Object, org.apache.ignite.lang.IgniteClosure)} writes in + * Skips version check during {@link IgniteCache#invoke(Object, EntryProcessor, Object[])} writes in * {@link 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. diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheInterceptor.java b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheInterceptor.java index cb0192c..b1030bd 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheInterceptor.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheInterceptor.java @@ -42,7 +42,7 @@ public interface GridCacheInterceptor { @Nullable public V onGet(K key, @Nullable V val); /** - * This method is called within {@link GridCacheProjection#put(Object, Object, org.apache.ignite.lang.IgnitePredicate[])} + * This method is called within {@link GridCacheProjection#put(Object, Object, IgnitePredicate[])} * and similar operations before new value is stored in cache. *

* Implementations should not execute any complex logic, @@ -56,7 +56,7 @@ public interface GridCacheInterceptor { * @param oldVal Old value. * @param newVal New value. * @return Value to be put to cache. Returning {@code null} cancels the update. - * @see GridCacheProjection#put(Object, Object, org.apache.ignite.lang.IgnitePredicate[]) + * @see GridCacheProjection#put(Object, Object, IgnitePredicate[]) */ @Nullable public V onBeforePut(K key, @Nullable V oldVal, V newVal); @@ -76,7 +76,7 @@ public interface GridCacheInterceptor { public void onAfterPut(K key, V val); /** - * This method is called within {@link GridCacheProjection#remove(Object, org.apache.ignite.lang.IgnitePredicate[])} + * This method is called within {@link GridCacheProjection#remove(Object, IgnitePredicate[])} * and similar operations to provide control over returned value. *

* Implementations should not execute any complex logic, @@ -91,7 +91,7 @@ public interface GridCacheInterceptor { * @return Tuple. The first value is the flag whether remove should be cancelled or not. * The second is the value to be returned as result of {@code remove()} operation, * may be {@code null}. - * @see GridCacheProjection#remove(Object, org.apache.ignite.lang.IgnitePredicate[]) + * @see GridCacheProjection#remove(Object, IgnitePredicate[]) */ @Nullable public IgniteBiTuple onBeforeRemove(K key, @Nullable V val); diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/GridCachePartialUpdateException.java b/modules/core/src/main/java/org/gridgain/grid/cache/GridCachePartialUpdateException.java index dd41e55..015a5a7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/GridCachePartialUpdateException.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/GridCachePartialUpdateException.java @@ -49,6 +49,7 @@ public class GridCachePartialUpdateException extends IgniteCheckedException { addSuppressed(err); } + /** {@inheritDoc} */ @Override public String getMessage() { return super.getMessage() + ": " + failedKeys; } diff --git a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheProjection.java b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheProjection.java index 965f31e..2d14721 100644 --- a/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheProjection.java +++ b/modules/core/src/main/java/org/gridgain/grid/cache/GridCacheProjection.java @@ -708,82 +708,6 @@ public interface GridCacheProjection extends Iterable public IgniteFuture putxAsync(K key, V val, @Nullable IgnitePredicate>... filter); /** - * Stores result of applying {@code valTransform} closure to the previous value associated with - * given key in cache. Result of closure application is guaranteed to be atomic, however, closure - * itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putx(Object, Object, org.apache.ignite.lang.IgnitePredicate[])} or {@link #put(Object, Object, org.apache.ignite.lang.IgnitePredicate[])} - * methods, this method will not transfer the whole updated value over the network, but instead will - * transfer the transforming closure that will be applied on each remote node involved in transaction. - * It may add significant performance gain when dealing with large values as the value is much larger - * than the closure itself. If write-through is enabled, the stored value will be persisted to - * {@link GridCacheStore} via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param key Key to store in cache. - * @param transformer Closure to be applied to the previous value in cache. If this closure returns - * {@code null}, the associated value will be removed from cache. - * @throws NullPointerException If either key or transform closure is {@code null}. - * @throws IgniteCheckedException On any error occurred while storing value in cache. - */ - public void transform(K key, IgniteClosure transformer) throws IgniteCheckedException; - - /** - * Applies {@code transformer} closure to the previous value associated with given key in cache, - * closure should return {@link org.apache.ignite.lang.IgniteBiTuple} instance where first value is new value stored in cache - * and second value is returned as result of this method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param key Key to store in cache. - * @param transformer Closure to be applied to the previous value in cache. - * @return Value computed by the closure. - * @throws IgniteCheckedException On any error occurred while storing value in cache. - */ - public R transformAndCompute(K key, IgniteClosure> transformer) throws IgniteCheckedException; - - /** - * Stores result of applying {@code transformer} closure to the previous value associated with - * given key in cache. Result of closure application is guaranteed to be atomic, however, closure - * itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putx(Object, Object, org.apache.ignite.lang.IgnitePredicate[])} method, this method will not transfer - * the whole updated value over the network, but instead will transfer the transforming closure - * that will be applied on each remote node involved in transaction. It may add significant performance - * gain when dealing with large values as the value is much larger than the closure itself. - * If write-through is enabled, the stored value will be persisted to {@link GridCacheStore} - * via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param key Key to store in cache. - * @param transformer Closure to be applied to the previous value in cache. If this closure returns - * {@code null}, the associated value will be removed from cache. - * @return Future for the transform operation. - * @throws NullPointerException If either key or transform closure is {@code null}. - */ - public IgniteFuture transformAsync(K key, IgniteClosure transformer); - - /** * 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 GridCacheMode#PARTITIONED} or {@link GridCacheMode#REPLICATED} caches, @@ -1079,60 +1003,6 @@ public interface GridCacheProjection extends Iterable @Nullable IgnitePredicate>... filter) throws IgniteCheckedException; /** - * Stores result of applying transform closures from the given map to previous values associated - * with corresponding keys in cache. Execution of closure is guaranteed to be atomic, - * however, closure itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putAll(Map, org.apache.ignite.lang.IgnitePredicate[])} method, this method will not transfer - * the whole updated value over the network, but instead will transfer the transforming closures - * that will be applied on each remote node involved in transaction. It may add significant - * performance gain when dealing with large values as the value is much larger than the closure itself. - * If write-through is enabled, the stored value will be persisted to {@link GridCacheStore} - * via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param m Map containing keys and closures to be applied to values. - * @throws IgniteCheckedException On any error occurred while storing value in cache. - */ - public void transformAll(@Nullable Map> m) throws IgniteCheckedException; - - /** - * Stores result of applying the specified transform closure to previous values associated - * with the specified keys in cache. Execution of closure is guaranteed to be atomic, - * however, closure itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putAll(Map, org.apache.ignite.lang.IgnitePredicate[])} method, this method will not transfer - * the whole updated value over the network, but instead will transfer the transforming closure - * that will be applied on each remote node involved in transaction. It may add significant - * performance gain when dealing with large values as the value is much larger than the closure itself. - * If write-through is enabled, the stored value will be persisted to {@link GridCacheStore} - * via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param keys Keys for entries, to which the transformation closure will be applied. - * If the collection is {@code null} or empty, this method is no-op. - * @param transformer Transformation closure to be applied to each value. - * @throws IgniteCheckedException On any error occurred while storing value in cache. - */ - public void transformAll(@Nullable Set keys, IgniteClosure transformer) throws IgniteCheckedException; - - /** * Asynchronously stores given key-value pairs in cache. If filters are provided, then entries will * be stored in cache only if they pass the filter. Note that filter check is atomic, * so value stored in cache is guaranteed to be consistent with the filters. @@ -1156,62 +1026,6 @@ public interface GridCacheProjection extends Iterable @Nullable IgnitePredicate>... filter); /** - * Stores result of applying transform closures from the given map to previous values associated - * with corresponding keys in cache. Result of closure application is guaranteed to be atomic, - * however, closure itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putAll(Map, org.apache.ignite.lang.IgnitePredicate[])} method, this method will not transfer - * the whole updated value over the network, but instead will transfer the transforming closures - * that will be applied on each remote node involved in transaction. It may add significant performance - * gain when dealing with large values as the value is much larger than the closure itself. - * If write-through is enabled, the stored value will be persisted to {@link GridCacheStore} - * via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param m Map containing keys and closures to be applied to values. - * @return Future for operation. - */ - public IgniteFuture transformAllAsync(@Nullable Map> m); - - /** - * Stores result of applying the specified transform closure to previous values associated - * with the specified keys in cache. Result of closure application is guaranteed to be atomic, - * however, closure itself can be applied more than once. - *

- * Note that transform closure must not throw any exceptions. If exception is thrown from {@code apply} - * method, the transaction will be invalidated and entries participating in transaction will be nullified. - *

- * Unlike {@link #putAll(Map, org.apache.ignite.lang.IgnitePredicate[])} method, this method will not transfer - * the whole updated value over the network, but instead will transfer the transforming closure - * that will be applied on each remote node involved in transaction. It may add significant - * performance gain when dealing with large values as the value is much larger than the closure itself. - * If write-through is enabled, the stored value will be persisted to {@link GridCacheStore} - * via {@link GridCacheStore#put(IgniteTx, Object, Object)} method. - *

Transactions

- * This method is transactional and will enlist the entry into ongoing transaction - * if there is one. - *

Cache Flags

- * This method is not available if any of the following flags are set on projection: - * {@link GridCacheFlag#LOCAL}, {@link GridCacheFlag#READ}. - * - * @param keys Keys for entries, to which the transformation closure will be applied. - * If the collection is {@code null} or empty, this method is no-op. - * @param transformer Transformation closure to be applied to each value. - * @return Future for operation. - * @throws IgniteCheckedException On any error occurred while storing value in cache. - */ - public IgniteFuture transformAllAsync(@Nullable Set keys, IgniteClosure transformer) - throws IgniteCheckedException; - - /** * Set of keys cached on this node. You can remove elements from this set, but you cannot add elements * to this set. All removal operation will be reflected on the cache itself. *

diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeEntry.java new file mode 100644 index 0000000..1f3900d --- /dev/null +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeEntry.java @@ -0,0 +1,72 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.gridgain.grid.kernal.processors.cache; + +import org.gridgain.grid.util.tostring.*; +import org.gridgain.grid.util.typedef.internal.*; + +import javax.cache.processor.*; + +/** + * Implementation of {@link MutableEntry} passed to the {@link EntryProcessor#process(MutableEntry, Object...)}. + */ +public class CacheInvokeEntry implements MutableEntry { + /** */ + @GridToStringInclude + private final K key; + + /** */ + @GridToStringInclude + private V val; + + /** + * @param key Key. + * @param val Value. + */ + public CacheInvokeEntry(K key, V val) { + this.key = key; + this.val = val; + } + + /** {@inheritDoc} */ + @Override public boolean exists() { + return val != null; + } + + /** {@inheritDoc} */ + @Override public void remove() { + val = null; + } + + /** {@inheritDoc} */ + @Override public void setValue(V val) { + this.val = val; + } + + /** {@inheritDoc} */ + @Override public K getKey() { + return key; + } + + /** {@inheritDoc} */ + @Override public V getValue() { + return val; + } + + /** {@inheritDoc} */ + @Override public T unwrap(Class clazz) { + throw new IllegalArgumentException(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(CacheInvokeEntry.class, this); + } +} diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeResult.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeResult.java new file mode 100644 index 0000000..ab0959e --- /dev/null +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/CacheInvokeResult.java @@ -0,0 +1,96 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.gridgain.grid.kernal.processors.cache; + +import org.apache.ignite.marshaller.optimized.*; +import org.gridgain.grid.util.tostring.*; +import org.gridgain.grid.util.typedef.internal.*; + +import javax.cache.processor.*; +import java.io.*; + +/** + * Implementation of {@link EntryProcessorResult}. + */ +public class CacheInvokeResult implements EntryProcessorResult, Externalizable, IgniteOptimizedMarshallable { + /** */ + private static final long serialVersionUID = 0L; + + /** */ + @SuppressWarnings({"NonConstantFieldWithUpperCaseName", "JavaAbbreviationUsage", "UnusedDeclaration"}) + private static Object GG_CLASS_ID; + + /** */ + @GridToStringInclude + private T res; + + /** */ + private Exception err; + + /** + * Empty constructor required by {@link Externalizable}. + */ + public CacheInvokeResult() { + // No-op. + } + + /** + * @param res Computed result. + */ + public CacheInvokeResult(T res) { + assert res != null; + + this.res = res; + } + + /** + * @param err Exception thrown by {@link EntryProcessor#process(MutableEntry, Object...)}. + */ + public CacheInvokeResult(Exception err) { + this.err = err; + } + + /** {@inheritDoc} */ + @Override public Object ggClassId() { + return GG_CLASS_ID; + } + + /** {@inheritDoc} */ + @Override public T get() throws EntryProcessorException { + if (err != null) { + if (err instanceof EntryProcessorException) + throw (EntryProcessorException)err; + + throw new EntryProcessorException(err); + } + + return res; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(res); + + out.writeObject(err); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + res = (T)in.readObject(); + + err = (Exception)in.readObject(); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(CacheInvokeResult.class, this); + } +} diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheAdapter.java index e255ba7..54c11a3 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheAdapter.java @@ -43,6 +43,7 @@ import org.jdk8.backport.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -1419,12 +1420,18 @@ public abstract class GridCacheAdapter extends GridMetadataAwareAdapter im * @param reload Reload flag. * @param tx Transaction. * @param filter Filter. + * @param subjId Subject ID. + * @param taskName Task name. * @param vis Visitor. * @return Future. */ - public IgniteFuture readThroughAllAsync(final Collection keys, boolean reload, - @Nullable final IgniteTxEx tx, IgnitePredicate>[] filter, @Nullable UUID subjId, - String taskName, final IgniteBiInClosure vis) { + public IgniteFuture readThroughAllAsync(final Collection keys, + boolean reload, + @Nullable final IgniteTxEx tx, + IgnitePredicate>[] filter, + @Nullable UUID subjId, + String taskName, + final IgniteBiInClosure vis) { return ctx.closures().callLocalSafe(new GPC() { @Nullable @Override public Object call() { try { @@ -2193,102 +2200,241 @@ public abstract class GridCacheAdapter extends GridMetadataAwareAdapter im } /** {@inheritDoc} */ - @Override public void transform(final K key, final IgniteClosure transformer) throws IgniteCheckedException { - A.notNull(key, "key", transformer, "valTransform"); + @Override public EntryProcessorResult invoke(final K key, + final EntryProcessor entryProcessor, + final Object... args) + throws IgniteCheckedException { + A.notNull(key, "key", entryProcessor, "entryProcessor"); if (keyCheck) validateCacheKey(key); ctx.denyOnLocalRead(); - syncOp(new SyncInOp(true) { - @Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException { - tx.transformAllAsync(ctx, Collections.singletonMap(key, transformer), false, null, -1).get(); + return syncOp(new SyncOp>(true) { + @Nullable @Override public EntryProcessorResult op(IgniteTxLocalAdapter tx) + throws IgniteCheckedException { + Map> invokeMap = + Collections.singletonMap(key, (EntryProcessor)entryProcessor); + + IgniteFuture>>> fut = + tx.invokeAsync(ctx, invokeMap, args); + + Map> resMap = fut.get().value(); + + if (resMap != null) { + assert resMap.isEmpty() || resMap.size() == 1 : resMap.size(); + + return resMap.isEmpty() ? null : resMap.values().iterator().next(); + } + + return null; } + }); + } - @Override public String toString() { - return "transform [key=" + key + ", valTransform=" + transformer + ']'; + /** {@inheritDoc} */ + @Override public Map> invokeAll(final Set keys, + final EntryProcessor entryProcessor, + final Object... args) throws IgniteCheckedException { + A.notNull(keys, "keys", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKeys(keys); + + ctx.denyOnLocalRead(); + + return syncOp(new SyncOp>>(keys.size() == 1) { + @Nullable @Override public Map> op(IgniteTxLocalAdapter tx) + throws IgniteCheckedException { + Map> invokeMap = F.viewAsMap(keys, new C1>() { + @Override public EntryProcessor apply(K k) { + return entryProcessor; + } + }); + + IgniteFuture>>> fut = + tx.invokeAsync(ctx, invokeMap, args); + + return fut.get().value(); } }); } /** {@inheritDoc} */ - @Override public R transformAndCompute(final K key, final IgniteClosure> transformer) - throws IgniteCheckedException { - A.notNull(key, "key", transformer, "transformer"); + @Override public IgniteFuture> invokeAsync( + final K key, + final EntryProcessor entryProcessor, + final Object... args) + throws EntryProcessorException { + A.notNull(key, "key", entryProcessor, "entryProcessor"); if (keyCheck) validateCacheKey(key); ctx.denyOnLocalRead(); - return syncOp(new SyncOp(true) { - @Override public R op(IgniteTxLocalAdapter tx) throws IgniteCheckedException { - IgniteFuture> ret = tx.transformAllAsync(ctx, - F.t(key, new GridCacheTransformComputeClosure<>(transformer)), true, null, -1); + IgniteFuture fut = asyncOp(new AsyncInOp(key) { + @Override public IgniteFuture>>> inOp(IgniteTxLocalAdapter tx) { + Map> invokeMap = + Collections.singletonMap(key, (EntryProcessor)entryProcessor); - return transformer.apply(ret.get().value()).get2(); + return tx.invokeAsync(ctx, invokeMap, args); } @Override public String toString() { - return "transformAndCompute [key=" + key + ", valTransform=" + transformer + ']'; + return "invokeAsync [key=" + key + ", entryProcessor=" + entryProcessor + ']'; + } + }); + + IgniteFuture>>> fut0 = + (IgniteFuture>>>)fut; + + return fut0.chain(new CX1>>>, EntryProcessorResult>() { + @Override public EntryProcessorResult applyx(IgniteFuture>>> fut) + throws IgniteCheckedException { + GridCacheReturn>> ret = fut.get(); + + Map> resMap = ret.value(); + + if (resMap != null) { + assert resMap.isEmpty() || resMap.size() == 1 : resMap.size(); + + return resMap.isEmpty() ? null : resMap.values().iterator().next(); + } + + return null; } }); } /** {@inheritDoc} */ - @Override public IgniteFuture putxAsync(K key, V val, - @Nullable IgnitePredicate>... filter) { - return putxAsync(key, val, null, -1, filter); + @Override public IgniteFuture>> invokeAllAsync( + final Set keys, + final EntryProcessor entryProcessor, + final Object... args) { + A.notNull(keys, "keys", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKeys(keys); + + ctx.denyOnLocalRead(); + + IgniteFuture fut = asyncOp(new AsyncInOp(keys) { + @Override public IgniteFuture>>> inOp(IgniteTxLocalAdapter tx) { + Map> invokeMap = F.viewAsMap(keys, new C1>() { + @Override public EntryProcessor apply(K k) { + return entryProcessor; + } + }); + + return tx.invokeAsync(ctx, invokeMap, args); + } + + @Override public String toString() { + return "invokeAllAsync [keys=" + keys + ", entryProcessor=" + entryProcessor + ']'; + } + }); + + IgniteFuture>>> fut0 = + (IgniteFuture>>>)fut; + + return fut0.chain(new CX1>>>, Map>>() { + @Override public Map> applyx(IgniteFuture>>> fut) + throws IgniteCheckedException { + GridCacheReturn>> ret = fut.get(); + + assert ret != null; + + return ret.value() != null ? ret.value() : Collections.>emptyMap(); + } + }); } /** {@inheritDoc} */ - @Override public IgniteFuture putxAsync(final K key, final V val, - @Nullable final GridCacheEntryEx entry, final long ttl, - @Nullable final IgnitePredicate>... filter) { - A.notNull(key, "key", val, "val"); + @Override public IgniteFuture>> invokeAllAsync( + final Map> map, + final Object... args) { + A.notNull(map, "map"); if (keyCheck) - validateCacheKey(key); - - validateCacheValue(val); + validateCacheKeys(map.keySet()); ctx.denyOnLocalRead(); - return asyncOp(new AsyncOp(key) { - @Override public IgniteFuture op(IgniteTxLocalAdapter tx) { - return tx.putAllAsync(ctx, F.t(key, val), false, entry, ttl, filter).chain( - (IgniteClosure>, Boolean>)RET2FLAG); + IgniteFuture fut = asyncOp(new AsyncInOp(map.keySet()) { + @Override public IgniteFuture>>> inOp(IgniteTxLocalAdapter tx) { + return tx.invokeAsync(ctx, (Map>)map, args); } @Override public String toString() { - return "putxAsync [key=" + key + ", val=" + val + ", filter=" + Arrays.toString(filter) + ']'; + return "invokeAllAsync [map=" + map + ']'; + } + }); + + IgniteFuture>>> fut0 = + (IgniteFuture>>>)fut; + + return fut0.chain(new CX1>>>, Map>>() { + @Override public Map> applyx(IgniteFuture>>> fut) + throws IgniteCheckedException { + GridCacheReturn>> ret = fut.get(); + + assert ret != null; + + return ret.value() != null ? ret.value() : Collections.>emptyMap(); } }); } /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(final K key, final IgniteClosure transformer) { - return transformAsync(key, transformer, null, -1); + @Override public Map> invokeAll( + final Map> map, + final Object... args) throws IgniteCheckedException { + A.notNull(map, "map"); + + if (keyCheck) + validateCacheKeys(map.keySet()); + + ctx.denyOnLocalRead(); + + return syncOp(new SyncOp>>(map.size() == 1) { + @Nullable @Override public Map> op(IgniteTxLocalAdapter tx) + throws IgniteCheckedException { + IgniteFuture>>> fut = tx.invokeAsync(ctx, map, args); + + return fut.get().value(); + } + }); + } + + /** {@inheritDoc} */ + @Override public IgniteFuture putxAsync(K key, V val, + @Nullable IgnitePredicate>... filter) { + return putxAsync(key, val, null, -1, filter); } /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(final K key, final IgniteClosure transformer, - @Nullable final GridCacheEntryEx entry, final long ttl) { - A.notNull(key, "key", transformer, "transformer"); + @Override public IgniteFuture putxAsync(final K key, final V val, + @Nullable final GridCacheEntryEx entry, final long ttl, + @Nullable final IgnitePredicate>... filter) { + A.notNull(key, "key", val, "val"); if (keyCheck) validateCacheKey(key); + validateCacheValue(val); + ctx.denyOnLocalRead(); - return asyncOp(new AsyncInOp(key) { - @Override public IgniteFuture inOp(IgniteTxLocalAdapter tx) { - return tx.transformAllAsync(ctx, F.t(key, transformer), false, entry, ttl); + return asyncOp(new AsyncOp(key) { + @Override public IgniteFuture op(IgniteTxLocalAdapter tx) { + return tx.putAllAsync(ctx, F.t(key, val), false, entry, ttl, filter).chain( + (IgniteClosure>, Boolean>)RET2FLAG); } @Override public String toString() { - return "transformAsync [key=" + key + ", valTransform=" + transformer + ']'; + return "putxAsync [key=" + key + ", val=" + val + ", filter=" + Arrays.toString(filter) + ']'; } }); } @@ -2563,42 +2709,6 @@ public abstract class GridCacheAdapter extends GridMetadataAwareAdapter im } /** {@inheritDoc} */ - @Override public void transformAll(@Nullable final Map> m) - throws IgniteCheckedException { - if (F.isEmpty(m)) - return; - - if (keyCheck) - validateCacheKeys(m.keySet()); - - ctx.denyOnLocalRead(); - - syncOp(new SyncInOp(m.size() == 1) { - @Override public void inOp(IgniteTxLocalAdapter tx) throws IgniteCheckedException { - tx.transformAllAsync(ctx, m, false, null, -1).get(); - } - - @Override public String toString() { - return "transformAll [map=" + m + ']'; - } - }); - } - - /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Set keys, final IgniteClosure transformer) - throws IgniteCheckedException { - if (F.isEmpty(keys)) - return; - - // Reuse transformAll(Map), mapping all keys to a transformer closure. - transformAll(F.viewAsMap(keys, new C1>() { - @Override public IgniteClosure apply(K k) { - return transformer; - } - })); - } - - /** {@inheritDoc} */ @Override public IgniteFuture putAllAsync(final Map m, @Nullable final IgnitePredicate>... filter) { if (F.isEmpty(m)) @@ -2623,41 +2733,6 @@ public abstract class GridCacheAdapter extends GridMetadataAwareAdapter im } /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable final Map> m) { - if (F.isEmpty(m)) - return new GridFinishedFuture<>(ctx.kernalContext()); - - if (keyCheck) - validateCacheKeys(m.keySet()); - - ctx.denyOnLocalRead(); - - return asyncOp(new AsyncInOp(m.keySet()) { - @Override public IgniteFuture inOp(IgniteTxLocalAdapter tx) { - return tx.transformAllAsync(ctx, m, false, null, -1); - } - - @Override public String toString() { - return "transformAllAsync [map=" + m + ']'; - } - }); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Set keys, - final IgniteClosure transformer) throws IgniteCheckedException { - if (F.isEmpty(keys)) - return new GridFinishedFuture<>(ctx.kernalContext()); - - // Reuse transformAllAsync(Map), mapping all keys to a transformer closure. - return transformAllAsync(F.viewAsMap(keys, new C1>() { - @Override public IgniteClosure apply(K k) { - return transformer; - } - })); - } - - /** {@inheritDoc} */ @Nullable @Override public V remove(K key, IgnitePredicate>[] filter) throws IgniteCheckedException { return remove(key, null, filter); @@ -4516,7 +4591,7 @@ public abstract class GridCacheAdapter extends GridMetadataAwareAdapter im * @param key Cache key. * @throws IllegalArgumentException If validation fails. */ - private void validateCacheKey(Object key) { + protected void validateCacheKey(Object key) { if (keyCheck) { CU.validateCacheKey(log, key); diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryEx.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryEx.java index 5fb0b95..0962cd7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryEx.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryEx.java @@ -20,6 +20,7 @@ import org.gridgain.grid.util.lang.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.util.*; /** @@ -392,6 +393,7 @@ public interface GridCacheEntryEx extends GridMetadataAware { * @param op Update operation. * @param val Value. Type depends on operation. * @param valBytes Value bytes. Can be non-null only if operation is UPDATE. + * @param invokeArgs Optional arguments for entry processor. * @param writeThrough Write through flag. * @param retval Return value flag. * @param expiryPlc Expiry policy. @@ -424,6 +426,7 @@ public interface GridCacheEntryEx extends GridMetadataAware { GridCacheOperation op, @Nullable Object val, @Nullable byte[] valBytes, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, @@ -448,6 +451,7 @@ public interface GridCacheEntryEx extends GridMetadataAware { * @param ver Cache version. * @param op Operation. * @param writeObj Value. Type depends on operation. + * @param invokeArgs Optional arguments for EntryProcessor. * @param writeThrough Write through flag. * @param retval Return value flag. * @param expiryPlc Expiry policy.. @@ -457,14 +461,15 @@ public interface GridCacheEntryEx extends GridMetadataAware { * @param intercept If {@code true} then calls cache interceptor. * @param subjId Subject ID initiated this update. * @param taskName Task name. - * @return Tuple containing success flag and old value. + * @return Tuple containing success flag, old value and result for invoke operation. * @throws IgniteCheckedException If update failed. * @throws GridCacheEntryRemovedException If entry is obsolete. */ - public IgniteBiTuple innerUpdateLocal( + public GridTuple3> innerUpdateLocal( GridCacheVersion ver, GridCacheOperation op, @Nullable Object writeObj, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryImpl.java index f7545b0..c910df2 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEntryImpl.java @@ -507,16 +507,6 @@ public class GridCacheEntryImpl implements GridCacheEntry, Externali } /** {@inheritDoc} */ - @Override public void transform(IgniteClosure transformer) throws IgniteCheckedException { - transformAsync(transformer).get(); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - return proxy.transformAsync(key, transformer, isNearEnabled(ctx) ? null : cached, ttl); - } - - /** {@inheritDoc} */ @Override public boolean replacex(V val) throws IgniteCheckedException { return setx(val, ctx.hasPeekArray()); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionEntry.java index 04fe0a9..e81f637 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionEntry.java @@ -267,16 +267,6 @@ public class GridCacheEvictionEntry implements GridCacheEntry, Exter } /** {@inheritDoc} */ - @Override public void transform(IgniteClosure transformer) throws IgniteCheckedException { - throw unsupported(); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - throw unsupported(); - } - - /** {@inheritDoc} */ @Nullable @Override public V replace(V val) throws IgniteCheckedException { throw unsupported(); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheFilterEvaluationEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheFilterEvaluationEntry.java index 6862a5e..9e5644a 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheFilterEvaluationEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheFilterEvaluationEntry.java @@ -239,16 +239,6 @@ public class GridCacheFilterEvaluationEntry implements GridCacheEntry transformer) throws IgniteCheckedException { - throw new UnsupportedOperationException("transform"); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - throw new UnsupportedOperationException("transformAsync"); - } - - /** {@inheritDoc} */ @Nullable @Override public V replace(V val) throws IgniteCheckedException { throw new UnsupportedOperationException("replace"); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java index 0fd64de..bb493cc 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java @@ -29,6 +29,7 @@ import org.jetbrains.annotations.*; import sun.misc.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.nio.*; import java.util.*; @@ -1364,10 +1365,11 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx /** {@inheritDoc} */ @SuppressWarnings("unchecked") - @Override public IgniteBiTuple innerUpdateLocal( + @Override public GridTuple3> innerUpdateLocal( GridCacheVersion ver, GridCacheOperation op, @Nullable Object writeObj, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, @@ -1386,6 +1388,8 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx IgniteBiTuple interceptorRes = null; + EntryProcessorResult invokeRes = null; + synchronized (this) { boolean needVal = retval || intercept || op == GridCacheOperation.TRANSFORM || !F.isEmpty(filter); @@ -1427,7 +1431,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx updateTtl(ttl); } - return new IgniteBiTuple<>(false, retval ? old : null); + return new T3<>(false, retval ? old : null, null); } } @@ -1443,11 +1447,24 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx if (op == GridCacheOperation.TRANSFORM) { transformCloClsName = writeObj.getClass().getName(); - IgniteClosure transform = (IgniteClosure)writeObj; + EntryProcessor entryProcessor = (EntryProcessor)writeObj; + + assert entryProcessor != null; + + CacheInvokeEntry entry = new CacheInvokeEntry<>(key, old); + + try { + Object computed = entryProcessor.process(entry, invokeArgs); - assert transform != null; + updated = cctx.unwrapTemporary(entry.getValue()); - updated = cctx.unwrapTemporary(transform.apply(old)); + invokeRes = computed != null ? new CacheInvokeResult<>(cctx.unwrapTemporary(computed)) : null; + } + catch (Exception e) { + updated = old; + + invokeRes = new CacheInvokeResult<>(e); + } } else updated = (V)writeObj; @@ -1459,13 +1476,13 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx updated = (V)cctx.config().getInterceptor().onBeforePut(key, old, updated); if (updated == null) - return new IgniteBiTuple<>(false, cctx.unwrapTemporary(old)); + return new GridTuple3<>(false, cctx.unwrapTemporary(old), invokeRes); } else { interceptorRes = cctx.config().getInterceptor().onBeforeRemove(key, old); if (cctx.cancelRemove(interceptorRes)) - return new IgniteBiTuple<>(false, cctx.unwrapTemporary(interceptorRes.get2())); + return new GridTuple3<>(false, cctx.unwrapTemporary(interceptorRes.get2()), invokeRes); } } @@ -1575,7 +1592,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx } } - return new IgniteBiTuple<>(res, cctx.unwrapTemporary(interceptorRes != null ? interceptorRes.get2() : old)); + return new GridTuple3<>(res, cctx.unwrapTemporary(interceptorRes != null ? interceptorRes.get2() : old), invokeRes); } /** {@inheritDoc} */ @@ -1586,6 +1603,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx GridCacheOperation op, @Nullable Object writeObj, @Nullable byte[] valBytes, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, @@ -1615,6 +1633,8 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx GridDrResolveResult drRes = null; + EntryProcessorResult invokeRes = null; + long newTtl = -1L; long newExpireTime = 0L; long newDrExpireTime = -1L; // Explicit DR expire time which possibly will be sent to DHT node. @@ -1644,7 +1664,15 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx if (drRes.isUseOld()) { old = retval ? rawGetOrUnmarshalUnlocked(false) : val; - return new GridCacheUpdateAtomicResult<>(false, old, null, -1L, -1L, null, null, false); + return new GridCacheUpdateAtomicResult<>(false, + old, + null, + invokeRes, + -1L, + -1L, + null, + null, + false); } newTtl = drRes.newTtl(); @@ -1692,7 +1720,15 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx old = retval ? rawGetOrUnmarshalUnlocked(false) : val; - return new GridCacheUpdateAtomicResult<>(false, old, null, -1L, -1L, null, null, false); + return new GridCacheUpdateAtomicResult<>(false, + old, + null, + invokeRes, + -1L, + -1L, + null, + null, + false); } } else @@ -1744,6 +1780,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx return new GridCacheUpdateAtomicResult<>(false, retval ? old : null, null, + invokeRes, -1L, -1L, null, @@ -1760,11 +1797,27 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx if (op == GridCacheOperation.TRANSFORM) { transformClo = writeObj; - IgniteClosure transform = (IgniteClosure)writeObj; + EntryProcessor entryProcessor = (EntryProcessor)writeObj; - updated = cctx.unwrapTemporary(transform.apply(old)); + CacheInvokeEntry entry = new CacheInvokeEntry<>(key, old); + + try { + Object computed = entryProcessor.process(entry, invokeArgs); - valBytes = null; + updated = cctx.unwrapTemporary(entry.getValue()); + + if (computed != null) + invokeRes = new CacheInvokeResult<>(cctx.unwrapTemporary(computed)); + + valBytes = null; + } + catch (Exception e) { + invokeRes = new CacheInvokeResult<>(e); + + updated = old; + + valBytes = oldBytes.getIfMarshaled(); + } } else updated = (V)writeObj; @@ -1794,6 +1847,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx return new GridCacheUpdateAtomicResult<>(false, retval ? old : null, null, + invokeRes, -1L, -1L, null, @@ -1899,6 +1953,7 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx return new GridCacheUpdateAtomicResult<>(false, cctx.unwrapTemporary(interceptRes.get2()), null, + invokeRes, -1L, -1L, null, @@ -2001,7 +2056,15 @@ public abstract class GridCacheMapEntry implements GridCacheEntryEx if (log.isDebugEnabled()) log.debug("Updated cache entry [val=" + val + ", old=" + old + ", entry=" + this + ']'); - return new GridCacheUpdateAtomicResult<>(res, old, updated, newTtl, newDrExpireTime, enqueueVer, drRes, true); + return new GridCacheUpdateAtomicResult<>(res, + old, + updated, + invokeRes, + newTtl, + newDrExpireTime, + enqueueVer, + drRes, + true); } /** diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMessage.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMessage.java index ab98dcb..45eda5f 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMessage.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMessage.java @@ -372,6 +372,60 @@ public abstract class GridCacheMessage extends GridTcpCommunicationMessage } /** + * @param args Arguments to marshal. + * @param ctx Context. + * @return Marshalled collection. + * @throws IgniteCheckedException If failed. + */ + @Nullable protected final byte[][] marshalInvokeArguments(@Nullable Object[] args, + GridCacheSharedContext ctx) throws IgniteCheckedException { + assert ctx != null; + + if (args == null || args.length == 0) + return null; + + byte[][] argsBytes = new byte[args.length][]; + + for (int i = 0; i < args.length; i++) { + Object arg = args[i]; + + if (ctx.deploymentEnabled()) + prepareObject(arg, ctx); + + argsBytes[i] = arg == null ? null : CU.marshal(ctx, arg); + } + + return argsBytes; + } + + + /** + * @param byteCol Collection to unmarshal. + * @param ctx Context. + * @param ldr Loader. + * @return Unmarshalled collection. + * @throws IgniteCheckedException If failed. + */ + @Nullable protected final Object[] unmarshalInvokeArguments(@Nullable byte[][] byteCol, + GridCacheSharedContext ctx, + ClassLoader ldr) throws IgniteCheckedException { + assert ldr != null; + assert ctx != null; + + if (byteCol == null) + return null; + + Object[] args = new Object[byteCol.length]; + + IgniteMarshaller marsh = ctx.marshaller(); + + for (int i = 0; i < byteCol.length; i++) + args[i] = byteCol[i] == null ? null : marsh.unmarshal(byteCol[i], ldr); + + return args; + } + + /** * @param filter Collection to marshal. * @param ctx Context. * @return Marshalled collection. diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProcessor.java index 0724a58..8e9cea0 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProcessor.java @@ -72,6 +72,9 @@ public class GridCacheProcessor extends GridProcessorAdapter { /** Map of proxies. */ private final Map> proxies; + /** Map of proxies. */ + private final Map> jCacheProxies; + /** Map of public proxies, i.e. proxies which could be returned to the user. */ private final Map> publicProxies; @@ -105,6 +108,7 @@ public class GridCacheProcessor extends GridProcessorAdapter { caches = new LinkedHashMap<>(); proxies = new HashMap<>(); publicProxies = new HashMap<>(); + jCacheProxies = new HashMap<>(); preloadFuts = new TreeMap<>(); sysCaches = new HashSet<>(); @@ -816,6 +820,8 @@ public class GridCacheProcessor extends GridProcessorAdapter { GridCacheAdapter cache = e.getValue(); proxies.put(e.getKey(), new GridCacheProxyImpl(cache.context(), cache, null)); + + jCacheProxies.put(e.getKey(), new IgniteCacheProxy(cache.context(), cache, null, false)); } for (GridCacheAdapter cache : caches.values()) { @@ -1594,12 +1600,26 @@ public class GridCacheProcessor extends GridProcessorAdapter { if (sysCaches.contains(name)) throw new IllegalStateException("Failed to get cache because it is system cache: " + name); - GridCacheAdapter cache = (GridCacheAdapter)caches.get(name); + IgniteCacheProxy cache = (IgniteCacheProxy)jCacheProxies.get(name); + + if (cache == null) + throw new IllegalArgumentException("Cache is not configured: " + name); + + return cache; + } + + /** + * @param name Cache name. + * @return Cache instance for given name. + */ + @SuppressWarnings("unchecked") + public IgniteCacheProxy jcache(@Nullable String name) { + IgniteCacheProxy cache = (IgniteCacheProxy)jCacheProxies.get(name); if (cache == null) throw new IllegalArgumentException("Cache is not configured: " + name); - return new IgniteCacheProxy<>(cache.context(), cache, null); + return cache; } /** diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionEx.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionEx.java index 2362f57..f1f2483 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionEx.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionEx.java @@ -18,6 +18,7 @@ import org.gridgain.grid.kernal.processors.cache.dr.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.util.*; /** @@ -116,18 +117,6 @@ public interface GridCacheProjectionEx extends GridCacheProjection { /** * Internal method that is called from {@link GridCacheEntryImpl}. * - * @param key Key. - * @param transformer Transformer closure. - * @param entry Cached entry. - * @param ttl Optional time-to-lve. - * @return Transform operation future. - */ - public IgniteFuture transformAsync(K key, IgniteClosure transformer, @Nullable GridCacheEntryEx entry, - long ttl); - - /** - * Internal method that is called from {@link GridCacheEntryImpl}. - * * @param key Key to remove. * @param entry Cached entry. If not provided, equivalent to {GridCacheProjection#put}. * @param filter Optional filter. @@ -393,4 +382,65 @@ public interface GridCacheProjectionEx extends GridCacheProjection { * @return New projection based on this one, but with the specified expiry policy. */ public GridCacheProjectionEx withExpiryPolicy(ExpiryPolicy plc); + + /** + * @param key Key. + * @param entryProcessor Entry processor. + * @param args Arguments. + * @return Invoke result. + * @throws IgniteCheckedException If failed. + */ + @Nullable public EntryProcessorResult invoke(K key, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException; + + /** + * @param key Key. + * @param entryProcessor Entry processor. + * @param args Arguments. + * @return Future. + */ + public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args); + + /** + * @param keys Keys. + * @param entryProcessor Entry processor. + * @param args Arguments. + * @return Invoke results. + * @throws IgniteCheckedException If failed. + */ + public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException; + + /** + * @param keys Keys. + * @param entryProcessor Entry processor. + * @param args Arguments. + * @return Future. + */ + public IgniteFuture>> invokeAllAsync(Set keys, + EntryProcessor entryProcessor, + Object... args); + + /** + * @param map Map containing keys and entry processors to be applied to values. + * @param args Arguments. + * @return Invoke results. + * @throws IgniteCheckedException If failed. + */ + public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException; + + /** + * @param map Map containing keys and entry processors to be applied to values. + * @param args Arguments. + * @return Future. + */ + public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionImpl.java index 5bd973c..8cebb39 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProjectionImpl.java @@ -26,6 +26,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -773,18 +774,44 @@ public class GridCacheProjectionImpl implements GridCacheProjectionEx transformer) throws IgniteCheckedException { - A.notNull(key, "key", transformer, "valTransform"); + @Override public EntryProcessorResult invoke(K key, EntryProcessor entryProcessor, Object... args) + throws IgniteCheckedException { + return cache.invoke(key, entryProcessor, args); + } - cache.transform(key, transformer); + /** {@inheritDoc} */ + @Override public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { + return cache.invokeAll(keys, entryProcessor, args); } /** {@inheritDoc} */ - @Override public R transformAndCompute(K key, IgniteClosure> transformer) - throws IgniteCheckedException { - A.notNull(key, "key", transformer, "transformer"); + @Override public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args) { + return cache.invokeAsync(key, entryProcessor, args); + } - return cache.transformAndCompute(key, transformer); + /** {@inheritDoc} */ + @Override public IgniteFuture>> invokeAllAsync(Set keys, + EntryProcessor entryProcessor, + Object... args) { + return cache.invokeAllAsync(keys, entryProcessor, args); + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException { + return cache.invokeAll(map, args); + } + + /** {@inheritDoc} */ + @Override public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args) { + return cache.invokeAllAsync(map, args); } /** {@inheritDoc} */ @@ -806,13 +833,6 @@ public class GridCacheProjectionImpl implements GridCacheProjectionEx transformAsync(K key, IgniteClosure transformer) { - A.notNull(key, "key", transformer, "valTransform"); - - return cache.transformAsync(key, transformer); - } - - /** {@inheritDoc} */ @Override public V putIfAbsent(K key, V val) throws IgniteCheckedException { return putIfAbsentAsync(key, val).get(); } @@ -833,12 +853,6 @@ public class GridCacheProjectionImpl implements GridCacheProjectionEx transformAsync(K key, IgniteClosure transformer, - @Nullable GridCacheEntryEx entry, long ttl) { - return cache.transformAsync(key, transformer, entry, ttl); - } - - /** {@inheritDoc} */ @Override public V replace(K key, V val) throws IgniteCheckedException { return replaceAsync(key, val).get(); } @@ -877,23 +891,6 @@ public class GridCacheProjectionImpl implements GridCacheProjectionEx> m) throws IgniteCheckedException { - if (F.isEmpty(m)) - return; - - cache.transformAll(m); - } - - /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Set keys, IgniteClosure transformer) - throws IgniteCheckedException { - if (F.isEmpty(keys)) - return; - - cache.transformAll(keys, transformer); - } - - /** {@inheritDoc} */ @Override public IgniteFuture putAllAsync(Map m, @Nullable IgnitePredicate>[] filter) { m = isAll(m, true); @@ -905,23 +902,6 @@ public class GridCacheProjectionImpl implements GridCacheProjectionEx transformAllAsync(@Nullable Map> m) { - if (F.isEmpty(m)) - return new GridFinishedFuture<>(cctx.kernalContext()); - - return cache.transformAllAsync(m); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Set keys, IgniteClosure transformer) - throws IgniteCheckedException { - if (F.isEmpty(keys)) - return new GridFinishedFuture<>(cctx.kernalContext()); - - return cache.transformAllAsync(keys, transformer); - } - - /** {@inheritDoc} */ @Override public Set keySet() { return cache.keySet(entryFilter(true)); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProxyImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProxyImpl.java index 136e078..9d5db1c 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProxyImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheProxyImpl.java @@ -26,6 +26,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -712,11 +713,13 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public void transform(K key, IgniteClosure transformer) throws IgniteCheckedException { + @Override public EntryProcessorResult invoke(K key, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - delegate.transform(key, transformer); + return delegate.invoke(key, entryProcessor, args); } finally { gate.leave(prev); @@ -724,12 +727,13 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public R transformAndCompute(K key, IgniteClosure> transformer) - throws IgniteCheckedException { + @Override public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.transformAndCompute(key, transformer); + return delegate.invokeAsync(key, entryProcessor, args); } finally { gate.leave(prev); @@ -737,12 +741,13 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture putxAsync(K key, V val, - @Nullable IgnitePredicate>[] filter) { + @Override public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putxAsync(key, val, filter); + return delegate.invokeAll(keys, entryProcessor, args); } finally { gate.leave(prev); @@ -750,12 +755,14 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture putxAsync(K key, V val, @Nullable GridCacheEntryEx entry, - long ttl, @Nullable IgnitePredicate>... filter) { + @Override public IgniteFuture>> invokeAllAsync( + Set keys, + EntryProcessor entryProcessor, + Object... args) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putxAsync(key, val, entry, ttl, filter); + return delegate.invokeAllAsync(keys, entryProcessor, args); } finally { gate.leave(prev); @@ -763,11 +770,13 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(K key, IgniteClosure transformer) { + @Override public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.transformAsync(key, transformer); + return delegate.invokeAll(map, args); } finally { gate.leave(prev); @@ -775,11 +784,13 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Nullable @Override public V putIfAbsent(K key, V val) throws IgniteCheckedException { + @Override public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putIfAbsent(key, val); + return delegate.invokeAllAsync(map, args); } finally { gate.leave(prev); @@ -787,11 +798,12 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture putIfAbsentAsync(K key, V val) { + @Override public IgniteFuture putxAsync(K key, V val, + @Nullable IgnitePredicate>[] filter) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putIfAbsentAsync(key, val); + return delegate.putxAsync(key, val, filter); } finally { gate.leave(prev); @@ -799,11 +811,15 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public boolean putxIfAbsent(K key, V val) throws IgniteCheckedException { + @Override public IgniteFuture putxAsync(K key, + V val, + @Nullable GridCacheEntryEx entry, + long ttl, + @Nullable IgnitePredicate>... filter) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putxIfAbsent(key, val); + return delegate.putxAsync(key, val, entry, ttl, filter); } finally { gate.leave(prev); @@ -811,11 +827,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture putxIfAbsentAsync(K key, V val) { + @Nullable @Override public V putIfAbsent(K key, V val) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.putxIfAbsentAsync(key, val); + return delegate.putIfAbsent(key, val); } finally { gate.leave(prev); @@ -823,12 +839,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(K key, IgniteClosure transformer, - @Nullable GridCacheEntryEx entry, long ttl) { + @Override public IgniteFuture putIfAbsentAsync(K key, V val) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.transformAsync(key, transformer); + return delegate.putIfAbsentAsync(key, val); } finally { gate.leave(prev); @@ -836,11 +851,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Nullable @Override public V replace(K key, V val) throws IgniteCheckedException { + @Override public boolean putxIfAbsent(K key, V val) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replace(key, val); + return delegate.putxIfAbsent(key, val); } finally { gate.leave(prev); @@ -848,11 +863,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture replaceAsync(K key, V val) { + @Override public IgniteFuture putxIfAbsentAsync(K key, V val) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replaceAsync(key, val); + return delegate.putxIfAbsentAsync(key, val); } finally { gate.leave(prev); @@ -860,11 +875,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public boolean replacex(K key, V val) throws IgniteCheckedException { + @Nullable @Override public V replace(K key, V val) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replacex(key, val); + return delegate.replace(key, val); } finally { gate.leave(prev); @@ -872,11 +887,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture replacexAsync(K key, V val) { + @Override public IgniteFuture replaceAsync(K key, V val) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replacexAsync(key, val); + return delegate.replaceAsync(key, val); } finally { gate.leave(prev); @@ -884,11 +899,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public boolean replace(K key, V oldVal, V newVal) throws IgniteCheckedException { + @Override public boolean replacex(K key, V val) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replace(key, oldVal, newVal); + return delegate.replacex(key, val); } finally { gate.leave(prev); @@ -896,11 +911,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture replaceAsync(K key, V oldVal, V newVal) { + @Override public IgniteFuture replacexAsync(K key, V val) { GridCacheProjectionImpl prev = gate.enter(prj); try { - return delegate.replaceAsync(key, oldVal, newVal); + return delegate.replacexAsync(key, val); } finally { gate.leave(prev); @@ -908,12 +923,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public void putAll(@Nullable Map m, - @Nullable IgnitePredicate>[] filter) throws IgniteCheckedException { + @Override public boolean replace(K key, V oldVal, V newVal) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - delegate.putAll(m, filter); + return delegate.replace(key, oldVal, newVal); } finally { gate.leave(prev); @@ -921,11 +935,11 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Map> m) throws IgniteCheckedException { + @Override public IgniteFuture replaceAsync(K key, V oldVal, V newVal) { GridCacheProjectionImpl prev = gate.enter(prj); try { - delegate.transformAll(m); + return delegate.replaceAsync(key, oldVal, newVal); } finally { gate.leave(prev); @@ -933,12 +947,12 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Set keys, IgniteClosure transformer) - throws IgniteCheckedException { + @Override public void putAll(@Nullable Map m, + @Nullable IgnitePredicate>[] filter) throws IgniteCheckedException { GridCacheProjectionImpl prev = gate.enter(prj); try { - delegate.transformAll(keys, transformer); + delegate.putAll(m, filter); } finally { gate.leave(prev); @@ -959,31 +973,6 @@ public class GridCacheProxyImpl implements GridCacheProxy, Externali } /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Map> m) { - GridCacheProjectionImpl prev = gate.enter(prj); - - try { - return delegate.transformAllAsync(m); - } - finally { - gate.leave(prev); - } - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Set keys, IgniteClosure transformer) - throws IgniteCheckedException { - GridCacheProjectionImpl prev = gate.enter(prj); - - try { - return delegate.transformAllAsync(keys, transformer); - } - finally { - gate.leave(prev); - } - } - - /** {@inheritDoc} */ @Override public Set keySet() { GridCacheProjectionImpl prev = gate.enter(prj); diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturn.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturn.java index e9c476a..ab05b34 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturn.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturn.java @@ -14,7 +14,9 @@ import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.grid.util.tostring.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; +import java.util.*; /** * Return value for cases where both, value and success flag need to be returned. @@ -24,7 +26,7 @@ public class GridCacheReturn implements Externalizable, IgniteOptimizedMarsha private static final long serialVersionUID = 0L; /** */ - @SuppressWarnings({"NonConstantFieldWithUpperCaseName", "AbbreviationUsage", "UnusedDeclaration"}) + @SuppressWarnings({"NonConstantFieldWithUpperCaseName", "JavaAbbreviationUsage", "UnusedDeclaration"}) private static Object GG_CLASS_ID; /** Value. */ @@ -42,13 +44,6 @@ public class GridCacheReturn implements Externalizable, IgniteOptimizedMarsha } /** - * @param v Value. - */ - public GridCacheReturn(V v) { - this.v = v; - } - - /** * * @param success Success flag. */ @@ -93,17 +88,6 @@ public class GridCacheReturn implements Externalizable, IgniteOptimizedMarsha } /** - * @param v Value. - * @return This instance for chaining. - */ - public GridCacheReturn valueIfNull(V v) { - if (this.v == null) - this.v = v; - - return this; - } - - /** * @return Success flag. */ public boolean success() { @@ -123,27 +107,34 @@ public class GridCacheReturn implements Externalizable, IgniteOptimizedMarsha } /** - * @param v Value. * @param success Success flag. * @return This instance for chaining. */ - public GridCacheReturn setIfNull(V v, boolean success) { - if (this.v == null) { - this.v = v; - this.success = success; - } + public GridCacheReturn success(boolean success) { + this.success = success; return this; } /** - * @param success Success flag. - * @return This instance for chaining. + * @param key Key. + * @param res Result. */ - public GridCacheReturn success(boolean success) { - this.success = success; + @SuppressWarnings("unchecked") + public synchronized void addEntryProcessResult(Object key, EntryProcessorResult res) { + assert v == null || v instanceof Map : v; + assert key != null; + assert res != null; - return this; + HashMap resMap = (HashMap)v; + + if (resMap == null) { + resMap = new HashMap<>(); + + v = (V)resMap; + } + + resMap.put(key, res); } /** {@inheritDoc} */ @@ -157,11 +148,15 @@ public class GridCacheReturn implements Externalizable, IgniteOptimizedMarsha out.writeObject(v); } + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { success = in.readBoolean(); v = (V)in.readObject(); } /** {@inheritDoc} */ - @Override public String toString() { return S.toString(GridCacheReturn.class, this); } + @Override public String toString() { + return S.toString(GridCacheReturn.class, this); + } } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheStoreManager.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheStoreManager.java index a7e47b0..b6fe4be 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheStoreManager.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheStoreManager.java @@ -180,7 +180,8 @@ public class GridCacheStoreManager extends GridCacheManagerAdapter { * @throws IgniteCheckedException If data loading failed. */ @SuppressWarnings({"unchecked"}) - public boolean loadAllFromStore(@Nullable IgniteTx tx, Collection keys, + public boolean loadAllFromStore(@Nullable IgniteTx tx, + Collection keys, final IgniteBiInClosure vis) throws IgniteCheckedException { if (store != null) { if (!keys.isEmpty()) { @@ -230,6 +231,10 @@ public class GridCacheStoreManager extends GridCacheManagerAdapter { return true; } + else { + for (K key : keys) + vis.apply(key, null); + } return false; } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTransformComputeClosure.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTransformComputeClosure.java deleted file mode 100644 index bf06bd8..0000000 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTransformComputeClosure.java +++ /dev/null @@ -1,68 +0,0 @@ -/* @java.file.header */ - -/* _________ _____ __________________ _____ - * __ ____/___________(_)______ /__ ____/______ ____(_)_______ - * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ - * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / - * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ - */ - -package org.gridgain.grid.kernal.processors.cache; - -import org.apache.ignite.lang.*; -import org.gridgain.grid.cache.GridCacheProjection; - -import java.io.*; - -/** - */ -public final class GridCacheTransformComputeClosure implements IgniteClosure, Externalizable { - /** */ - private static final long serialVersionUID = 0L; - - /** */ - private IgniteClosure> transformer; - - /** */ - private R retVal; - - /** - * Required by {@link Externalizable}. - */ - public GridCacheTransformComputeClosure() { - // No-op. - } - - /** - * @param transformer Transformer closure. - */ - public GridCacheTransformComputeClosure(IgniteClosure> transformer) { - this.transformer = transformer; - } - - /** - * @return Return value for {@link GridCacheProjection#transformAndCompute(Object, org.apache.ignite.lang.IgniteClosure)} - */ - public R returnValue() { - return retVal; - } - - /** {@inheritDoc} */ - @Override public V apply(V v) { - IgniteBiTuple t = transformer.apply(v); - - retVal = t.get2(); - - return t.get1(); - } - - /** {@inheritDoc} */ - @Override public void writeExternal(ObjectOutput out) throws IOException { - out.writeObject(transformer); - } - - /** {@inheritDoc} */ - @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - transformer = (IgniteClosure>)in.readObject(); - } -} diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheUpdateAtomicResult.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheUpdateAtomicResult.java index 43ca819..34dbe52 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheUpdateAtomicResult.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheUpdateAtomicResult.java @@ -9,11 +9,12 @@ package org.gridgain.grid.kernal.processors.cache; -import org.gridgain.grid.kernal.processors.dr.*; import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.grid.util.tostring.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; + /** * Cache entry atomic update result. */ @@ -46,14 +47,18 @@ public class GridCacheUpdateAtomicResult { /** Whether update should be propagated to DHT node. */ private final boolean sndToDht; + /** Value computed by entry processor. */ + private EntryProcessorResult res; + /** * Constructor. * * @param success Success flag. * @param oldVal Old value. * @param newVal New value. + * @param res Value computed by the {@link EntryProcessor}. * @param newTtl New TTL. - * @param drExpireTime Explict DR expire time (if any). + * @param drExpireTime Explicit DR expire time (if any). * @param rmvVer Version for deferred delete. * @param drRes DR resolution result. * @param sndToDht Whether update should be propagated to DHT node. @@ -61,6 +66,7 @@ public class GridCacheUpdateAtomicResult { public GridCacheUpdateAtomicResult(boolean success, @Nullable V oldVal, @Nullable V newVal, + @Nullable EntryProcessorResult res, long newTtl, long drExpireTime, @Nullable GridCacheVersion rmvVer, @@ -69,6 +75,7 @@ public class GridCacheUpdateAtomicResult { this.success = success; this.oldVal = oldVal; this.newVal = newVal; + this.res = res; this.newTtl = newTtl; this.drExpireTime = drExpireTime; this.rmvVer = rmvVer; @@ -77,6 +84,13 @@ public class GridCacheUpdateAtomicResult { } /** + * @return Value computed by the {@link EntryProcessor}. + */ + @Nullable public EntryProcessorResult computedResult() { + return res; + } + + /** * @return Success flag. */ public boolean success() { diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridAtomicCacheQueueImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridAtomicCacheQueueImpl.java index 9ef3b7b..786e863 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridAtomicCacheQueueImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridAtomicCacheQueueImpl.java @@ -10,13 +10,13 @@ package org.gridgain.grid.kernal.processors.cache.datastructures; import org.apache.ignite.*; -import org.apache.ignite.lang.*; -import org.gridgain.grid.cache.*; +import org.apache.ignite.cache.*; import org.gridgain.grid.cache.datastructures.*; import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.util.*; /** @@ -39,7 +39,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { @SuppressWarnings("unchecked") @Override public boolean offer(T item) throws IgniteException { try { - Long idx = transformHeader(new AddClosure(id, 1)); + Long idx = transformHeader(new AddProcessor(id, 1)); if (idx == null) return false; @@ -52,13 +52,11 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { while (true) { try { - boolean putx = cache.putx(key, item, null); - - assert putx; + cache.put(key, item); break; } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { @@ -81,7 +79,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { @Nullable @Override public T poll() throws IgniteException { try { while (true) { - Long idx = transformHeader(new PollClosure(id)); + Long idx = transformHeader(new PollProcessor(id)); if (idx == null) return null; @@ -96,7 +94,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { while (true) { try { - T data = (T)cache.remove(key, null); + T data = (T)cache.getAndRemove(key); if (data != null) return data; @@ -105,7 +103,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { stop = U.currentTimeMillis() + RETRY_TIMEOUT; while (U.currentTimeMillis() < stop ) { - data = (T)cache.remove(key, null); + data = (T)cache.getAndRemove(key); if (data != null) return data; @@ -113,7 +111,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { break; } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { @@ -138,7 +136,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { A.notNull(items, "items"); try { - Long idx = transformHeader(new AddClosure(id, items.size())); + Long idx = transformHeader(new AddProcessor(id, items.size())); if (idx == null) return false; @@ -157,11 +155,11 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { while (true) { try { - cache.putAll(putMap, null); + cache.putAll(putMap); break; } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { @@ -182,7 +180,7 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override protected void removeItem(long rmvIdx) throws IgniteCheckedException { - Long idx = (Long)cache.transformAndCompute(queueKey, new RemoveClosure(id, rmvIdx)); + Long idx = (Long)cache.invoke(queueKey, new RemoveProcessor(id, rmvIdx)); if (idx != null) { checkRemoved(idx); @@ -195,20 +193,20 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { while (true) { try { - if (cache.removex(key)) + if (cache.remove(key)) return; if (stop == 0) stop = U.currentTimeMillis() + RETRY_TIMEOUT; while (U.currentTimeMillis() < stop ) { - if (cache.removex(key)) + if (cache.remove(key)) return; } break; } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { @@ -224,20 +222,20 @@ public class GridAtomicCacheQueueImpl extends GridCacheQueueAdapter { } /** - * @param c Transform closure to be applied for queue header. - * @return Value computed by the transform closure. + * @param c EntryProcessor to be applied for queue header. + * @return Value computed by the entry processor. * @throws IgniteCheckedException If failed. */ @SuppressWarnings("unchecked") - @Nullable private Long transformHeader(IgniteClosure> c) + @Nullable private Long transformHeader(EntryProcessor c) throws IgniteCheckedException { int cnt = 0; while (true) { try { - return (Long)cache.transformAndCompute(queueKey, c); + return (Long)cache.invoke(queueKey, c); } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (cnt++ == MAX_UPDATE_RETRIES) throw e; else { diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheDataStructuresManager.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheDataStructuresManager.java index b4fc6d2..35b10b7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheDataStructuresManager.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheDataStructuresManager.java @@ -735,7 +735,12 @@ public final class GridCacheDataStructuresManager extends GridCacheManager if (hdr.empty()) return true; - GridCacheQueueAdapter.removeKeys(cctx.cache(), hdr.id(), name, hdr.collocated(), hdr.head(), hdr.tail(), + GridCacheQueueAdapter.removeKeys(cctx.kernalContext().cache().jcache(cctx.cache().name()), + hdr.id(), + name, + hdr.collocated(), + hdr.head(), + hdr.tail(), batchSize); return true; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheQueueAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheQueueAdapter.java index b3277ed..ed00313 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheQueueAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridCacheQueueAdapter.java @@ -11,8 +11,6 @@ package org.gridgain.grid.kernal.processors.cache.datastructures; import org.apache.ignite.*; import org.apache.ignite.lang.*; -import org.gridgain.grid.*; -import org.gridgain.grid.cache.*; import org.gridgain.grid.cache.affinity.*; import org.gridgain.grid.cache.datastructures.*; import org.gridgain.grid.kernal.processors.cache.*; @@ -21,6 +19,7 @@ import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -50,7 +49,7 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp protected final GridCacheContext cctx; /** Cache. */ - protected final GridCacheAdapter cache; + protected final IgniteCache cache; /** Queue name. */ protected final String queueName; @@ -91,7 +90,7 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp cap = hdr.capacity(); collocated = hdr.collocated(); queueKey = new GridCacheQueueHeaderKey(queueName); - cache = cctx.cache(); + cache = cctx.kernalContext().cache().jcache(cctx.name()); log = cctx.logger(getClass()); @@ -130,34 +129,24 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public int size() { - try { - GridCacheQueueHeader hdr = (GridCacheQueueHeader)cache.get(queueKey); + GridCacheQueueHeader hdr = (GridCacheQueueHeader)cache.get(queueKey); - checkRemoved(hdr); + checkRemoved(hdr); - return hdr.size(); - } - catch (IgniteCheckedException e) { - throw new IgniteException(e); - } + return hdr.size(); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Nullable @Override public T peek() throws IgniteException { - try { - GridCacheQueueHeader hdr = (GridCacheQueueHeader)cache.get(queueKey); + GridCacheQueueHeader hdr = (GridCacheQueueHeader)cache.get(queueKey); - checkRemoved(hdr); + checkRemoved(hdr); - if (hdr.empty()) - return null; + if (hdr.empty()) + return null; - return (T)cache.get(itemKey(hdr.head())); - } - catch (IgniteCheckedException e) { - throw new IgniteException(e); - } + return (T)cache.get(itemKey(hdr.head())); } /** {@inheritDoc} */ @@ -333,8 +322,7 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp A.ensure(batchSize >= 0, "Batch size cannot be negative: " + batchSize); try { - IgniteBiTuple t = (IgniteBiTuple)cache.transformAndCompute(queueKey, - new ClearClosure(id)); + IgniteBiTuple t = (IgniteBiTuple)cache.invoke(queueKey, new ClearProcessor(id)); if (t == null) return; @@ -385,9 +373,16 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp * @throws IgniteCheckedException If failed. */ @SuppressWarnings("unchecked") - static void removeKeys(GridCacheProjection cache, IgniteUuid id, String name, boolean collocated, long startIdx, - long endIdx, int batchSize) throws IgniteCheckedException { - Collection keys = new ArrayList<>(batchSize > 0 ? batchSize : 10); + static void removeKeys(IgniteCache cache, + IgniteUuid id, + String name, + boolean collocated, + long startIdx, + long endIdx, + int batchSize) + throws IgniteCheckedException + { + Set keys = new HashSet<>(batchSize > 0 ? batchSize : 10); for (long idx = startIdx; idx < endIdx; idx++) { keys.add(itemKey(id, name, collocated, idx)); @@ -576,24 +571,19 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp if (next == null) throw new NoSuchElementException(); - try { - cur = next; - curIdx = idx; + cur = next; + curIdx = idx; - idx++; + idx++; - if (rmvIdxs != null) { - while (F.contains(rmvIdxs, idx) && idx < endIdx) - idx++; - } + if (rmvIdxs != null) { + while (F.contains(rmvIdxs, idx) && idx < endIdx) + idx++; + } - next = idx < endIdx ? (T)cache.get(itemKey(idx)) : null; + next = idx < endIdx ? (T)cache.get(itemKey(idx)) : null; - return cur; - } - catch (IgniteCheckedException e) { - throw new IgniteException(e); - } + return cur; } /** {@inheritDoc} */ @@ -646,9 +636,8 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** */ - protected static class ClearClosure implements IgniteClosure>>, - Externalizable { + protected static class ClearProcessor implements + EntryProcessor>, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -658,30 +647,39 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** * Required by {@link Externalizable}. */ - public ClearClosure() { + public ClearProcessor() { // No-op. } /** * @param id Queue unique ID. */ - public ClearClosure(IgniteUuid id) { + public ClearProcessor(IgniteUuid id) { this.id = id; } /** {@inheritDoc} */ - @Override public IgniteBiTuple> apply(GridCacheQueueHeader hdr) { + @Override public IgniteBiTuple process( + MutableEntry e, Object... args) { + GridCacheQueueHeader hdr = e.getValue(); + boolean rmvd = queueRemoved(hdr, id); if (rmvd) - return new IgniteBiTuple<>(hdr, new IgniteBiTuple<>(QUEUE_REMOVED_IDX, QUEUE_REMOVED_IDX)); + return new IgniteBiTuple<>(QUEUE_REMOVED_IDX, QUEUE_REMOVED_IDX); else if (hdr.empty()) - return new IgniteBiTuple<>(hdr, null); + return null; + + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + hdr.tail(), + hdr.tail(), + null); - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - hdr.tail(), hdr.tail(), null); + e.setValue(newHdr); - return new IgniteBiTuple<>(newHdr, new IgniteBiTuple<>(hdr.head(), hdr.tail())); + return new IgniteBiTuple<>(hdr.head(), hdr.tail()); } /** {@inheritDoc} */ @@ -697,8 +695,8 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** */ - protected static class PollClosure implements - IgniteClosure>, Externalizable { + protected static class PollProcessor implements + EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -708,31 +706,40 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** * Required by {@link Externalizable}. */ - public PollClosure() { + public PollProcessor() { // No-op. } /** * @param id Queue unique ID. */ - public PollClosure(IgniteUuid id) { + public PollProcessor(IgniteUuid id) { this.id = id; } /** {@inheritDoc} */ - @Override public IgniteBiTuple apply(GridCacheQueueHeader hdr) { + @Override public Long process( + MutableEntry e, Object... args) { + GridCacheQueueHeader hdr = e.getValue(); + boolean rmvd = queueRemoved(hdr, id); if (rmvd || hdr.empty()) - return new IgniteBiTuple<>(hdr, rmvd ? QUEUE_REMOVED_IDX : null); + return rmvd ? QUEUE_REMOVED_IDX : null; Set rmvdIdxs = hdr.removedIndexes(); if (rmvdIdxs == null) { - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - hdr.head() + 1, hdr.tail(), rmvdIdxs); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + hdr.head() + 1, + hdr.tail(), + rmvdIdxs); + + e.setValue(newHdr); - return new IgniteBiTuple<>(newHdr, hdr.head()); + return hdr.head(); } long next = hdr.head() + 1; @@ -741,19 +748,31 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp do { if (!rmvdIdxs.remove(next)) { - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - next + 1, hdr.tail(), rmvdIdxs.isEmpty() ? null : rmvdIdxs); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + next + 1, + hdr.tail(), + rmvdIdxs.isEmpty() ? null : rmvdIdxs); - return new IgniteBiTuple<>(newHdr, next); + e.setValue(newHdr); + + return next; } next++; } while (next != hdr.tail()); - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - next, hdr.tail(), rmvdIdxs.isEmpty() ? null : rmvdIdxs); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + next, + hdr.tail(), + rmvdIdxs.isEmpty() ? null : rmvdIdxs); + + e.setValue(newHdr); - return new IgniteBiTuple<>(newHdr, null); + return null; } /** {@inheritDoc} */ @@ -769,8 +788,8 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** */ - protected static class AddClosure implements - IgniteClosure>, Externalizable { + protected static class AddProcessor implements + EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -783,7 +802,7 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** * Required by {@link Externalizable}. */ - public AddClosure() { + public AddProcessor() { // No-op. } @@ -791,22 +810,30 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp * @param id Queue unique ID. * @param size Number of elements to add. */ - public AddClosure(IgniteUuid id, int size) { + public AddProcessor(IgniteUuid id, int size) { this.id = id; this.size = size; } /** {@inheritDoc} */ - @Override public IgniteBiTuple apply(GridCacheQueueHeader hdr) { + @Override public Long process(MutableEntry e, Object... args) { + GridCacheQueueHeader hdr = e.getValue(); + boolean rmvd = queueRemoved(hdr, id); if (rmvd || !spaceAvailable(hdr, size)) - return new IgniteBiTuple<>(hdr, rmvd ? QUEUE_REMOVED_IDX : null); + return rmvd ? QUEUE_REMOVED_IDX : null; - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - hdr.head(), hdr.tail() + size, hdr.removedIndexes()); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + hdr.head(), + hdr.tail() + size, + hdr.removedIndexes()); - return new IgniteBiTuple<>(newHdr, hdr.tail()); + e.setValue(newHdr); + + return hdr.tail(); } /** @@ -833,8 +860,8 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** */ - protected static class RemoveClosure implements - IgniteClosure>, Externalizable { + protected static class RemoveProcessor implements + EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -847,7 +874,7 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp /** * Required by {@link Externalizable}. */ - public RemoveClosure() { + public RemoveProcessor() { // No-op. } @@ -855,17 +882,19 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp * @param id Queue UUID. * @param idx Index of item to be removed. */ - public RemoveClosure(IgniteUuid id, Long idx) { + public RemoveProcessor(IgniteUuid id, Long idx) { this.id = id; this.idx = idx; } /** {@inheritDoc} */ - @Override public IgniteBiTuple apply(GridCacheQueueHeader hdr) { + @Override public Long process(MutableEntry e, Object... args) { + GridCacheQueueHeader hdr = e.getValue(); + boolean rmvd = queueRemoved(hdr, id); if (rmvd || hdr.empty() || idx < hdr.head()) - return new IgniteBiTuple<>(hdr, rmvd ? QUEUE_REMOVED_IDX : null); + return rmvd ? QUEUE_REMOVED_IDX : null; if (idx == hdr.head()) { Set rmvIdxs = hdr.removedIndexes(); @@ -873,10 +902,16 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp long head = hdr.head() + 1; if (!F.contains(rmvIdxs, head)) { - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - head, hdr.tail(), hdr.removedIndexes()); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + head, + hdr.tail(), + hdr.removedIndexes()); - return new IgniteBiTuple<>(newHdr, idx); + e.setValue(newHdr); + + return idx; } rmvIdxs = new HashSet<>(rmvIdxs); @@ -884,10 +919,16 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp while (rmvIdxs.remove(head)) head++; - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - head, hdr.tail(), rmvIdxs.isEmpty() ? null : rmvIdxs); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + head, + hdr.tail(), + rmvIdxs.isEmpty() ? null : rmvIdxs); + + e.setValue(newHdr); - return new IgniteBiTuple<>(newHdr, null); + return null; } Set rmvIdxs = hdr.removedIndexes(); @@ -907,10 +948,16 @@ public abstract class GridCacheQueueAdapter extends AbstractCollection imp idx = null; } - GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), hdr.capacity(), hdr.collocated(), - hdr.head(), hdr.tail(), rmvIdxs); + GridCacheQueueHeader newHdr = new GridCacheQueueHeader(hdr.id(), + hdr.capacity(), + hdr.collocated(), + hdr.head(), + hdr.tail(), + rmvIdxs); + + e.setValue(newHdr); - return new IgniteBiTuple<>(newHdr, idx); + return idx; } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridTransactionalCacheQueueImpl.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridTransactionalCacheQueueImpl.java index 1d58729..c9ad46e 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridTransactionalCacheQueueImpl.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/datastructures/GridTransactionalCacheQueueImpl.java @@ -17,6 +17,7 @@ import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; +import javax.cache.*; import java.util.*; import static org.apache.ignite.transactions.IgniteTxConcurrency.*; @@ -26,6 +27,9 @@ import static org.apache.ignite.transactions.IgniteTxIsolation.*; * {@link GridCacheQueue} implementation using transactional cache. */ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter { + /** */ + private final IgniteTransactions txs; + /** * @param queueName Queue name. * @param hdr Queue header. @@ -33,6 +37,8 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter */ public GridTransactionalCacheQueueImpl(String queueName, GridCacheQueueHeader hdr, GridCacheContext cctx) { super(queueName, hdr, cctx); + + txs = cctx.kernalContext().grid().transactions(); } /** {@inheritDoc} */ @@ -47,15 +53,13 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter while (true) { try { - try (IgniteTx tx = cache.txStart(PESSIMISTIC, REPEATABLE_READ)) { - Long idx = (Long)cache.transformAndCompute(queueKey, new AddClosure(id, 1)); + try (IgniteTx tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { + Long idx = (Long)cache.invoke(queueKey, new AddProcessor(id, 1)); if (idx != null) { checkRemoved(idx); - boolean putx = cache.putx(itemKey(idx), item, null); - - assert putx; + cache.put(itemKey(idx), item); retVal = true; } @@ -67,17 +71,21 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter break; } } - catch (ClusterGroupEmptyException e) { - throw e; - } - catch (ClusterTopologyException e) { - if (cnt++ == MAX_UPDATE_RETRIES) + catch (CacheException e) { + if (e.getCause() instanceof ClusterGroupEmptyException) throw e; - else { - U.warn(log, "Failed to add item, will retry [err=" + e + ']'); - U.sleep(RETRY_DELAY); + if (e.getCause() instanceof ClusterTopologyException) { + if (cnt++ == MAX_UPDATE_RETRIES) + throw e; + else { + U.warn(log, "Failed to add item, will retry [err=" + e + ']'); + + U.sleep(RETRY_DELAY); + } } + else + throw e; } } @@ -97,13 +105,13 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter T retVal; while (true) { - try (IgniteTx tx = cache.txStart(PESSIMISTIC, REPEATABLE_READ)) { - Long idx = (Long)cache.transformAndCompute(queueKey, new PollClosure(id)); + try (IgniteTx tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { + Long idx = (Long)cache.invoke(queueKey, new PollProcessor(id)); if (idx != null) { checkRemoved(idx); - retVal = (T)cache.remove(itemKey(idx), null); + retVal = (T)cache.getAndRemove(itemKey(idx)); assert retVal != null; } @@ -114,17 +122,21 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter break; } - catch (ClusterGroupEmptyException e) { - throw e; - } - catch(ClusterTopologyException e) { - if (cnt++ == MAX_UPDATE_RETRIES) + catch (CacheException e) { + if (e.getCause() instanceof ClusterGroupEmptyException) throw e; - else { - U.warn(log, "Failed to poll, will retry [err=" + e + ']'); - U.sleep(RETRY_DELAY); + if (e.getCause() instanceof ClusterTopologyException) { + if (cnt++ == MAX_UPDATE_RETRIES) + throw e; + else { + U.warn(log, "Failed to add item, will retry [err=" + e + ']'); + + U.sleep(RETRY_DELAY); + } } + else + throw e; } } @@ -146,8 +158,8 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter int cnt = 0; while (true) { - try (IgniteTx tx = cache.txStart(PESSIMISTIC, REPEATABLE_READ)) { - Long idx = (Long)cache.transformAndCompute(queueKey, new AddClosure(id, items.size())); + try (IgniteTx tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { + Long idx = (Long)cache.invoke(queueKey, new AddProcessor(id, items.size())); if (idx != null) { checkRemoved(idx); @@ -160,7 +172,7 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter idx++; } - cache.putAll(putMap, null); + cache.putAll(putMap); retVal = true; } @@ -171,17 +183,21 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter break; } - catch (ClusterGroupEmptyException e) { - throw e; - } - catch(ClusterTopologyException e) { - if (cnt++ == MAX_UPDATE_RETRIES) + catch (CacheException e) { + if (e.getCause() instanceof ClusterGroupEmptyException) throw e; - else { - U.warn(log, "Failed to addAll, will retry [err=" + e + ']'); - U.sleep(RETRY_DELAY); + if (e.getCause() instanceof ClusterTopologyException) { + if (cnt++ == MAX_UPDATE_RETRIES) + throw e; + else { + U.warn(log, "Failed to add item, will retry [err=" + e + ']'); + + U.sleep(RETRY_DELAY); + } } + else + throw e; } } @@ -199,13 +215,13 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter int cnt = 0; while (true) { - try (IgniteTx tx = cache.txStart(PESSIMISTIC, REPEATABLE_READ)) { - Long idx = (Long)cache.transformAndCompute(queueKey, new RemoveClosure(id, rmvIdx)); + try (IgniteTx tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { + Long idx = (Long)cache.invoke(queueKey, new RemoveProcessor(id, rmvIdx)); if (idx != null) { checkRemoved(idx); - boolean rmv = cache.removex(itemKey(idx)); + boolean rmv = cache.remove(itemKey(idx)); assert rmv; } @@ -214,17 +230,21 @@ public class GridTransactionalCacheQueueImpl extends GridCacheQueueAdapter break; } - catch (ClusterGroupEmptyException e) { - throw e; - } - catch(ClusterTopologyException e) { - if (cnt++ == MAX_UPDATE_RETRIES) + catch (CacheException e) { + if (e.getCause() instanceof ClusterGroupEmptyException) throw e; - else { - U.warn(log, "Failed to remove item, will retry [err=" + e + ", idx=" + rmvIdx + ']'); - U.sleep(RETRY_DELAY); + if (e.getCause() instanceof ClusterTopologyException) { + if (cnt++ == MAX_UPDATE_RETRIES) + throw e; + else { + U.warn(log, "Failed to add item, will retry [err=" + e + ']'); + + U.sleep(RETRY_DELAY); + } } + else + throw e; } } } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedLockResponse.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedLockResponse.java index 8edfc7c..76fd449 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedLockResponse.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedLockResponse.java @@ -57,11 +57,15 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessag } /** + * @param cacheId Cache ID. * @param lockVer Lock version. * @param futId Future ID. * @param cnt Key count. */ - public GridDistributedLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, int cnt) { + public GridDistributedLockResponse(int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + int cnt) { super(lockVer, cnt); assert futId != null; @@ -74,11 +78,15 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessag } /** + * @param cacheId Cache ID. * @param lockVer Lock ID. * @param futId Future ID. * @param err Error. */ - public GridDistributedLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, Throwable err) { + public GridDistributedLockResponse(int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + Throwable err) { super(lockVer, 0); assert futId != null; @@ -89,12 +97,17 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessag } /** + * @param cacheId Cache ID. * @param lockVer Lock ID. * @param futId Future ID. * @param cnt Count. * @param err Error. */ - public GridDistributedLockResponse(int cacheId, GridCacheVersion lockVer, IgniteUuid futId, int cnt, Throwable err) { + public GridDistributedLockResponse(int cacheId, + GridCacheVersion lockVer, + IgniteUuid futId, + int cnt, + Throwable err) { super(lockVer, cnt); assert futId != null; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java index 4a93646..d507d0d 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java @@ -83,6 +83,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter * @param timeout Timeout. * @param txSize Expected transaction size. * @param grpLockKey Group lock key if this is a group-lock transaction. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. */ public GridDistributedTxRemoteAdapter( GridCacheSharedContext ctx, @@ -325,7 +327,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter else { // Copy values. entry.value(e.value(), e.hasWriteValue(), e.hasReadValue()); - entry.transformClosures(e.transformClosures()); + entry.entryProcessors(e.entryProcessors()); entry.valueBytes(e.valueBytes()); entry.op(e.op()); entry.ttl(e.ttl()); @@ -481,7 +483,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter if (updateNearCache(cacheCtx, txEntry.key(), topVer)) nearCached = cacheCtx.dht().near().peekExx(txEntry.key()); - if (!F.isEmpty(txEntry.transformClosures()) || !F.isEmpty(txEntry.filters())) + if (!F.isEmpty(txEntry.entryProcessors()) || !F.isEmpty(txEntry.filters())) txEntry.cached().unswap(true, false); GridTuple3 res = applyTransformClosures(txEntry, diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java index dc8ddcb..b7ff63e 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java @@ -215,7 +215,7 @@ public abstract class GridDhtTransactionalCacheAdapter extends GridDhtCach req.keyBytes() != null ? req.keyBytes().get(i) : null, writeEntry == null ? null : writeEntry.value(), writeEntry == null ? null : writeEntry.valueBytes(), - writeEntry == null ? null : writeEntry.transformClosures(), + writeEntry == null ? null : writeEntry.entryProcessors(), drVer, req.accessTtl()); diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocal.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocal.java index 0f11ecc..32e43a7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocal.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocal.java @@ -340,8 +340,13 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements * @return Future that will be completed when locks are acquired. */ public IgniteFuture> prepareAsync(@Nullable Iterable> reads, - @Nullable Iterable> writes, Map, GridCacheVersion> verMap, long msgId, - IgniteUuid nearMiniId, Map> txNodes, boolean last, Collection lastBackups) { + @Nullable Iterable> writes, + Map, GridCacheVersion> verMap, + long msgId, + IgniteUuid nearMiniId, + Map> txNodes, + boolean last, + Collection lastBackups) { assert optimistic(); // In optimistic mode prepare still can be called explicitly from salvageTx. diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java index b752178..55d8f7a 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java @@ -406,7 +406,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter extends IgniteTxLocalAdapter w = writeEntries == null ? null : writeEntries.get(idx++); + IgniteTxEntry + w = writeEntries == null ? null : writeEntries.get(idx++); txEntry = addEntry(NOOP, null, null, + null, cached, null, CU.empty(), @@ -545,7 +547,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter extends IgniteTxLocalAdapterempty() : filter); + filter == null ? CU.empty() : filter, + /**computeInvoke*/false); return ret; } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxRemote.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxRemote.java index 97ec1af..2b4491f 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxRemote.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridDhtTxRemote.java @@ -16,9 +16,11 @@ import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.kernal.processors.cache.distributed.*; import org.gridgain.grid.kernal.processors.cache.transactions.*; import org.gridgain.grid.util.tostring.*; +import org.gridgain.grid.util.typedef.*; import org.jdk8.backport.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; @@ -280,7 +282,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter * @param val Value. * @param valBytes Value bytes. * @param drVer Data center replication version. - * @param clos Transform closures. + * @param entryProcessors Entry processors. * @param ttl TTL. */ public void addWrite(GridCacheContext cacheCtx, @@ -289,7 +291,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter byte[] keyBytes, @Nullable V val, @Nullable byte[] valBytes, - @Nullable Collection> clos, + @Nullable Collection, Object[]>> entryProcessors, @Nullable GridCacheVersion drVer, long ttl) { checkInternal(key); @@ -310,7 +312,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter txEntry.keyBytes(keyBytes); txEntry.valueBytes(valBytes); - txEntry.transformClosures(clos); + txEntry.entryProcessors(entryProcessors); writeMap.put(key, txEntry); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java index 2c988e7..ea952d7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java @@ -34,6 +34,7 @@ import org.jetbrains.annotations.*; import sun.misc.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -306,14 +307,30 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { @SuppressWarnings("unchecked") @Override public IgniteFuture putAsync(K key, V val, @Nullable GridCacheEntryEx entry, long ttl, @Nullable IgnitePredicate>... filter) { - return updateAllAsync0(F0.asMap(key, val), null, null, null, true, false, entry, ttl, filter); + return updateAllAsync0(F0.asMap(key, val), + null, + null, + null, + null, + true, + false, + entry, + filter); } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public IgniteFuture putxAsync(K key, V val, @Nullable GridCacheEntryEx entry, long ttl, @Nullable IgnitePredicate>... filter) { - return updateAllAsync0(F0.asMap(key, val), null, null, null, false, false, entry, ttl, filter); + return updateAllAsync0(F0.asMap(key, val), + null, + null, + null, + null, + false, + false, + entry, + filter); } /** {@inheritDoc} */ @@ -385,7 +402,14 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public IgniteFuture> replacexAsync(K key, V oldVal, V newVal) { - return updateAllAsync0(F.asMap(key, newVal), null, null, null, true, true, null, 0, + return updateAllAsync0(F.asMap(key, newVal), + null, + null, + null, + null, + true, + true, + null, ctx.equalsPeekArray(oldVal)); } @@ -398,7 +422,15 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { /** {@inheritDoc} */ @Override public IgniteFuture putAllAsync(Map m, @Nullable IgnitePredicate>[] filter) { - return updateAllAsync0(m, null, null, null, false, false, null, 0, filter); + return updateAllAsync0(m, + null, + null, + null, + null, + false, + false, + null, + filter); } /** {@inheritDoc} */ @@ -410,43 +442,18 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { @Override public IgniteFuture putAllDrAsync(Map> drMap) { ctx.dr().onReceiveCacheEntriesReceived(drMap.size()); - return updateAllAsync0(null, null, drMap, null, false, false, null, 0, null); - } - - /** {@inheritDoc} */ - @Override public void transform(K key, IgniteClosure transformer) throws IgniteCheckedException { - transformAsync(key, transformer).get(); - } - - /** {@inheritDoc} */ - @Override public R transformAndCompute(K key, IgniteClosure> transformer) - throws IgniteCheckedException { - return (R)updateAllAsync0(null, - Collections.singletonMap(key, new GridCacheTransformComputeClosure<>(transformer)), null, null, true, - false, null, 0, null).get(); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(K key, IgniteClosure transformer, - @Nullable GridCacheEntryEx entry, long ttl) { - return updateAllAsync0(null, Collections.singletonMap(key, transformer), null, null, false, false, entry, ttl, + return updateAllAsync0(null, + null, + null, + drMap, + null, + false, + false, + null, null); } /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Map> m) throws IgniteCheckedException { - transformAllAsync(m).get(); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Map> m) { - if (F.isEmpty(m)) - return new GridFinishedFuture(ctx.kernalContext()); - - return updateAllAsync0(null, m, null, null, false, false, null, 0, null); - } - - /** {@inheritDoc} */ @Override public V remove(K key, @Nullable GridCacheEntryEx entry, @Nullable IgnitePredicate>... filter) throws IgniteCheckedException { return removeAsync(key, entry, filter).get(); @@ -579,29 +586,142 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { "GridCacheAtomicityMode.ATOMIC mode (use GridCacheAtomicityMode.TRANSACTIONAL instead)")); } + /** {@inheritDoc} */ + @Override public EntryProcessorResult invoke(K key, EntryProcessor entryProcessor, Object... args) + throws IgniteCheckedException { + return invokeAsync(key, entryProcessor, args).get(); + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) + throws IgniteCheckedException { + return invokeAllAsync(keys, entryProcessor, args).get(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args) { + A.notNull(key, "key", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKey(key); + + ctx.denyOnLocalRead(); + + Map invokeMap = + Collections.singletonMap(key, (EntryProcessor)entryProcessor); + + IgniteFuture>> fut = updateAllAsync0(null, + invokeMap, + args, + null, + null, + true, + false, + null, + null); + + return fut.chain(new CX1>>, EntryProcessorResult>() { + @Override public EntryProcessorResult applyx(IgniteFuture>> fut) + throws IgniteCheckedException { + Map> resMap = fut.get(); + + if (resMap != null) { + assert resMap.isEmpty() || resMap.size() == 1 : resMap.size(); + + return resMap.isEmpty() ? null : resMap.values().iterator().next(); + } + + return null; + } + }); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public IgniteFuture>> invokeAllAsync(Set keys, + final EntryProcessor entryProcessor, + Object... args) { + A.notNull(keys, "keys", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKeys(keys); + + ctx.denyOnLocalRead(); + + Map invokeMap = F.viewAsMap(keys, new C1() { + @Override public EntryProcessor apply(K k) { + return entryProcessor; + } + }); + + return updateAllAsync0(null, + invokeMap, + args, + null, + null, + true, + false, + null, + null); + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException { + return invokeAllAsync(map, args).get(); + } + + /** {@inheritDoc} */ + @Override public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args) { + A.notNull(map, "map"); + + if (keyCheck) + validateCacheKeys(map.keySet()); + + ctx.denyOnLocalRead(); + + return updateAllAsync0(null, + map, + args, + null, + null, + true, + false, + null, + null); + } + /** * Entry point for all public API put/transform methods. * - * @param map Put map. Either {@code map}, {@code transformMap} or {@code drMap} should be passed. - * @param transformMap Transform map. Either {@code map}, {@code transformMap} or {@code drMap} should be passed. + * @param map Put map. Either {@code map}, {@code invokeMap} or {@code drMap} should be passed. + * @param invokeMap Invoke map. Either {@code map}, {@code invokeMap} or {@code drMap} should be passed. + * @param invokeArgs Optional arguments for EntryProcessor. * @param drPutMap DR put map. * @param drRmvMap DR remove map. * @param retval Return value required flag. * @param rawRetval Return {@code GridCacheReturn} instance. * @param cached Cached cache entry for key. May be passed if and only if map size is {@code 1}. - * @param ttl Entry time-to-live. * @param filter Cache entry filter for atomic updates. * @return Completion future. */ private IgniteFuture updateAllAsync0( @Nullable final Map map, - @Nullable final Map> transformMap, + @Nullable final Map invokeMap, + @Nullable Object[] invokeArgs, @Nullable final Map> drPutMap, @Nullable final Map drRmvMap, final boolean retval, final boolean rawRetval, @Nullable GridCacheEntryEx cached, - long ttl, @Nullable final IgnitePredicate>[] filter ) { if (map != null && keyCheck) @@ -619,10 +739,11 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { ctx, this, ctx.config().getWriteSynchronizationMode(), - transformMap != null ? TRANSFORM : UPDATE, - map != null ? map.keySet() : transformMap != null ? transformMap.keySet() : drPutMap != null ? + invokeMap != null ? TRANSFORM : UPDATE, + map != null ? map.keySet() : invokeMap != null ? invokeMap.keySet() : drPutMap != null ? drPutMap.keySet() : drRmvMap.keySet(), - map != null ? map.values() : transformMap != null ? transformMap.values() : null, + map != null ? map.values() : invokeMap != null ? invokeMap.values() : null, + invokeArgs, drPutMap != null ? drPutMap.values() : null, drRmvMap != null ? drRmvMap.values() : null, retval, @@ -682,6 +803,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { keys != null ? keys : drMap.keySet(), null, null, + null, keys != null ? null : drMap.values(), retval, rawRetval, @@ -692,8 +814,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { taskNameHash); return asyncOp(new CO>() { - @Override - public IgniteFuture apply() { + @Override public IgniteFuture apply() { updateFut.map(); return updateFut; @@ -858,11 +979,11 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { IgniteFuture forceFut = preldr.request(req.keys(), req.topologyVersion()); if (forceFut.isDone()) - updateAllAsyncInternal0(nodeId, req, cached, completionCb); + updateAllAsyncInternal0(nodeId, req, completionCb); else { forceFut.listenAsync(new CI1>() { @Override public void apply(IgniteFuture t) { - updateAllAsyncInternal0(nodeId, req, cached, completionCb); + updateAllAsyncInternal0(nodeId, req, completionCb); } }); } @@ -873,13 +994,11 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { * * @param nodeId Node ID. * @param req Update request. - * @param cached Cached entry if updating single local entry. * @param completionCb Completion callback. */ public void updateAllAsyncInternal0( UUID nodeId, GridNearAtomicUpdateRequest req, - @Nullable GridCacheEntryEx cached, CI2, GridNearAtomicUpdateResponse> completionCb ) { GridNearAtomicUpdateResponse res = new GridNearAtomicUpdateResponse<>(ctx.cacheId(), nodeId, @@ -887,7 +1006,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { List keys = req.keys(); - assert !req.returnValue() || keys.size() == 1; + assert !req.returnValue() || (req.operation() == TRANSFORM || keys.size() == 1); GridDhtAtomicUpdateFuture dhtFut = null; @@ -966,6 +1085,9 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { deleted = updRes.deleted(); dhtFut = updRes.dhtFuture(); + + if (req.operation() == TRANSFORM) + retVal = new GridCacheReturn<>((Object)updRes.invokeResults(), true); } else { UpdateSingleResult updRes = updateSingle(node, @@ -1075,8 +1197,8 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { String taskName, @Nullable IgniteCacheExpiryPolicy expiry ) throws GridCacheEntryRemovedException { - // Cannot update in batches during DR due to possible conflicts. - assert !req.returnValue(); // Should not request return values for putAll. + assert !ctx.dr().receiveEnabled(); // Cannot update in batches during DR due to possible conflicts. + assert !req.returnValue() || req.operation() == TRANSFORM; // Should not request return values for putAll. if (!F.isEmpty(req.filter())) { try { @@ -1092,12 +1214,20 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { int size = req.keys().size(); Map putMap = null; - Map> transformMap = null; + + Map> entryProcessorMap = null; + Collection rmvKeys = null; + UpdateBatchResult updRes = new UpdateBatchResult<>(); + List> filtered = new ArrayList<>(size); + GridCacheOperation op = req.operation(); + Map invokeResMap = + op == TRANSFORM ? U.newHashMap(size) : null; + int firstEntryIdx = 0; boolean intercept = ctx.config().getInterceptor() != null; @@ -1136,7 +1266,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { } if (op == TRANSFORM) { - IgniteClosure transform = req.transformClosure(i); + EntryProcessor entryProcessor = req.entryProcessor(i); V old = entry.innerGet( null, @@ -1148,17 +1278,32 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { /*event*/true, /*temporary*/true, req.subjectId(), - transform, + entryProcessor, taskName, CU.empty(), null); - if (transformMap == null) - transformMap = new HashMap<>(); + CacheInvokeEntry invokeEntry = new CacheInvokeEntry<>(entry.key(), old); - transformMap.put(entry.key(), transform); + V updated; + CacheInvokeResult invokeRes = null; - V updated = transform.apply(old); + try { + Object computed = entryProcessor.process(invokeEntry, req.invokeArguments()); + + updated = ctx.unwrapTemporary(invokeEntry.getValue()); + + if (computed != null) + invokeRes = new CacheInvokeResult<>(ctx.unwrapTemporary(computed)); + } + catch (Exception e) { + invokeRes = new CacheInvokeResult<>(e); + + updated = old; + } + + if (invokeRes != null) + invokeResMap.put(entry.key(), invokeRes); if (updated == null) { if (intercept) { @@ -1179,7 +1324,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { node, putMap, null, - transformMap, + entryProcessorMap, dhtFut, completionCb, req, @@ -1192,7 +1337,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { firstEntryIdx = i + 1; putMap = null; - transformMap = null; + entryProcessorMap = null; filtered = new ArrayList<>(); } @@ -1221,7 +1366,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { node, null, rmvKeys, - transformMap, + entryProcessorMap, dhtFut, completionCb, req, @@ -1234,7 +1379,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { firstEntryIdx = i + 1; rmvKeys = null; - transformMap = null; + entryProcessorMap = null; filtered = new ArrayList<>(); } @@ -1244,6 +1389,11 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { putMap.put(entry.key(), ctx.unwrapTemporary(updated)); } + + if (entryProcessorMap == null) + entryProcessorMap = new HashMap<>(); + + entryProcessorMap.put(entry.key(), entryProcessor); } else if (op == UPDATE) { V updated = req.value(i); @@ -1331,7 +1481,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { node, putMap, rmvKeys, - transformMap, + entryProcessorMap, dhtFut, completionCb, req, @@ -1346,6 +1496,8 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { updRes.dhtFuture(dhtFut); + updRes.invokeResult(invokeResMap); + return updRes; } @@ -1442,6 +1594,8 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { boolean intercept = ctx.config().getInterceptor() != null; + Map> computedMap = null; + // Avoid iterator creation. for (int i = 0; i < keys.size(); i++) { K k = keys.get(i); @@ -1487,6 +1641,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { op, writeVal, newValBytes, + req.invokeArguments(), primary && storeEnabled(), req.returnValue(), expiry, @@ -1524,16 +1679,16 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { newValBytes = null; // Value has been changed. } - IgniteClosure transformC = null; + EntryProcessor entryProcessor = null; if (req.forceTransformBackups() && op == TRANSFORM) - transformC = (IgniteClosure)writeVal; + entryProcessor = (EntryProcessor)writeVal; if (!readersOnly) { dhtFut.addWriteEntry(entry, updRes.newValue(), newValBytes, - transformC, + entryProcessor, updRes.newTtl(), expireTime, newDrVer); @@ -1544,7 +1699,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { entry, updRes.newValue(), newValBytes, - transformC, + entryProcessor, ttl, expireTime); } @@ -1599,17 +1754,26 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { deleted.add(F.t(entry, updRes.removeVersion())); } - // Create only once. - if (retVal == null) { - Object ret = updRes.oldValue(); + if (op == TRANSFORM) { + assert req.returnValue(); - if (op == TRANSFORM && writeVal instanceof GridCacheTransformComputeClosure) { - assert req.returnValue(); + if (updRes.computedResult() != null) { + if (retVal == null) { + computedMap = U.newHashMap(keys.size()); - ret = ((GridCacheTransformComputeClosure)writeVal).returnValue(); + retVal = new GridCacheReturn<>((Object)computedMap, updRes.success()); + } + + computedMap.put(k, updRes.computedResult()); } + } + else { + // Create only once. + if (retVal == null) { + Object ret = updRes.oldValue(); - retVal = new GridCacheReturn<>(req.returnValue() ? ret : null, updRes.success()); + retVal = new GridCacheReturn<>(req.returnValue() ? ret : null, updRes.success()); + } } } catch (IgniteCheckedException e) { @@ -1628,7 +1792,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { * @param node Originating node. * @param putMap Values to put. * @param rmvKeys Keys to remove. - * @param transformMap Transform closures. + * @param entryProcessorMap Entry processors. * @param dhtFut DHT update future if has backups. * @param completionCb Completion callback to invoke when DHT future is completed. * @param req Request. @@ -1648,7 +1812,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { ClusterNode node, @Nullable Map putMap, @Nullable Collection rmvKeys, - @Nullable Map> transformMap, + @Nullable Map> entryProcessorMap, @Nullable GridDhtAtomicUpdateFuture dhtFut, CI2, GridNearAtomicUpdateResponse> completionCb, final GridNearAtomicUpdateRequest req, @@ -1740,6 +1904,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { op, writeVal, null, + null, false, false, expiry, @@ -1784,13 +1949,14 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { byte[] valBytes = valBytesTuple.getIfMarshaled(); - IgniteClosure transformC = transformMap == null ? null : transformMap.get(entry.key()); + EntryProcessor entryProcessor = + entryProcessorMap == null ? null : entryProcessorMap.get(entry.key()); if (!batchRes.readersOnly()) dhtFut.addWriteEntry(entry, writeVal, valBytes, - transformC, + entryProcessor, updRes.newTtl(), -1, null); @@ -1800,7 +1966,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { entry, writeVal, valBytes, - transformC, + entryProcessor, updRes.newTtl(), -1); } @@ -2086,6 +2252,7 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { req.operation(), req.keys(), vals, + req.invokeArguments(), drPutVals, drRmvVals, req.returnValue(), @@ -2229,9 +2396,9 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { V val = req.value(i); byte[] valBytes = req.valueBytes(i); - IgniteClosure transform = req.transformClosure(i); + EntryProcessor entryProcessor = req.entryProcessor(i); - GridCacheOperation op = transform != null ? TRANSFORM : + GridCacheOperation op = entryProcessor != null ? TRANSFORM : (val != null || valBytes != null) ? UPDATE : DELETE; @@ -2247,8 +2414,9 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { nodeId, nodeId, op, - op == TRANSFORM ? transform : val, + op == TRANSFORM ? entryProcessor : val, valBytes, + op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/false, /*retval*/false, /*expiry policy*/null, @@ -2487,12 +2655,16 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { /** */ private boolean readersOnly; + /** */ + private Map invokeRes; + /** * @param entry Entry. * @param updRes Entry update result. * @param entries All entries. */ - private void addDeleted(GridDhtCacheEntry entry, GridCacheUpdateAtomicResult updRes, + private void addDeleted(GridDhtCacheEntry entry, + GridCacheUpdateAtomicResult updRes, Collection> entries) { if (updRes.removeVersion() != null) { if (deleted == null) @@ -2517,6 +2689,20 @@ public class GridDhtAtomicCache extends GridDhtCacheAdapter { } /** + * @param invokeRes Result for invoke operation. + */ + private void invokeResult(Map invokeRes) { + this.invokeRes = invokeRes; + } + + /** + * @return Result for invoke operation. + */ + Map invokeResults() { + return invokeRes; + } + + /** * @param dhtFut DHT future. */ private void dhtFuture(@Nullable GridDhtAtomicUpdateFuture dhtFut) { diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java index 8602ae3..88cc8f6 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateFuture.java @@ -22,6 +22,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jdk8.backport.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -197,7 +198,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter * @param entry Entry to map. * @param val Value to write. * @param valBytes Value bytes. - * @param transformC Transform closure. + * @param entryProcessor Entry processor. * @param ttl TTL (optional). * @param drExpireTime DR expire time (optional). * @param drVer DR version (optional). @@ -205,7 +206,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter public void addWriteEntry(GridDhtCacheEntry entry, @Nullable V val, @Nullable byte[] valBytes, - IgniteClosure transformC, + EntryProcessor entryProcessor, long ttl, long drExpireTime, @Nullable GridCacheVersion drVer) { @@ -236,7 +237,8 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter topVer, forceTransformBackups, this.updateReq.subjectId(), - this.updateReq.taskNameHash()); + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null); mappings.put(nodeId, updateReq); } @@ -245,7 +247,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter entry.keyBytes(), val, valBytes, - transformC, + entryProcessor, ttl, drExpireTime, drVer); @@ -258,7 +260,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter * @param entry Entry. * @param val Value. * @param valBytes Value bytes. - * @param transformC Transform closure. + * @param entryProcessor Entry processor.. * @param ttl TTL for near cache update (optional). * @param expireTime Expire time for near cache update (optional). */ @@ -266,7 +268,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter GridDhtCacheEntry entry, @Nullable V val, @Nullable byte[] valBytes, - IgniteClosure transformC, + EntryProcessor entryProcessor, long ttl, long expireTime) { GridCacheWriteSynchronizationMode syncMode = updateReq.writeSynchronizationMode(); @@ -294,7 +296,8 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter topVer, forceTransformBackups, this.updateReq.subjectId(), - this.updateReq.taskNameHash()); + this.updateReq.taskNameHash(), + forceTransformBackups ? this.updateReq.invokeArguments() : null); mappings.put(nodeId, updateReq); } @@ -308,7 +311,7 @@ public class GridDhtAtomicUpdateFuture extends GridFutureAdapter entry.keyBytes(), val, valBytes, - transformC, + entryProcessor, ttl, expireTime); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java index 2b68734..c34a221 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridDhtAtomicUpdateRequest.java @@ -10,7 +10,6 @@ package org.gridgain.grid.kernal.processors.cache.distributed.dht.atomic; import org.apache.ignite.*; -import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.kernal.*; import org.gridgain.grid.kernal.processors.cache.*; @@ -20,6 +19,7 @@ import org.gridgain.grid.util.tostring.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.nio.*; import java.util.*; @@ -111,23 +111,30 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp @GridDirectVersion(2) private boolean forceTransformBackups; - /** Transform closures. */ + /** Entry processors. */ @GridDirectTransient - private List> transformClos; + private List> entryProcessors; - /** Transform closure bytes. */ + /** Entry processors bytes. */ @GridDirectCollection(byte[].class) @GridDirectVersion(2) - private List transformClosBytes; + private List entryProcessorsBytes; - /** Near transform closures. */ + /** Near entry processors. */ @GridDirectTransient - private List> nearTransformClos; + private List> nearEntryProcessors; - /** Near transform closures bytes. */ + /** Near entry processors bytes. */ @GridDirectCollection(byte[].class) @GridDirectVersion(2) - private List nearTransformClosBytes; + private List nearEntryProcessorsBytes; + + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; /** Subject ID. */ @GridDirectVersion(3) @@ -151,6 +158,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp * @param nodeId Node ID. * @param futVer Future version. * @param writeVer Write version for cache values. + * @param invokeArgs Optional arguments for entry processor. * @param syncMode Cache write synchronization mode. * @param topVer Topology version. * @param forceTransformBackups Force transform backups flag. @@ -166,8 +174,11 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp long topVer, boolean forceTransformBackups, UUID subjId, - int taskNameHash + int taskNameHash, + Object[] invokeArgs ) { + assert invokeArgs == null || forceTransformBackups; + this.cacheId = cacheId; this.nodeId = nodeId; this.futVer = futVer; @@ -177,13 +188,14 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp this.forceTransformBackups = forceTransformBackups; this.subjId = subjId; this.taskNameHash = taskNameHash; + this.invokeArgs = invokeArgs; keys = new ArrayList<>(); keyBytes = new ArrayList<>(); if (forceTransformBackups) { - transformClos = new ArrayList<>(); - transformClosBytes = new ArrayList<>(); + entryProcessors = new ArrayList<>(); + entryProcessorsBytes = new ArrayList<>(); } else { vals = new ArrayList<>(); @@ -203,7 +215,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp * @param keyBytes Key bytes, if key was already serialized. * @param val Value, {@code null} if should be removed. * @param valBytes Value bytes, {@code null} if should be removed. - * @param transformC Transform closure. + * @param entryProcessor Entry processor. * @param ttl TTL (optional). * @param drExpireTime DR expire time (optional). * @param drVer DR version (optional). @@ -212,15 +224,18 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp @Nullable byte[] keyBytes, @Nullable V val, @Nullable byte[] valBytes, - IgniteClosure transformC, + EntryProcessor entryProcessor, long ttl, long drExpireTime, @Nullable GridCacheVersion drVer) { keys.add(key); this.keyBytes.add(keyBytes); - if (forceTransformBackups && transformC != null) - transformClos.add(transformC); + if (forceTransformBackups) { + assert entryProcessor != null; + + entryProcessors.add(entryProcessor); + } else { vals.add(val); this.valBytes.add(valBytes != null ? GridCacheValueBytes.marshaled(valBytes) : null); @@ -270,7 +285,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp * @param keyBytes Key bytes, if key was already serialized. * @param val Value, {@code null} if should be removed. * @param valBytes Value bytes, {@code null} if should be removed. - * @param transformC Transform closure. + * @param entryProcessor Entry processor. * @param ttl TTL. * @param expireTime Expire time. */ @@ -278,7 +293,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp @Nullable byte[] keyBytes, @Nullable V val, @Nullable byte[] valBytes, - IgniteClosure transformC, + EntryProcessor entryProcessor, long ttl, long expireTime) { @@ -287,8 +302,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp nearKeyBytes = new ArrayList<>(); if (forceTransformBackups) { - nearTransformClos = new ArrayList<>(); - nearTransformClosBytes = new ArrayList<>(); + nearEntryProcessors = new ArrayList<>(); + nearEntryProcessorsBytes = new ArrayList<>(); } else { nearVals = new ArrayList<>(); @@ -300,9 +315,9 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp nearKeyBytes.add(keyBytes); if (forceTransformBackups) { - assert transformC != null; + assert entryProcessor != null; - nearTransformClos.add(transformC); + nearEntryProcessors.add(entryProcessor); } else { nearVals.add(val); @@ -465,10 +480,10 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp /** * @param idx Key index. - * @return Transform closure. + * @return Entry processor. */ - @Nullable public IgniteClosure transformClosure(int idx) { - return transformClos == null ? null : transformClos.get(idx); + @Nullable public EntryProcessor entryProcessor(int idx) { + return entryProcessors == null ? null : entryProcessors.get(idx); } /** @@ -497,8 +512,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp * @param idx Key index. * @return Transform closure. */ - @Nullable public IgniteClosure nearTransformClosure(int idx) { - return nearTransformClos == null ? null : nearTransformClos.get(idx); + @Nullable public EntryProcessor nearEntryProcessor(int idx) { + return nearEntryProcessors == null ? null : nearEntryProcessors.get(idx); } /** @@ -615,6 +630,13 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp return -1L; } + /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + /** {@inheritDoc} * @param ctx*/ @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException { @@ -623,14 +645,17 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp keyBytes = marshalCollection(keys, ctx); valBytes = marshalValuesCollection(vals, ctx); - if (forceTransformBackups) - transformClosBytes = marshalCollection(transformClos, ctx); + if (forceTransformBackups) { + invokeArgsBytes = marshalInvokeArguments(invokeArgs, ctx); + + entryProcessorsBytes = marshalCollection(entryProcessors, ctx); + } nearKeyBytes = marshalCollection(nearKeys, ctx); nearValBytes = marshalValuesCollection(nearVals, ctx); if (forceTransformBackups) - nearTransformClosBytes = marshalCollection(nearTransformClos, ctx); + nearEntryProcessorsBytes = marshalCollection(nearEntryProcessors, ctx); } /** {@inheritDoc} */ @@ -640,14 +665,17 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp keys = unmarshalCollection(keyBytes, ctx, ldr); vals = unmarshalValueBytesCollection(valBytes, ctx, ldr); - if (forceTransformBackups) - transformClos = unmarshalCollection(transformClosBytes, ctx, ldr); + if (forceTransformBackups) { + entryProcessors = unmarshalCollection(entryProcessorsBytes, ctx, ldr); + + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); + } nearKeys = unmarshalCollection(nearKeyBytes, ctx, ldr); nearVals = unmarshalValueBytesCollection(nearValBytes, ctx, ldr); if (forceTransformBackups) - nearTransformClos = unmarshalCollection(nearTransformClosBytes, ctx, ldr); + nearEntryProcessors = unmarshalCollection(nearEntryProcessorsBytes, ctx, ldr); } /** {@inheritDoc} */ @@ -677,18 +705,20 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp _clone.drVers = drVers; _clone.ttls = ttls; _clone.drExpireTimes = drExpireTimes; + _clone.nearTtls = nearTtls; + _clone.nearExpireTimes = nearExpireTimes; _clone.syncMode = syncMode; _clone.nearKeys = nearKeys; _clone.nearKeyBytes = nearKeyBytes; _clone.nearVals = nearVals; _clone.nearValBytes = nearValBytes; _clone.forceTransformBackups = forceTransformBackups; - _clone.transformClos = transformClos; - _clone.transformClosBytes = transformClosBytes; - _clone.nearTransformClos = nearTransformClos; - _clone.nearTransformClosBytes = nearTransformClosBytes; - _clone.nearExpireTimes = nearExpireTimes; - _clone.nearTtls = nearTtls; + _clone.entryProcessors = entryProcessors; + _clone.entryProcessorsBytes = entryProcessorsBytes; + _clone.nearEntryProcessors = nearEntryProcessors; + _clone.nearEntryProcessorsBytes = nearEntryProcessorsBytes; + _clone.invokeArgs = invokeArgs; + _clone.invokeArgsBytes = invokeArgsBytes; _clone.subjId = subjId; _clone.taskNameHash = taskNameHash; } @@ -716,12 +746,6 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; case 4: - if (!commState.putLongList(ttls)) - return false; - - commState.idx++; - - case 5: if (drVers != null) { if (commState.it == null) { if (!commState.putInt(drVers.size())) @@ -748,12 +772,39 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 6: + case 5: if (!commState.putCacheVersion(futVer)) return false; commState.idx++; + case 6: + if (invokeArgsBytes != null) { + if (commState.it == null) { + if (!commState.putInt(invokeArgsBytes.length)) + return false; + + commState.it = arrayIterator(invokeArgsBytes); + } + + while (commState.it.hasNext() || commState.cur != NULL) { + if (commState.cur == NULL) + commState.cur = commState.it.next(); + + if (!commState.putByteArray((byte[])commState.cur)) + return false; + + commState.cur = NULL; + } + + commState.it = null; + } else { + if (!commState.putInt(-1)) + return false; + } + + commState.idx++; + case 7: if (keyBytes != null) { if (commState.it == null) { @@ -782,24 +833,42 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; case 8: - if (!commState.putUuid(nodeId)) + if (!commState.putLongList(nearExpireTimes)) return false; commState.idx++; case 9: - if (!commState.putEnum(syncMode)) + if (!commState.putLongList(nearTtls)) return false; commState.idx++; case 10: - if (!commState.putLong(topVer)) + if (!commState.putUuid(nodeId)) return false; commState.idx++; case 11: + if (!commState.putEnum(syncMode)) + return false; + + commState.idx++; + + case 12: + if (!commState.putLong(topVer)) + return false; + + commState.idx++; + + case 13: + if (!commState.putLongList(ttls)) + return false; + + commState.idx++; + + case 14: if (valBytes != null) { if (commState.it == null) { if (!commState.putInt(valBytes.size())) @@ -826,13 +895,13 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 12: + case 15: if (!commState.putCacheVersion(writeVer)) return false; commState.idx++; - case 13: + case 16: if (nearKeyBytes != null) { if (commState.it == null) { if (!commState.putInt(nearKeyBytes.size())) @@ -859,7 +928,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 14: + case 17: if (nearValBytes != null) { if (commState.it == null) { if (!commState.putInt(nearValBytes.size())) @@ -886,19 +955,13 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 15: - if (!commState.putBoolean(forceTransformBackups)) - return false; - - commState.idx++; - - case 16: - if (nearTransformClosBytes != null) { + case 18: + if (entryProcessorsBytes != null) { if (commState.it == null) { - if (!commState.putInt(nearTransformClosBytes.size())) + if (!commState.putInt(entryProcessorsBytes.size())) return false; - commState.it = nearTransformClosBytes.iterator(); + commState.it = entryProcessorsBytes.iterator(); } while (commState.it.hasNext() || commState.cur != NULL) { @@ -919,13 +982,19 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 17: - if (transformClosBytes != null) { + case 19: + if (!commState.putBoolean(forceTransformBackups)) + return false; + + commState.idx++; + + case 20: + if (nearEntryProcessorsBytes != null) { if (commState.it == null) { - if (!commState.putInt(transformClosBytes.size())) + if (!commState.putInt(nearEntryProcessorsBytes.size())) return false; - commState.it = transformClosBytes.iterator(); + commState.it = nearEntryProcessorsBytes.iterator(); } while (commState.it.hasNext() || commState.cur != NULL) { @@ -946,29 +1015,18 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 18: + case 21: if (!commState.putUuid(subjId)) return false; commState.idx++; - case 19: + case 22: if (!commState.putInt(taskNameHash)) return false; commState.idx++; - case 20: - if (!commState.putLongList(nearExpireTimes)) - return false; - - commState.idx++; - - case 21: - if (!commState.putLongList(nearTtls)) - return false; - - commState.idx++; } return true; @@ -994,16 +1052,6 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; case 4: - GridLongList drTtls0 = commState.getLongList(); - - if (drTtls0 == LONG_LIST_NOT_READ) - return false; - - ttls = drTtls0; - - commState.idx++; - - case 5: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1032,7 +1080,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 6: + case 5: GridCacheVersion futVer0 = commState.getCacheVersion(); if (futVer0 == CACHE_VER_NOT_READ) @@ -1042,6 +1090,35 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; + case 6: + if (commState.readSize == -1) { + if (buf.remaining() < 4) + return false; + + commState.readSize = commState.getInt(); + } + + if (commState.readSize >= 0) { + if (invokeArgsBytes == null) + invokeArgsBytes = new byte[commState.readSize][]; + + for (int i = commState.readItems; i < commState.readSize; i++) { + byte[] _val = commState.getByteArray(); + + if (_val == BYTE_ARR_NOT_READ) + return false; + + invokeArgsBytes[i] = (byte[])_val; + + commState.readItems++; + } + } + + commState.readSize = -1; + commState.readItems = 0; + + commState.idx++; + case 7: if (commState.readSize == -1) { if (buf.remaining() < 4) @@ -1072,6 +1149,26 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; case 8: + GridLongList nearExpireTimes0 = commState.getLongList(); + + if (nearExpireTimes0 == LONG_LIST_NOT_READ) + return false; + + nearExpireTimes = nearExpireTimes0; + + commState.idx++; + + case 9: + GridLongList nearTtls0 = commState.getLongList(); + + if (nearTtls0 == LONG_LIST_NOT_READ) + return false; + + nearTtls = nearTtls0; + + commState.idx++; + + case 10: UUID nodeId0 = commState.getUuid(); if (nodeId0 == UUID_NOT_READ) @@ -1081,7 +1178,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 9: + case 11: if (buf.remaining() < 1) return false; @@ -1091,7 +1188,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 10: + case 12: if (buf.remaining() < 8) return false; @@ -1099,7 +1196,17 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 11: + case 13: + GridLongList ttls0 = commState.getLongList(); + + if (ttls0 == LONG_LIST_NOT_READ) + return false; + + ttls = ttls0; + + commState.idx++; + + case 14: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1128,7 +1235,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 12: + case 15: GridCacheVersion writeVer0 = commState.getCacheVersion(); if (writeVer0 == CACHE_VER_NOT_READ) @@ -1138,7 +1245,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 13: + case 16: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1167,7 +1274,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 14: + case 17: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1196,15 +1303,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 15: - if (buf.remaining() < 1) - return false; - - forceTransformBackups = commState.getBoolean(); - - commState.idx++; - - case 16: + case 18: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1213,8 +1312,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp } if (commState.readSize >= 0) { - if (nearTransformClosBytes == null) - nearTransformClosBytes = new ArrayList<>(commState.readSize); + if (entryProcessorsBytes == null) + entryProcessorsBytes = new ArrayList<>(commState.readSize); for (int i = commState.readItems; i < commState.readSize; i++) { byte[] _val = commState.getByteArray(); @@ -1222,7 +1321,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp if (_val == BYTE_ARR_NOT_READ) return false; - nearTransformClosBytes.add((byte[])_val); + entryProcessorsBytes.add((byte[])_val); commState.readItems++; } @@ -1233,7 +1332,15 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 17: + case 19: + if (buf.remaining() < 1) + return false; + + forceTransformBackups = commState.getBoolean(); + + commState.idx++; + + case 20: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -1242,8 +1349,8 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp } if (commState.readSize >= 0) { - if (transformClosBytes == null) - transformClosBytes = new ArrayList<>(commState.readSize); + if (nearEntryProcessorsBytes == null) + nearEntryProcessorsBytes = new ArrayList<>(commState.readSize); for (int i = commState.readItems; i < commState.readSize; i++) { byte[] _val = commState.getByteArray(); @@ -1251,7 +1358,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp if (_val == BYTE_ARR_NOT_READ) return false; - transformClosBytes.add((byte[])_val); + nearEntryProcessorsBytes.add((byte[])_val); commState.readItems++; } @@ -1262,7 +1369,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 18: + case 21: UUID subjId0 = commState.getUuid(); if (subjId0 == UUID_NOT_READ) @@ -1272,7 +1379,7 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 19: + case 22: if (buf.remaining() < 4) return false; @@ -1280,25 +1387,6 @@ public class GridDhtAtomicUpdateRequest extends GridCacheMessage imp commState.idx++; - case 20: - GridLongList nearExpireTimes0 = commState.getLongList(); - - if (nearExpireTimes0 == LONG_LIST_NOT_READ) - return false; - - nearExpireTimes = nearExpireTimes0; - - commState.idx++; - - case 21: - GridLongList nearTtls0 = commState.getLongList(); - - if (nearTtls0 == LONG_LIST_NOT_READ) - return false; - - nearTtls = nearTtls0; - - commState.idx++; } return true; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java index 6b233e7..849a4fc 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateFuture.java @@ -70,6 +70,9 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection vals; + /** Optional arguments for entry processor. */ + private Object[] invokeArgs; + /** DR put values. */ @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private Collection> drPutVals; @@ -158,6 +161,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter * @param syncMode Write synchronization mode. * @param keys Keys to update. * @param vals Values or transform closure. + * @param invokeArgs Optional arguments for entry processor. * @param drPutVals DR put values (optional). * @param drRmvVals DR remove values (optional). * @param retval Return value require flag. @@ -175,6 +179,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter GridCacheOperation op, Collection keys, @Nullable Collection vals, + @Nullable Object[] invokeArgs, @Nullable Collection> drPutVals, @Nullable Collection drRmvVals, final boolean retval, @@ -186,6 +191,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter int taskNameHash ) { super(cctx.kernalContext()); + this.rawRetval = rawRetval; assert vals == null || vals.size() == keys.size(); @@ -200,6 +206,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter this.op = op; this.keys = keys; this.vals = vals; + this.invokeArgs = invokeArgs; this.drPutVals = drPutVals; this.drRmvVals = drRmvVals; this.retval = retval; @@ -317,6 +324,9 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter Object retval = res == null ? null : rawRetval ? ret : this.retval ? ret.value() : ret.success(); + if (op == TRANSFORM && retval == null) + retval = Collections.emptyMap(); + if (super.onDone(retval, err)) { cctx.mvcc().removeAtomicFuture(version()); @@ -366,7 +376,13 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter if (res.error() != null) addFailedKeys(req.keys(), res.error()); else { - if (req.fastMap() && req.hasPrimary()) + if (op == TRANSFORM) { + assert !req.fastMap(); + + if (res.returnValue() != null) + addInvokeResults(res.returnValue()); + } + else if (req.fastMap() && req.hasPrimary()) opRes = res.returnValue(); } @@ -464,7 +480,9 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter * @param remap Flag indicating if this is partial remap for this future. * @param oldNodeId Old node ID if was remap. */ - private void map0(GridDiscoveryTopologySnapshot topSnapshot, Collection keys, boolean remap, + private void map0(GridDiscoveryTopologySnapshot topSnapshot, + Collection keys, + boolean remap, @Nullable UUID oldNodeId) { assert oldNodeId == null || remap; @@ -560,6 +578,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter retval, op == TRANSFORM && cctx.hasFlag(FORCE_TRANSFORM_BACKUP), expiryPlc, + invokeArgs, filter, subjId, taskNameHash); @@ -666,6 +685,7 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter retval, op == TRANSFORM && cctx.hasFlag(FORCE_TRANSFORM_BACKUP), expiryPlc, + invokeArgs, filter, subjId, taskNameHash); @@ -820,6 +840,24 @@ public class GridNearAtomicUpdateFuture extends GridFutureAdapter } /** + * @param ret Result from single node. + */ + private synchronized void addInvokeResults(GridCacheReturn ret) { + assert op == TRANSFORM : op; + assert ret.value() == null || ret.value() instanceof Map : ret.value(); + + if (ret.value() != null) { + if (opRes != null) { + Map map = (Map)opRes.value(); + + map.putAll((Map)ret.value()); + } + else + opRes = ret; + } + } + + /** * @param failedKeys Failed keys. * @param err Error cause. * @return Root {@link GridCachePartialUpdateException}. diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java index 9a64025..a210711 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateRequest.java @@ -22,6 +22,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.nio.*; import java.util.*; @@ -77,6 +78,13 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im @GridDirectCollection(GridCacheValueBytes.class) private List valBytes; + /** Optional arguments for entry processor. */ + @GridDirectTransient + private Object[] invokeArgs; + + /** Entry processor arguments bytes. */ + private byte[][] invokeArgsBytes; + /** DR versions. */ @GridDirectCollection(GridCacheVersion.class) private List drVers; @@ -138,8 +146,12 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im * @param syncMode Synchronization mode. * @param op Cache update operation. * @param retval Return value required flag. + * @param forceTransformBackups Force transform backups flag. * @param expiryPlc Expiry policy. + * @param invokeArgs Optional arguments for entry processor. * @param filter Optional filter for atomic check. + * @param subjId Subject ID. + * @param taskNameHash Task name hash code. */ public GridNearAtomicUpdateRequest( int cacheId, @@ -152,7 +164,8 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im GridCacheOperation op, boolean retval, boolean forceTransformBackups, - ExpiryPolicy expiryPlc, + @Nullable ExpiryPolicy expiryPlc, + @Nullable Object[] invokeArgs, @Nullable IgnitePredicate>[] filter, @Nullable UUID subjId, int taskNameHash @@ -169,6 +182,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im this.retval = retval; this.forceTransformBackups = forceTransformBackups; this.expiryPlc = expiryPlc; + this.invokeArgs = invokeArgs; this.filter = filter; this.subjId = subjId; this.taskNameHash = taskNameHash; @@ -274,10 +288,14 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im * @param drVer DR version (optional). * @param primary If given key is primary on this mapping. */ - public void addUpdateEntry(K key, @Nullable Object val, long drTtl, long drExpireTime, - @Nullable GridCacheVersion drVer, boolean primary) { + public void addUpdateEntry(K key, + @Nullable Object val, + long drTtl, + long drExpireTime, + @Nullable GridCacheVersion drVer, + boolean primary) { assert val != null || op == DELETE; - assert op != TRANSFORM || val instanceof IgniteClosure; + assert op != TRANSFORM || val instanceof EntryProcessor; keys.add(key); vals.add(val); @@ -343,6 +361,13 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im } /** + * @return Optional arguments for entry processor. + */ + @Nullable public Object[] invokeArguments() { + return invokeArgs; + } + + /** * @param idx Key index. * @return Value. */ @@ -354,12 +379,12 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im /** * @param idx Key index. - * @return Transform closure. + * @return Entry processor. */ - public IgniteClosure transformClosure(int idx) { + public EntryProcessor entryProcessor(int idx) { assert op == TRANSFORM : op; - return (IgniteClosure)vals.get(idx); + return (EntryProcessor)vals.get(idx); } /** @@ -491,6 +516,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im keyBytes = marshalCollection(keys, ctx); valBytes = marshalValuesCollection(vals, ctx); filterBytes = marshalFilter(filter, ctx); + invokeArgsBytes = marshalInvokeArguments(invokeArgs, ctx); if (expiryPlc != null) expiryPlcBytes = CU.marshal(ctx, new IgniteExternalizableExpiryPolicy(expiryPlc)); @@ -503,6 +529,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im keys = unmarshalCollection(keyBytes, ctx, ldr); vals = unmarshalValueBytesCollection(valBytes, ctx, ldr); filter = unmarshalFilter(filterBytes, ctx, ldr); + invokeArgs = unmarshalInvokeArguments(invokeArgsBytes, ctx, ldr); if (expiryPlcBytes != null) expiryPlc = ctx.marshaller().unmarshal(expiryPlcBytes, ldr); @@ -535,11 +562,14 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im _clone.keyBytes = keyBytes; _clone.vals = vals; _clone.valBytes = valBytes; + _clone.invokeArgs = invokeArgs; + _clone.invokeArgsBytes = invokeArgsBytes; _clone.drVers = drVers; _clone.drTtls = drTtls; _clone.drExpireTimes = drExpireTimes; _clone.retval = retval; _clone.expiryPlc = expiryPlc; + _clone.expiryPlcBytes = expiryPlcBytes; _clone.filter = filter; _clone.filterBytes = filterBytes; _clone.hasPrimary = hasPrimary; @@ -604,12 +634,18 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; case 6: - if (!commState.putBoolean(fastMap)) + if (!commState.putByteArray(expiryPlcBytes)) return false; commState.idx++; case 7: + if (!commState.putBoolean(fastMap)) + return false; + + commState.idx++; + + case 8: if (filterBytes != null) { if (commState.it == null) { if (!commState.putInt(filterBytes.length)) @@ -636,19 +672,46 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 8: + case 9: if (!commState.putCacheVersion(futVer)) return false; commState.idx++; - case 9: + case 10: if (!commState.putBoolean(hasPrimary)) return false; commState.idx++; - case 10: + case 11: + if (invokeArgsBytes != null) { + if (commState.it == null) { + if (!commState.putInt(invokeArgsBytes.length)) + return false; + + commState.it = arrayIterator(invokeArgsBytes); + } + + while (commState.it.hasNext() || commState.cur != NULL) { + if (commState.cur == NULL) + commState.cur = commState.it.next(); + + if (!commState.putByteArray((byte[])commState.cur)) + return false; + + commState.cur = NULL; + } + + commState.it = null; + } else { + if (!commState.putInt(-1)) + return false; + } + + commState.idx++; + + case 12: if (keyBytes != null) { if (commState.it == null) { if (!commState.putInt(keyBytes.size())) @@ -675,43 +738,37 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 11: + case 13: if (!commState.putEnum(op)) return false; commState.idx++; - case 12: + case 14: if (!commState.putBoolean(retval)) return false; commState.idx++; - case 13: + case 15: if (!commState.putEnum(syncMode)) return false; commState.idx++; - case 14: + case 16: if (!commState.putLong(topVer)) return false; commState.idx++; - case 15: - if (!commState.putByteArray(expiryPlcBytes)) - return false; - - commState.idx++; - - case 16: + case 17: if (!commState.putCacheVersion(updateVer)) return false; commState.idx++; - case 17: + case 18: if (valBytes != null) { if (commState.it == null) { if (!commState.putInt(valBytes.size())) @@ -738,19 +795,19 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 18: + case 19: if (!commState.putBoolean(forceTransformBackups)) return false; commState.idx++; - case 19: + case 20: if (!commState.putUuid(subjId)) return false; commState.idx++; - case 20: + case 21: if (!commState.putInt(taskNameHash)) return false; @@ -820,6 +877,16 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; case 6: + byte[] expiryPlcBytes0 = commState.getByteArray(); + + if (expiryPlcBytes0 == BYTE_ARR_NOT_READ) + return false; + + expiryPlcBytes = expiryPlcBytes0; + + commState.idx++; + + case 7: if (buf.remaining() < 1) return false; @@ -827,7 +894,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 7: + case 8: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -856,7 +923,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 8: + case 9: GridCacheVersion futVer0 = commState.getCacheVersion(); if (futVer0 == CACHE_VER_NOT_READ) @@ -866,7 +933,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 9: + case 10: if (buf.remaining() < 1) return false; @@ -874,7 +941,36 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 10: + case 11: + if (commState.readSize == -1) { + if (buf.remaining() < 4) + return false; + + commState.readSize = commState.getInt(); + } + + if (commState.readSize >= 0) { + if (invokeArgsBytes == null) + invokeArgsBytes = new byte[commState.readSize][]; + + for (int i = commState.readItems; i < commState.readSize; i++) { + byte[] _val = commState.getByteArray(); + + if (_val == BYTE_ARR_NOT_READ) + return false; + + invokeArgsBytes[i] = (byte[])_val; + + commState.readItems++; + } + } + + commState.readSize = -1; + commState.readItems = 0; + + commState.idx++; + + case 12: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -903,7 +999,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 11: + case 13: if (buf.remaining() < 1) return false; @@ -913,7 +1009,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 12: + case 14: if (buf.remaining() < 1) return false; @@ -921,7 +1017,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 13: + case 15: if (buf.remaining() < 1) return false; @@ -931,7 +1027,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 14: + case 16: if (buf.remaining() < 8) return false; @@ -939,17 +1035,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 15: - byte[] expiryPlcBytes0 = commState.getByteArray(); - - if (expiryPlcBytes0 == BYTE_ARR_NOT_READ) - return false; - - expiryPlcBytes = expiryPlcBytes0; - - commState.idx++; - - case 16: + case 17: GridCacheVersion updateVer0 = commState.getCacheVersion(); if (updateVer0 == CACHE_VER_NOT_READ) @@ -959,7 +1045,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 17: + case 18: if (commState.readSize == -1) { if (buf.remaining() < 4) return false; @@ -988,7 +1074,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 18: + case 19: if (buf.remaining() < 1) return false; @@ -996,7 +1082,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 19: + case 20: UUID subjId0 = commState.getUuid(); if (subjId0 == UUID_NOT_READ) @@ -1006,7 +1092,7 @@ public class GridNearAtomicUpdateRequest extends GridCacheMessage im commState.idx++; - case 20: + case 21: if (buf.remaining() < 4) return false; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java index 8c8a8e5..e6a4eb7 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java @@ -164,15 +164,14 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentity * @return Participating nodes. */ @Override public Collection nodes() { - return - F.viewReadOnly(futures(), new IgniteClosure, ClusterNode>() { - @Nullable @Override public ClusterNode apply(IgniteFuture f) { - if (isMini(f)) - return ((MiniFuture)f).node(); + return F.viewReadOnly(futures(), new IgniteClosure, ClusterNode>() { + @Nullable @Override public ClusterNode apply(IgniteFuture f) { + if (isMini(f)) + return ((MiniFuture)f).node(); - return cctx.discovery().localNode(); - } - }); + return cctx.discovery().localNode(); + } + }); } /** {@inheritDoc} */ @@ -272,18 +271,38 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentity } else { // Check transaction entries (corresponding tx entries must be enlisted in transaction). - cand = new GridCacheMvccCandidate<>(entry, cctx.localNodeId(), - null, null, threadId, lockVer, timeout, true, tx.entry(entry.txKey()).locked(), inTx(), - inTx() && tx.implicitSingle(), false, false); + cand = new GridCacheMvccCandidate<>(entry, + cctx.localNodeId(), + null, + null, + threadId, + lockVer, + timeout, + true, + tx.entry(entry.txKey()).locked(), + inTx(), + inTx() && tx.implicitSingle(), + false, + false); cand.topologyVersion(topSnapshot.get().topologyVersion()); } } else { if (cand == null) { - cand = new GridCacheMvccCandidate<>(entry, cctx.localNodeId(), - null, null, threadId, lockVer, timeout, true, false, inTx(), - inTx() && tx.implicitSingle(), false, false); + cand = new GridCacheMvccCandidate<>(entry, + cctx.localNodeId(), + null, + null, + threadId, + lockVer, + timeout, + true, + false, + inTx(), + inTx() && tx.implicitSingle(), + false, + false); cand.topologyVersion(topSnapshot.get().topologyVersion()); } @@ -611,8 +630,7 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentity if (mapAsPrimary(keys, topVer)) return; - ConcurrentLinkedDeque8> mappings = - new ConcurrentLinkedDeque8<>(); + ConcurrentLinkedDeque8> mappings = new ConcurrentLinkedDeque8<>(); // Assign keys to primary nodes. GridNearLockMapping map = null; @@ -1270,10 +1288,20 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentity else cctx.mvcc().markExplicitOwner(k, threadId); - if (retval && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) - cctx.events().addEvent(cctx.affinity().partition(k), k, tx, null, - EVT_CACHE_OBJECT_READ, newVal, newVal != null || newBytes != null, - null, false, CU.subjectId(tx, cctx.shared()), null, tx == null ? null : tx.resolveTaskName()); + if (retval && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) { + cctx.events().addEvent(cctx.affinity().partition(k), + k, + tx, + null, + EVT_CACHE_OBJECT_READ, + newVal, + newVal != null || newBytes != null, + null, + false, + CU.subjectId(tx, cctx.shared()), + null, + tx == null ? null : tx.resolveTaskName()); + } i++; } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearAtomicCache.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearAtomicCache.java index d7e32b3..67c6fce 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearAtomicCache.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearAtomicCache.java @@ -25,6 +25,7 @@ import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; @@ -213,6 +214,7 @@ public class GridNearAtomicCache extends GridNearCacheAdapter { op, val, valBytes, + null, /*write-through*/false, /*retval*/false, /**expiry policy*/null, @@ -295,9 +297,9 @@ public class GridNearAtomicCache extends GridNearCacheAdapter { V val = req.nearValue(i); byte[] valBytes = req.nearValueBytes(i); - IgniteClosure transform = req.nearTransformClosure(i); + EntryProcessor entryProcessor = req.nearEntryProcessor(i); - GridCacheOperation op = transform != null ? TRANSFORM : + GridCacheOperation op = entryProcessor != null ? TRANSFORM : (val != null || valBytes != null) ? UPDATE : DELETE; @@ -313,8 +315,9 @@ public class GridNearAtomicCache extends GridNearCacheAdapter { nodeId, nodeId, op, - op == TRANSFORM ? transform : val, + op == TRANSFORM ? entryProcessor : val, valBytes, + op == TRANSFORM ? req.invokeArguments() : null, /*write-through*/false, /*retval*/false, null, @@ -523,32 +526,45 @@ public class GridNearAtomicCache extends GridNearCacheAdapter { } /** {@inheritDoc} */ - @Override public void transform(K key, IgniteClosure transformer) throws IgniteCheckedException { - dht.transform(key, transformer); + @Override public EntryProcessorResult invoke(K key, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { + return dht.invoke(key, entryProcessor, args); } /** {@inheritDoc} */ - @Override public R transformAndCompute(K key, IgniteClosure> transformer) - throws IgniteCheckedException { - return dht.transformAndCompute(key, transformer); + @Override public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { + return dht.invokeAll(keys, entryProcessor, args); } /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(K key, - IgniteClosure transformer, - @Nullable GridCacheEntryEx entry, - long ttl) { - return dht.transformAsync(key, transformer, entry, ttl); + @Override public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args) { + return dht.invokeAllAsync(map, args); + } + + /** {@inheritDoc} */ + @Override public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args) throws EntryProcessorException { + return dht.invokeAsync(key, entryProcessor, args); } /** {@inheritDoc} */ - @Override public void transformAll(@Nullable Map> m) throws IgniteCheckedException { - dht.transformAll(m); + @Override public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException { + return dht.invokeAllAsync(map, args).get(); } /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Map> m) { - return dht.transformAllAsync(m); + @Override public IgniteFuture>> invokeAllAsync(Set keys, + EntryProcessor entryProcessor, + Object... args) { + return dht.invokeAllAsync(keys, entryProcessor, args); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockResponse.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockResponse.java index 7a0c2fd..7711470 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockResponse.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockResponse.java @@ -57,6 +57,7 @@ public class GridNearLockResponse extends GridDistributedLockResponse extends GridCacheAdapter { return (V)updateAllInternal(UPDATE, Collections.singleton(key), Collections.singleton(val), + null, expiryPerCall(), true, false, @@ -127,6 +130,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (Boolean)updateAllInternal(UPDATE, Collections.singleton(key), Collections.singleton(val), + null, expiryPerCall(), false, false, @@ -145,6 +149,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (Boolean)updateAllInternal(UPDATE, Collections.singleton(key), Collections.singleton(val), + null, expiryPerCall(), false, false, @@ -163,7 +168,12 @@ public class GridLocalAtomicCache extends GridCacheAdapter { ctx.denyOnLocalRead(); - return updateAllAsync0(F0.asMap(key, val), null, true, false, ttl, filter); + return updateAllAsync0(F0.asMap(key, val), + null, + null, + true, + false, + filter); } /** {@inheritDoc} */ @@ -177,7 +187,12 @@ public class GridLocalAtomicCache extends GridCacheAdapter { ctx.denyOnLocalRead(); - return updateAllAsync0(F0.asMap(key, val), null, false, false, ttl, filter); + return updateAllAsync0(F0.asMap(key, val), + null, + null, + false, + false, + filter); } /** {@inheritDoc} */ @@ -242,6 +257,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (GridCacheReturn)updateAllInternal(UPDATE, Collections.singleton(key), Collections.singleton(newVal), + null, expiryPerCall(), true, true, @@ -259,6 +275,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (GridCacheReturn)updateAllInternal(DELETE, Collections.singleton(key), null, + null, expiryPerCall(), true, true, @@ -283,7 +300,11 @@ public class GridLocalAtomicCache extends GridCacheAdapter { ctx.denyOnLocalRead(); - return updateAllAsync0(F.asMap(key, newVal), null, true, true, 0, + return updateAllAsync0(F.asMap(key, newVal), + null, + null, + true, + true, ctx.equalsPeekArray(oldVal)); } @@ -295,6 +316,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { updateAllInternal(UPDATE, m.keySet(), m.values(), + null, expiryPerCall(), false, false, @@ -307,73 +329,12 @@ public class GridLocalAtomicCache extends GridCacheAdapter { @Nullable IgnitePredicate>[] filter) { ctx.denyOnLocalRead(); - return updateAllAsync0(m, null, false, false, 0, filter); - } - - /** {@inheritDoc} */ - @Override public void transform(K key, IgniteClosure transformer) throws IgniteCheckedException { - ctx.denyOnLocalRead(); - - updateAllInternal(TRANSFORM, - Collections.singleton(key), - Collections.singleton(transformer), - expiryPerCall(), - false, - false, + return updateAllAsync0(m, null, - ctx.isStoreEnabled()); - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override public R transformAndCompute(K key, IgniteClosure> transformer) - throws IgniteCheckedException { - return (R)updateAllInternal(TRANSFORM, - Collections.singleton(key), - Collections.singleton(new GridCacheTransformComputeClosure<>(transformer)), - expiryPerCall(), - true, - false, null, - ctx.isStoreEnabled()); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(K key, - IgniteClosure transformer, - @Nullable GridCacheEntryEx entry, - long ttl) { - ctx.denyOnLocalRead(); - - return updateAllAsync0(null, Collections.singletonMap(key, transformer), false, false, ttl, null); - } - - /** {@inheritDoc} */ - @SuppressWarnings("ConstantConditions") - @Override public void transformAll(@Nullable Map> m) throws IgniteCheckedException { - ctx.denyOnLocalRead(); - - if (F.isEmpty(m)) - return; - - updateAllInternal(TRANSFORM, - m.keySet(), - m.values(), - expiryPerCall(), false, false, - null, - ctx.isStoreEnabled()); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAllAsync(@Nullable Map> m) { - ctx.denyOnLocalRead(); - - if (F.isEmpty(m)) - return new GridFinishedFuture(ctx.kernalContext()); - - return updateAllAsync0(null, m, false, false, 0, null); + filter); } /** {@inheritDoc} */ @@ -386,6 +347,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (V)updateAllInternal(DELETE, Collections.singleton(key), null, + null, expiryPerCall(), true, false, @@ -412,6 +374,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { updateAllInternal(DELETE, keys, null, + null, expiryPerCall(), false, false, @@ -439,6 +402,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (Boolean)updateAllInternal(DELETE, Collections.singleton(key), null, + null, expiryPerCall(), false, false, @@ -467,6 +431,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return (Boolean)updateAllInternal(DELETE, Collections.singleton(key), null, + null, expiryPerCall(), false, false, @@ -669,31 +634,137 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return getAllAsync(keys, null, false, subjId, taskName, deserializePortable, false, expiry, filter).get(); } + /** {@inheritDoc} */ + @Override public EntryProcessorResult invoke(K key, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { + return invokeAsync(key, entryProcessor, args).get(); + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll(Set keys, + EntryProcessor entryProcessor, + Object... args) throws IgniteCheckedException { + return invokeAllAsync(keys, entryProcessor, args).get(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public IgniteFuture> invokeAsync(K key, + EntryProcessor entryProcessor, + Object... args) throws EntryProcessorException { + A.notNull(key, "key", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKey(key); + + ctx.denyOnLocalRead(); + + Map invokeMap = + Collections.singletonMap(key, (EntryProcessor)entryProcessor); + + IgniteFuture>> fut = updateAllAsync0(null, + invokeMap, + args, + true, + false, + null); + + return fut.chain(new CX1>>, EntryProcessorResult>() { + @Override public EntryProcessorResult applyx(IgniteFuture>> fut) + throws IgniteCheckedException { + Map> resMap = fut.get(); + + if (resMap != null) { + assert resMap.isEmpty() || resMap.size() == 1 : resMap.size(); + + return resMap.isEmpty() ? null : resMap.values().iterator().next(); + } + + return null; + } + }); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public IgniteFuture>> invokeAllAsync( + Set keys, + final EntryProcessor entryProcessor, + Object... args) { + A.notNull(keys, "keys", entryProcessor, "entryProcessor"); + + if (keyCheck) + validateCacheKeys(keys); + + ctx.denyOnLocalRead(); + + Map invokeMap = F.viewAsMap(keys, new C1() { + @Override public EntryProcessor apply(K k) { + return entryProcessor; + } + }); + + return updateAllAsync0(null, + invokeMap, + args, + true, + false, + null); + } + + /** {@inheritDoc} */ + @Override public Map> invokeAll( + Map> map, + Object... args) throws IgniteCheckedException { + return invokeAllAsync(map, args).get(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("unchecked") + @Override public IgniteFuture>> invokeAllAsync( + Map> map, + Object... args) { + A.notNull(map, "map"); + + if (keyCheck) + validateCacheKeys(map.keySet()); + + ctx.denyOnLocalRead(); + + return updateAllAsync0(null, + map, + args, + true, + false, + null); + } + /** * Entry point for public API update methods. * - * @param map Put map. Either {@code map} or {@code transformMap} should be passed. - * @param transformMap Transform map. Either {@code map} or {@code transformMap} should be passed. + * @param map Put map. Either {@code map} or {@code invokeMap} should be passed. + * @param invokeMap Transform map. Either {@code map} or {@code invokeMap} should be passed. + * @param invokeArgs Optional arguments for EntryProcessor. * @param retval Return value required flag. * @param rawRetval Return {@code GridCacheReturn} instance. - * @param ttl Entry time-to-live. * @param filter Cache entry filter for atomic updates. * @return Completion future. */ private IgniteFuture updateAllAsync0( @Nullable final Map map, - @Nullable final Map> transformMap, + @Nullable final Map invokeMap, + @Nullable final Object[] invokeArgs, final boolean retval, final boolean rawRetval, - final long ttl, @Nullable final IgnitePredicate>[] filter ) { - final GridCacheOperation op = transformMap != null ? TRANSFORM : UPDATE; + final GridCacheOperation op = invokeMap != null ? TRANSFORM : UPDATE; final Collection keys = - map != null ? map.keySet() : transformMap != null ? transformMap.keySet() : null; + map != null ? map.keySet() : invokeMap != null ? invokeMap.keySet() : null; - final Collection vals = map != null ? map.values() : transformMap != null ? transformMap.values() : null; + final Collection vals = map != null ? map.values() : invokeMap != null ? invokeMap.values() : null; final boolean storeEnabled = ctx.isStoreEnabled(); @@ -704,6 +775,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return updateAllInternal(op, keys, vals, + invokeArgs, expiry, retval, rawRetval, @@ -737,6 +809,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { return updateAllInternal(DELETE, keys, null, + null, expiryPlc, retval, rawRetval, @@ -747,11 +820,12 @@ public class GridLocalAtomicCache extends GridCacheAdapter { } /** - * Entry point for all public update methods (put, remove, transform). + * Entry point for all public update methods (put, remove, invoke). * * @param op Operation. * @param keys Keys. * @param vals Values. + * @param invokeArgs Optional arguments for EntryProcessor. * @param expiryPlc Expiry policy. * @param retval Return value required flag. * @param rawRetval Return {@code GridCacheReturn} instance. @@ -764,6 +838,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { private Object updateAllInternal(GridCacheOperation op, Collection keys, @Nullable Iterable vals, + @Nullable Object[] invokeArgs, @Nullable ExpiryPolicy expiryPlc, boolean retval, boolean rawRetval, @@ -784,9 +859,15 @@ public class GridLocalAtomicCache extends GridCacheAdapter { UUID subjId = ctx.subjectIdPerCall(null); if (storeEnabled && keys.size() > 1) { - updateWithBatch(op, keys, vals, expiryPlc, ver, filter, subjId, taskName); - - return null; + return updateWithBatch(op, + keys, + vals, + invokeArgs, + expiryPlc, + ver, + filter, + subjId, + taskName); } Iterator valsIter = vals != null ? vals.iterator() : null; @@ -809,10 +890,11 @@ public class GridLocalAtomicCache extends GridCacheAdapter { try { entry = entryEx(key); - IgniteBiTuple t = entry.innerUpdateLocal( + GridTuple3> t = entry.innerUpdateLocal( ver, val == null ? DELETE : op, val, + invokeArgs, storeEnabled, retval, expiryPlc, @@ -823,16 +905,23 @@ public class GridLocalAtomicCache extends GridCacheAdapter { subjId, taskName); - if (res == null) { - if (op == TRANSFORM && val instanceof GridCacheTransformComputeClosure) { - assert retval; + if (op == TRANSFORM) { + if (t.get3() != null) { + Map computedMap; + + if (res == null) { + computedMap = U.newHashMap(keys.size()); - res = new IgniteBiTuple<>(t.get1(), - ((GridCacheTransformComputeClosure)val).returnValue()); + res = new IgniteBiTuple<>(true, computedMap); + } + else + computedMap = (Map)res.get2(); + + computedMap.put(key, t.get3()); } - else - res = t; } + else if (res == null) + res = new T2(t.get1(), t.get2()); break; // While. } @@ -862,8 +951,13 @@ public class GridLocalAtomicCache extends GridCacheAdapter { if (err != null) throw err; - return res == null ? null : rawRetval ? + Object ret = res == null ? null : rawRetval ? new GridCacheReturn<>(res.get2(), res.get1()) : retval ? res.get2() : res.get1(); + + if (op == TRANSFORM && ret == null) + ret = Collections.emptyMap(); + + return ret; } /** @@ -872,18 +966,21 @@ public class GridLocalAtomicCache extends GridCacheAdapter { * @param op Operation. * @param keys Keys. * @param vals Values. + * @param invokeArgs Optional arguments for EntryProcessor. * @param expiryPlc Expiry policy. * @param ver Cache version. * @param filter Optional filter. * @param subjId Subject ID. * @param taskName Task name. * @throws GridCachePartialUpdateException If update failed. + * @return Results map for invoke operation. */ @SuppressWarnings({"ForLoopReplaceableByForEach", "unchecked"}) - private void updateWithBatch( + private Map updateWithBatch( GridCacheOperation op, Collection keys, @Nullable Iterable vals, + @Nullable Object[] invokeArgs, @Nullable ExpiryPolicy expiryPlc, GridCacheVersion ver, @Nullable IgnitePredicate>[] filter, @@ -896,7 +993,12 @@ public class GridLocalAtomicCache extends GridCacheAdapter { int size = locked.size(); Map putMap = null; + Collection rmvKeys = null; + + Map invokeResMap = + op == TRANSFORM ? U.newHashMap(size) : null; + List> filtered = new ArrayList<>(size); GridCachePartialUpdateException err = null; @@ -933,7 +1035,7 @@ public class GridLocalAtomicCache extends GridCacheAdapter { } if (op == TRANSFORM) { - IgniteClosure transform = (IgniteClosure)val; + EntryProcessor entryProcessor = (EntryProcessor)val; V old = entry.innerGet(null, /*swap*/true, @@ -944,12 +1046,32 @@ public class GridLocalAtomicCache extends GridCacheAdapter { /**event*/true, /**temporary*/true, subjId, - transform, + entryProcessor, taskName, CU.empty(), null); - V updated = transform.apply(old); + CacheInvokeEntry invokeEntry = new CacheInvokeEntry<>(entry.key(), old); + + V updated; + CacheInvokeResult invokeRes = null; + + try { + Object computed = entryProcessor.process(invokeEntry, invokeArgs); + + updated = ctx.unwrapTemporary(invokeEntry.getValue()); + + if (computed != null) + invokeRes = new CacheInvokeResult<>(ctx.unwrapTemporary(computed)); + } + catch (Exception e) { + invokeRes = new CacheInvokeResult<>(e); + + updated = old; + } + + if (invokeRes != null) + invokeResMap.put(entry.key(), invokeRes); if (updated == null) { if (intercept) { @@ -1107,6 +1229,8 @@ public class GridLocalAtomicCache extends GridCacheAdapter { if (err != null) throw err; + + return invokeResMap; } finally { unlockEntries(locked); @@ -1179,10 +1303,11 @@ public class GridLocalAtomicCache extends GridCacheAdapter { assert writeVal != null || op == DELETE : "null write value found."; - IgniteBiTuple t = entry.innerUpdateLocal( + GridTuple3> t = entry.innerUpdateLocal( ver, op, writeVal, + null, false, false, expiryPlc, diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/GridCacheQueryManager.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/GridCacheQueryManager.java index 25c0668..588cac1 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/GridCacheQueryManager.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/GridCacheQueryManager.java @@ -2693,16 +2693,6 @@ public abstract class GridCacheQueryManager extends GridCacheManagerAdapte } /** {@inheritDoc} */ - @Override public void transform(IgniteClosure transformer) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - throw new UnsupportedOperationException(); - } - - /** {@inheritDoc} */ @Nullable @Override public V replace(V val) { throw new UnsupportedOperationException(); } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/continuous/GridCacheContinuousQueryEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/continuous/GridCacheContinuousQueryEntry.java index 75453ee..991573b 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/continuous/GridCacheContinuousQueryEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/query/continuous/GridCacheContinuousQueryEntry.java @@ -396,18 +396,6 @@ public class GridCacheContinuousQueryEntry implements GridCacheEntry } /** {@inheritDoc} */ - @Override public void transform(IgniteClosure transformer) throws IgniteCheckedException { - ctx.denyOnFlag(READ); - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - ctx.denyOnFlag(READ); - - return new GridFinishedFuture<>(ctx.kernalContext(), false); - } - - /** {@inheritDoc} */ @Nullable @Override public V replace(V val) throws IgniteCheckedException { assert impl != null; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxAdapter.java index 29e33b8..bfd9359 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxAdapter.java @@ -1169,7 +1169,8 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter * @throws IgniteCheckedException If failed to get previous value for transform. * @throws GridCacheEntryRemovedException If entry was concurrently deleted. */ - protected GridTuple3 applyTransformClosures(IgniteTxEntry txEntry, + protected GridTuple3 applyTransformClosures( + IgniteTxEntry txEntry, boolean metrics) throws GridCacheEntryRemovedException, IgniteCheckedException { GridCacheContext cacheCtx = txEntry.context(); @@ -1177,7 +1178,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter if (isSystemInvalidate()) return F.t(cacheCtx.isStoreEnabled() ? RELOAD : DELETE, null, null); - if (F.isEmpty(txEntry.transformClosures())) + if (F.isEmpty(txEntry.entryProcessors())) return F.t(txEntry.op(), txEntry.value(), txEntry.valueBytes()); else { try { @@ -1193,19 +1194,12 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter /*event*/recordEvt, /*temporary*/true, /*subjId*/subjId, - /**closure name */recordEvt ? F.first(txEntry.transformClosures()) : null, + /**closure name */recordEvt ? F.first(txEntry.entryProcessors()).get1() : null, resolveTaskName(), CU.empty(), null); - try { - for (IgniteClosure clos : txEntry.transformClosures()) - val = clos.apply(val); - } - catch (Throwable e) { - throw new IgniteException("Transform closure must not throw any exceptions " + - "(transaction will be invalidated)", e); - } + val = txEntry.applyEntryProcessors(val); GridCacheOperation op = val == null ? DELETE : UPDATE; diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxEntry.java index 17b153d..73d17b5 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxEntry.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxEntry.java @@ -22,6 +22,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.atomic.*; @@ -71,7 +72,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, /** Transform. */ @GridToStringInclude - private Collection> transformClosCol; + private Collection, Object[]>> entryProcessorsCol; /** Transform closure bytes. */ @GridToStringExclude @@ -192,7 +193,8 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, * @param tx Owning transaction. * @param op Operation. * @param val Value. - * @param transformClos Transform closure. + * @param entryProcessor Entry processor. + * @param invokeArgs Optional arguments for EntryProcessor. * @param ttl Time to live. * @param entry Cache entry. * @param filters Put filters. @@ -202,9 +204,10 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, IgniteTxEx tx, GridCacheOperation op, V val, - IgniteClosure transformClos, + EntryProcessor entryProcessor, + Object[] invokeArgs, long ttl, - GridCacheEntryEx entry, + GridCacheEntryEx entry, IgnitePredicate>[] filters, GridCacheVersion drVer) { assert ctx != null; @@ -220,8 +223,8 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, this.filters = filters; this.drVer = drVer; - if (transformClos != null) - addTransformClosure(transformClos); + if (entryProcessor != null) + addEntryProcessor(entryProcessor, invokeArgs); key = entry.key(); keyBytes = entry.keyBytes(); @@ -299,7 +302,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, cp.filters = filters; cp.val.value(val.op(), val.value(), val.hasWriteValue(), val.hasReadValue()); cp.val.valueBytes(val.valueBytes()); - cp.transformClosCol = transformClosCol; + cp.entryProcessorsCol = entryProcessorsCol; cp.ttl = ttl; cp.drExpireTime = drExpireTime; cp.explicitVer = explicitVer; @@ -605,13 +608,14 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, } /** - * @param transformClos Transform closure. + * @param entryProcessor Entry processor. + * @param invokeArgs Optional arguments for EntryProcessor. */ - public void addTransformClosure(IgniteClosure transformClos) { - if (transformClosCol == null) - transformClosCol = new LinkedList<>(); + public void addEntryProcessor(EntryProcessor entryProcessor, Object[] invokeArgs) { + if (entryProcessorsCol == null) + entryProcessorsCol = new LinkedList<>(); - transformClosCol.add(transformClos); + entryProcessorsCol.add(new T2, Object[]>(entryProcessor, invokeArgs)); // Must clear transform closure bytes since collection has changed. transformClosBytes = null; @@ -620,17 +624,41 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, } /** - * @return Collection of transform closures. + * @return Collection of entry processors. */ - public Collection> transformClosures() { - return transformClosCol; + public Collection, Object[]>> entryProcessors() { + return entryProcessorsCol; + } + + /** + * @param val Value. + * @return New value. + */ + @SuppressWarnings("unchecked") + public V applyEntryProcessors(V val) { + for (T2, Object[]> t : entryProcessors()) { + try { + CacheInvokeEntry invokeEntry = new CacheInvokeEntry<>(key, val); + + EntryProcessor processor = t.get1(); + + processor.process(invokeEntry, t.get2()); + + val = invokeEntry.getValue(); + } + catch (Exception ignore) { + // No-op. + } + } + + return val; } /** - * @param transformClosCol Collection of transform closures. + * @param entryProcessorsCol Collection of entry processors. */ - public void transformClosures(@Nullable Collection> transformClosCol) { - this.transformClosCol = transformClosCol; + public void entryProcessors(@Nullable Collection, Object[]>> entryProcessorsCol) { + this.entryProcessorsCol = entryProcessorsCol; // Must clear transform closure bytes since collection has changed. transformClosBytes = null; @@ -740,8 +768,8 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, if (keyBytes == null) keyBytes = entry.getOrMarshalKeyBytes(); - if (transformClosBytes == null && transformClosCol != null) - transformClosBytes = CU.marshal(ctx, transformClosCol); + if (transformClosBytes == null && entryProcessorsCol != null) + transformClosBytes = CU.marshal(ctx, entryProcessorsCol); if (F.isEmptyOrNulls(filters)) filterBytes = null; @@ -781,8 +809,8 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, key = ctx.marshaller().unmarshal(keyBytes, clsLdr); // Unmarshal transform closure anyway if it exists. - if (transformClosBytes != null && transformClosCol == null) - transformClosCol = ctx.marshaller().unmarshal(transformClosBytes, clsLdr); + if (transformClosBytes != null && entryProcessorsCol == null) + entryProcessorsCol = ctx.marshaller().unmarshal(transformClosBytes, clsLdr); if (filters == null && filterBytes != null) { filters = ctx.marshaller().unmarshal(filterBytes, clsLdr); @@ -820,7 +848,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, } else { out.writeObject(key); - U.writeCollection(out, transformClosCol); + U.writeCollection(out, entryProcessorsCol); U.writeArray(out, filters); } @@ -850,7 +878,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, } else { key = (K)in.readObject(); - transformClosCol = U.readCollection(in); + entryProcessorsCol = U.readCollection(in); filters = U.readEntryFilterArray(in); } @@ -1022,6 +1050,7 @@ public class IgniteTxEntry implements GridPeerDeployAware, Externalizable, } /** + * @param sharedCtx Shared cache context. * @param ctx Cache context. * @param depEnabled Deployment enabled flag. * @throws IgniteCheckedException If marshaling failed. diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxHandler.java index 1d4b5d7..7284161 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxHandler.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxHandler.java @@ -1155,7 +1155,7 @@ public class IgniteTxHandler { txEntry.keyBytes(), txEntry.value(), txEntry.valueBytes(), - txEntry.transformClosures(), + txEntry.entryProcessors(), txEntry.drVersion(), txEntry.ttl()); diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalAdapter.java index 84ef5b7..7f86472 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalAdapter.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalAdapter.java @@ -28,6 +28,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.atomic.*; @@ -456,7 +457,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter boolean intercept = e.context().config().getInterceptor() != null; - if (intercept || !F.isEmpty(e.transformClosures())) + if (intercept || !F.isEmpty(e.entryProcessors())) e.cached().unswap(true, false); GridTuple3 res = applyTransformClosures(e, false); @@ -645,7 +646,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (cacheCtx.isNear()) ((GridNearCacheEntry)cached).recordDhtVersion(txEntry.dhtVersion()); - if (!F.isEmpty(txEntry.transformClosures()) || !F.isEmpty(txEntry.filters())) + if (!F.isEmpty(txEntry.entryProcessors()) || !F.isEmpty(txEntry.filters())) txEntry.cached().unswap(true, false); GridTuple3 res = applyTransformClosures(txEntry, @@ -702,7 +703,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter txEntry.value(val, true, false); txEntry.valueBytes(valBytes); txEntry.op(op); - txEntry.transformClosures(null); + txEntry.entryProcessors(null); txEntry.drVersion(explicitVer); } @@ -1061,10 +1062,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter // Read value from locked entry in group-lock transaction as well. if (txEntry.hasValue()) { - if (!F.isEmpty(txEntry.transformClosures())) { - for (IgniteClosure clos : txEntry.transformClosures()) - val = clos.apply(val); - } + if (!F.isEmpty(txEntry.entryProcessors())) + val = txEntry.applyEntryProcessors(val); if (val != null) { V val0 = val; @@ -1082,7 +1081,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter try { Object transformClo = (txEntry.op() == TRANSFORM && cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ)) ? - F.first(txEntry.transformClosures()) : null; + F.first(txEntry.entryProcessors()) : null; val = txEntry.cached().innerGet(this, /*swap*/true, @@ -1102,10 +1101,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (!readCommitted()) txEntry.readValue(val); - if (!F.isEmpty(txEntry.transformClosures())) { - for (IgniteClosure clos : txEntry.transformClosures()) - val = clos.apply(val); - } + if (!F.isEmpty(txEntry.entryProcessors())) + val = txEntry.applyEntryProcessors(val); V val0 = val; @@ -1195,6 +1192,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter txEntry = addEntry(READ, val, null, + null, entry, expiryPlc, filter, @@ -1229,6 +1227,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter txEntry = addEntry(READ, val, null, + null, entry, expiryPlc, CU.empty(), @@ -1344,10 +1343,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (!readCommitted()) txEntry.readValue(val); - if (!F.isEmpty(txEntry.transformClosures())) { - for (IgniteClosure clos : txEntry.transformClosures()) - visibleVal = clos.apply(visibleVal); - } + if (!F.isEmpty(txEntry.entryProcessors())) + visibleVal = txEntry.applyEntryProcessors(visibleVal); } // In pessimistic mode we hold the lock, so filter validation @@ -1560,9 +1557,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter try { Object transformClo = - (!F.isEmpty(txEntry.transformClosures()) && + (!F.isEmpty(txEntry.entryProcessors()) && cctx.gridEvents().isRecordable(EVT_CACHE_OBJECT_READ)) ? - F.first(txEntry.transformClosures()) : null; + F.first(txEntry.entryProcessors()) : null; V val = cached.innerGet(IgniteTxLocalAdapter.this, cacheCtx.isSwapOrOffheapEnabled(), @@ -1584,10 +1581,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter txEntry.setAndMarkValid(val); - if (!F.isEmpty(txEntry.transformClosures())) { - for (IgniteClosure clos : txEntry.transformClosures()) - val = clos.apply(val); - } + if (!F.isEmpty(txEntry.entryProcessors())) + val = txEntry.applyEntryProcessors(val); if (cacheCtx.portableEnabled()) val = (V)cacheCtx.unwrapPortableIfNeeded(val, !deserializePortable); @@ -1711,10 +1706,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (!readCommitted()) txEntry.readValue(val); - if (!F.isEmpty(txEntry.transformClosures())) { - for (IgniteClosure clos : txEntry.transformClosures()) - val = clos.apply(val); - } + if (!F.isEmpty(txEntry.entryProcessors())) + val = txEntry.applyEntryProcessors(val); retMap.put(entry.getKey(), val); } @@ -1736,6 +1729,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } /** {@inheritDoc} */ + @SuppressWarnings("unchecked") @Override public IgniteFuture> putAllAsync( GridCacheContext cacheCtx, Map map, @@ -1744,7 +1738,14 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter long ttl, IgnitePredicate>[] filter ) { - return putAllAsync0(cacheCtx, map, null, null, retval, cached, ttl, filter); + return (IgniteFuture>)putAllAsync0(cacheCtx, + map, + null, + null, + null, + retval, + cached, + filter); } /** {@inheritDoc} */ @@ -1752,18 +1753,31 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter GridCacheContext cacheCtx, Map> drMap ) { - return putAllAsync0(cacheCtx, null, null, drMap, false, null, -1, null); + return putAllAsync0(cacheCtx, + null, + null, + null, + drMap, + false, + null, + null); } /** {@inheritDoc} */ - @Override public IgniteFuture> transformAllAsync( + @SuppressWarnings("unchecked") + @Override public IgniteFuture>>> invokeAsync( GridCacheContext cacheCtx, - @Nullable Map> map, - boolean retval, - @Nullable GridCacheEntryEx cached, - long ttl + @Nullable Map> map, + Object... invokeArgs ) { - return putAllAsync0(cacheCtx, null, map, null, retval, null, -1, null); + return (IgniteFuture>>>)putAllAsync0(cacheCtx, + null, + map, + invokeArgs, + null, + false, + null, + null); } /** {@inheritDoc} */ @@ -1796,7 +1810,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @param expiryPlc Explicitly specified expiry policy for entry. * @param implicit Implicit flag. * @param lookup Value lookup map ({@code null} for remove). - * @param transformMap Map with transform closures if this is a transform operation. + * @param invokeMap Map with entry processors for invoke operation. + * @param invokeArgs Optional arguments for EntryProcessor. * @param retval Flag indicating whether a value should be returned. * @param lockOnly If {@code true}, then entry will be enlisted as noop. * @param filter User filters. @@ -1807,13 +1822,14 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @return Future with skipped keys (the ones that didn't pass filter for pessimistic transactions). */ protected IgniteFuture> enlistWrite( - GridCacheContext cacheCtx, + final GridCacheContext cacheCtx, Collection keys, @Nullable GridCacheEntryEx cached, @Nullable ExpiryPolicy expiryPlc, boolean implicit, @Nullable Map lookup, - @Nullable Map> transformMap, + @Nullable Map> invokeMap, + @Nullable Object[] invokeArgs, boolean retval, boolean lockOnly, IgnitePredicate>[] filter, @@ -1834,18 +1850,20 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter Set skipped = null; - boolean rmv = lookup == null && transformMap == null; + boolean rmv = lookup == null && invokeMap == null; + + Set missedForInvoke = null; try { // Set transform flag for transaction. - if (transformMap != null) + if (invokeMap != null) transform = true; groupLockSanityCheck(cacheCtx, keys); for (K key : keys) { V val = rmv || lookup == null ? null : lookup.get(key); - IgniteClosure transformClo = transformMap == null ? null : transformMap.get(key); + EntryProcessor entryProcessor = invokeMap == null ? null : invokeMap.get(key); GridCacheVersion drVer; long drTtl; @@ -1876,7 +1894,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (key == null) continue; - if (!rmv && val == null && transformClo == null) { + if (!rmv && val == null && entryProcessor == null) { skipped = skip(skipped, key); continue; @@ -1930,7 +1948,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter /*events*/retval, /*temporary*/false, CU.subjectId(this, cctx), - transformClo, + entryProcessor, resolveTaskName(), CU.empty(), null); @@ -1952,7 +1970,16 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (!readCommitted() && old != null) { // Enlist failed filters as reads for non-read-committed mode, // so future ops will get the same values. - txEntry = addEntry(READ, old, null, entry, null, CU.empty(), false, -1L, -1L, + txEntry = addEntry(READ, + old, + null, + null, + entry, + null, + CU.empty(), + false, + -1L, + -1L, null); txEntry.markValid(); @@ -1964,9 +1991,20 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter break; // While. } - txEntry = addEntry(lockOnly ? NOOP : rmv ? DELETE : transformClo != null ? TRANSFORM : - old != null ? UPDATE : CREATE, val, transformClo, entry, expiryPlc, filter, true, drTtl, - drExpireTime, drVer); + final GridCacheOperation op = lockOnly ? NOOP : rmv ? DELETE : + entryProcessor != null ? TRANSFORM : old != null ? UPDATE : CREATE; + + txEntry = addEntry(op, + val, + entryProcessor, + invokeArgs, + entry, + expiryPlc, + filter, + true, + drTtl, + drExpireTime, + drVer); if (!implicit() && readCommitted()) cacheCtx.evicts().touch(entry, topologyVersion()); @@ -1980,7 +2018,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter txEntry.markValid(); if (old == null) { - if (retval && !readThrough) { + boolean load = retval && !readThrough; + + // Check for transform here to avoid map creation. + load |= (op == TRANSFORM && keys.size() == 1); + + if (load) { // If return value is required, then we know for sure that there is only // one key in the keys collection. assert keys.size() == 1; @@ -1996,7 +2039,16 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter log.debug("Loaded value from remote node [key=" + k + ", val=" + v + ']'); - ret.set(v, true); + if (op == TRANSFORM) { + IgniteTxEntry e = + entry(new IgniteTxKey<>(k, cacheCtx.cacheId())); + + assert e != null && e.op() == TRANSFORM : e; + + addInvokeResult(e, v, ret); + } + else + ret.set(v, true); } }); @@ -2013,15 +2065,39 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } ); } - else - ret.set(null, true); + else { + if (retval) + ret.set(null, true); + else { + if (txEntry.op() == TRANSFORM) { + if (missedForInvoke == null) + missedForInvoke = new HashSet<>(); + + missedForInvoke.add(key); + } + else + ret.success(true); + } + } + } + else { + if (retval) + ret.set(old, true); + else { + if (txEntry.op() == TRANSFORM) + addInvokeResult(txEntry, old, ret); + else + ret.success(true); + } } - else - ret.set(old, true); } // Pessimistic. - else - ret.set(old, true); + else { + if (retval) + ret.set(old, true); + else + ret.success(true); + } break; // While. } @@ -2032,7 +2108,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } } else { - if (transformClo == null && txEntry.op() == TRANSFORM) + if (entryProcessor == null && txEntry.op() == TRANSFORM) throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " + "transaction after transform closure is applied): " + key); @@ -2051,18 +2127,34 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter continue; } - txEntry = addEntry(rmv ? DELETE : transformClo != null ? TRANSFORM : - v != null ? UPDATE : CREATE, val, transformClo, entry, expiryPlc, filter, true, drTtl, - drExpireTime, drVer); + GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM : + v != null ? UPDATE : CREATE; + + txEntry = addEntry(op, + val, + entryProcessor, + invokeArgs, + entry, + expiryPlc, + filter, + true, + drTtl, + drExpireTime, + drVer); enlisted.add(key); + + if (txEntry.op() == TRANSFORM) + addInvokeResult(txEntry, txEntry.value(), ret); } if (!pessimistic()) { txEntry.markValid(); - // Set tx entry and return values. - ret.set(v, true); + if (retval) + ret.set(v, true); + else + ret.success(true); } } } @@ -2071,6 +2163,42 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter return new GridFinishedFuture<>(cctx.kernalContext(), e); } + if (missedForInvoke != null) { + assert optimistic(); + assert invokeMap != null; + + IgniteFuture fut = loadMissing( + cacheCtx, + true, + missedForInvoke, + deserializePortables(cacheCtx), + new CI2() { + @Override public void apply(K key, V val) { + if (log.isDebugEnabled()) + log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']'); + + IgniteTxEntry e = entry(new IgniteTxKey<>(key, cacheCtx.cacheId())); + + assert e != null && e.op() == TRANSFORM : e; + + addInvokeResult(e, val, ret); + } + }); + + return new GridEmbeddedFuture<>( + cctx.kernalContext(), + fut, + new C2>() { + @Override public Set apply(Boolean b, Exception e) { + if (e != null) + throw new GridClosureException(e); + + return Collections.emptySet(); + } + } + ); + } + return new GridFinishedFuture<>(cctx.kernalContext(), skipped); } @@ -2080,8 +2208,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @param cacheCtx Context. * @param keys Keys. * @param failed Collection of potentially failed keys (need to populate in this method). - * @param transformed Output map where transformed values will be placed. - * @param transformMap Transform map. * @param ret Return value. * @param rmv {@code True} if remove. * @param retval Flag to return value or not. @@ -2090,19 +2216,20 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @param filter Filter to check entries. * @return Failed keys. * @throws IgniteCheckedException If error. + * @param computeInvoke If {@code true} computes return value for invoke operation. */ + @SuppressWarnings("unchecked") protected Set postLockWrite( GridCacheContext cacheCtx, Iterable keys, Set failed, - @Nullable Map transformed, - @Nullable Map> transformMap, - GridCacheReturn ret, + GridCacheReturn ret, boolean rmv, boolean retval, boolean read, long accessTtl, - IgnitePredicate>[] filter + IgnitePredicate>[] filter, + boolean computeInvoke ) throws IgniteCheckedException { for (K k : keys) { IgniteTxEntry txEntry = entry(cacheCtx.txKey(k)); @@ -2132,17 +2259,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (!F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter)) retval = true; - if (retval) { + boolean invoke = txEntry.op() == TRANSFORM; + + if (retval || invoke) { if (!cacheCtx.isNear()) { try { if (!hasPrevVal) v = cached.innerGet(this, - /*swap*/retval, - /*read-through*/retval, + /*swap*/true, + /*read-through*/true, /*failFast*/false, - /*unmarshal*/retval, - /*metrics*/true, - /*event*/!dht(), + /*unmarshal*/true, + /*metrics*/!invoke, + /*event*/!invoke && !dht(), /*temporary*/false, CU.subjectId(this, cctx), null, @@ -2158,10 +2287,15 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } else { if (!hasPrevVal) - v = retval ? cached.rawGetOrUnmarshal(false) : cached.rawGet(); + v = cached.rawGetOrUnmarshal(false); } - ret.value(v); + if (txEntry.op() == TRANSFORM) { + if (computeInvoke) + addInvokeResult(txEntry, v, ret); + } + else + ret.value(v); } boolean pass = cacheCtx.isAll(cached, filter); @@ -2185,7 +2319,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter failed = skip(failed, k); // Revert operation to previous. (if no - NOOP, so entry will be unlocked). - txEntry.setAndMarkValid(txEntry.previousOperation(), ret.value()); + txEntry.setAndMarkValid(txEntry.previousOperation(), (V)ret.value()); txEntry.filters(CU.empty()); txEntry.filtersSet(false); @@ -2222,33 +2356,61 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } /** + * @param txEntry Entry. + * @param val Value. + * @param ret Return value to update. + */ + private void addInvokeResult(IgniteTxEntry txEntry, V val, GridCacheReturn ret) { + try { + Object res = null; + + for (T2, Object[]> t : txEntry.entryProcessors()) { + CacheInvokeEntry invokeEntry = new CacheInvokeEntry<>(txEntry.key(), val); + + EntryProcessor entryProcessor = t.get1(); + + res = entryProcessor.process(invokeEntry, t.get2()); + } + + if (res != null) + ret.addEntryProcessResult(txEntry.key(), new CacheInvokeResult<>(res)); + } + catch (Exception e) { + ret.addEntryProcessResult(txEntry.key(), new CacheInvokeResult(e)); + } + } + + /** * Internal method for all put and transform operations. Only one of {@code map}, {@code transformMap} * maps must be non-null. * * @param cacheCtx Context. * @param map Key-value map to store. - * @param transformMap Transform map. + * @param invokeMap Invoke map. + * @param invokeArgs Optional arguments for EntryProcessor. * @param drMap DR map. * @param retval Key-transform value map to store. * @param cached Cached entry, if any. - * @param ttl Time to live. * @param filter Filter. * @return Operation future. */ - private IgniteFuture> putAllAsync0( + @SuppressWarnings("unchecked") + private IgniteFuture putAllAsync0( final GridCacheContext cacheCtx, @Nullable Map map, - @Nullable Map> transformMap, + @Nullable Map> invokeMap, + @Nullable final Object[] invokeArgs, @Nullable final Map> drMap, final boolean retval, @Nullable GridCacheEntryEx cached, - long ttl, @Nullable final IgnitePredicate>[] filter) { + assert filter == null || invokeMap == null; + cacheCtx.checkSecurity(GridSecurityPermission.CACHE_PUT); // Cached entry may be passed only from entry wrapper. final Map map0; - final Map> transformMap0; + final Map> invokeMap0; if (drMap != null) { assert map == null; @@ -2259,7 +2421,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } }); - transformMap0 = null; + invokeMap0 = null; } else if (cacheCtx.portableEnabled()) { if (map != null) { @@ -2280,14 +2442,14 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter else map0 = null; - if (transformMap != null) { - transformMap0 = U.newHashMap(transformMap.size()); + if (invokeMap != null) { + invokeMap0 = U.newHashMap(invokeMap.size()); try { - for (Map.Entry> e : transformMap.entrySet()) { + for (Map.Entry> e : invokeMap.entrySet()) { K key = (K)cacheCtx.marshalToPortable(e.getKey()); - transformMap0.put(key, e.getValue()); + invokeMap0.put(key, e.getValue()); } } catch (PortableException e) { @@ -2295,19 +2457,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } } else - transformMap0 = null; + invokeMap0 = null; } else { map0 = (Map)map; - transformMap0 = (Map>)transformMap; + invokeMap0 = (Map>)invokeMap; } if (log.isDebugEnabled()) log.debug("Called putAllAsync(...) [tx=" + this + ", map=" + map0 + ", retval=" + retval + "]"); - assert map0 != null || transformMap0 != null; + assert map0 != null || invokeMap0 != null; assert cached == null || - (map0 != null && map0.size() == 1) || (transformMap0 != null && transformMap0.size() == 1); + (map0 != null && map0.size() == 1) || (invokeMap0 != null && invokeMap0.size() == 1); try { checkValid(); @@ -2320,7 +2482,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter final GridCacheReturn ret = new GridCacheReturn<>(false); - if (F.isEmpty(map0) && F.isEmpty(transformMap0)) { + if (F.isEmpty(map0) && F.isEmpty(invokeMap0)) { if (implicit()) try { commit(); @@ -2333,7 +2495,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter } try { - Set keySet = map0 != null ? map0.keySet() : transformMap0.keySet(); + Set keySet = map0 != null ? map0.keySet() : invokeMap0.keySet(); Collection enlisted = new LinkedList<>(); @@ -2346,7 +2508,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter prj != null ? prj.expiry() : null, implicit, map0, - transformMap0, + invokeMap0, + invokeArgs, retval, false, filter, @@ -2390,19 +2553,16 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter if (log.isDebugEnabled()) log.debug("Acquired transaction lock for put on keys: " + keys); - Map transformed = null; - postLockWrite(cacheCtx, keys, loaded, - transformed, - transformMap0, ret, /*remove*/false, retval, /*read*/false, -1L, - filter); + filter, + /*computeInvoke*/true); return ret; } @@ -2554,7 +2714,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter plc, implicit, /** lookup map */null, - /** transform map */null, + /** invoke map */null, + /** invoke arguments */null, retval, /** lock only */false, filter, @@ -2595,14 +2756,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter postLockWrite(cacheCtx, passedKeys, loadFut.get(), - null, - null, ret, /*remove*/true, retval, /*read*/false, -1L, - filter); + filter, + /*computeInvoke*/false); return ret; } @@ -2650,6 +2810,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter /** * Checks if portable values should be deserialized. * + * @param cacheCtx Cache context. * @return {@code True} if portables should be deserialized, {@code false} otherwise. */ private boolean deserializePortables(GridCacheContext cacheCtx) { @@ -2670,6 +2831,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter /** * Checks that affinity keys are enlisted in group transaction on start. * + * @param cacheCtx Cache context. * @param keys Keys to check. * @throws IgniteCheckedException If sanity check failed. */ @@ -2721,7 +2883,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter /** expiry - leave unchanged */null, /** implicit */false, /** lookup map */null, - /** transform map */null, + /** invoke map */null, + /** invoke arguments */null, /** retval */false, /** lock only */true, CU.empty(), @@ -2842,7 +3005,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter * @param op Cache operation. * @param val Value. * @param expiryPlc Explicitly specified expiry policy. - * @param transformClos Transform closure. + * @param invokeArgs Optional arguments for EntryProcessor. + * @param entryProcessor Entry processor. * @param entry Cache entry. * @param filter Filter. * @param filtersSet {@code True} if filter should be marked as set. @@ -2853,7 +3017,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter */ protected final IgniteTxEntry addEntry(GridCacheOperation op, @Nullable V val, - @Nullable IgniteClosure transformClos, + @Nullable EntryProcessor entryProcessor, + Object[] invokeArgs, GridCacheEntryEx entry, @Nullable ExpiryPolicy expiryPlc, IgnitePredicate>[] filter, @@ -2861,6 +3026,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter long drTtl, long drExpireTime, @Nullable GridCacheVersion drVer) { + assert invokeArgs == null || op == TRANSFORM; + IgniteTxKey key = entry.txKey(); checkInternal(key); @@ -2883,12 +3050,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter IgniteTxEntry txEntry; if (old != null) { - if (transformClos != null) { + if (entryProcessor != null) { assert val == null; assert op == TRANSFORM; // Will change the op. - old.addTransformClosure(transformClos); + old.addEntryProcessor(entryProcessor, invokeArgs); } else { assert old.op() != TRANSFORM; @@ -2922,7 +3089,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter this, op, val, - transformClos, + entryProcessor, + invokeArgs, hasDrTtl ? drTtl : -1L, entry, filter, diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalEx.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalEx.java index 63b5a79..ac79a9a 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalEx.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxLocalEx.java @@ -16,6 +16,7 @@ import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.kernal.processors.cache.dr.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.util.*; /** @@ -53,6 +54,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { @Nullable public IgniteTxEntry groupLockEntry(); /** + * @param cacheCtx Cache context. * @param keys Keys to get. * @param cached Cached entry if this method is called from entry wrapper. * Cached entry is passed if and only if there is only one key in collection of keys. @@ -68,6 +70,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { IgnitePredicate>[] filter); /** + * @param cacheCtx Cache context. * @param map Map to put. * @param retval Flag indicating whether a value should be returned. * @param cached Cached entry, if any. Will be provided only if map has size 1. @@ -84,17 +87,18 @@ public interface IgniteTxLocalEx extends IgniteTxEx { IgnitePredicate>[] filter); /** - * @param map Map to put. + * @param cacheCtx Cache context. + * @param map Entry processors map. + * @param invokeArgs Optional arguments for entry processor. * @return Transform operation future. */ - public IgniteFuture> transformAllAsync( + public IgniteFuture>>> invokeAsync( GridCacheContext cacheCtx, - @Nullable Map> map, - boolean retval, - @Nullable GridCacheEntryEx cached, - long ttl); + Map> map, + Object... invokeArgs); /** + * @param cacheCtx Cache context. * @param keys Keys to remove. * @param retval Flag indicating whether a value should be returned. * @param cached Cached entry, if any. Will be provided only if size of keys collection is 1. @@ -109,6 +113,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { IgnitePredicate>[] filter); /** + * @param cacheCtx Cache context. * @param drMap DR map to put. * @return Future for DR put operation. */ @@ -117,6 +122,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { Map> drMap); /** + * @param cacheCtx Cache context. * @param drMap DR map. * @return Future for asynchronous remove. */ @@ -127,6 +133,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { /** * Performs keys locking for affinity-based group lock transactions. * + * @param cacheCtx Cache context. * @param keys Keys to lock. * @return Lock future. */ @@ -147,6 +154,7 @@ public interface IgniteTxLocalEx extends IgniteTxEx { public boolean finish(boolean commit) throws IgniteCheckedException; /** + * @param cacheCtx Cache context. * @param async if {@code True}, then loading will happen in a separate thread. * @param keys Keys. * @param c Closure. diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadCacheUpdaters.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadCacheUpdaters.java index 3bb95cc..5341b1c 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadCacheUpdaters.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadCacheUpdaters.java @@ -11,8 +11,10 @@ package org.gridgain.grid.kernal.processors.dataload; import org.apache.ignite.*; import org.apache.ignite.dataload.*; +import org.apache.ignite.internal.processors.cache.*; import org.apache.ignite.transactions.*; import org.gridgain.grid.cache.*; +import org.gridgain.grid.cache.affinity.*; import org.gridgain.grid.util.typedef.*; import org.jetbrains.annotations.*; @@ -90,13 +92,13 @@ public class GridDataLoadCacheUpdaters { * @param putMap Entries to put. * @throws IgniteCheckedException If failed. */ - protected static void updateAll(GridCacheProjection cache, @Nullable Collection rmvCol, + protected static void updateAll(IgniteCache cache, @Nullable Collection rmvCol, Map putMap) throws IgniteCheckedException { assert rmvCol != null || putMap != null; // Here we assume that there are no key duplicates, so the following calls are valid. if (rmvCol != null) - cache.removeAll(rmvCol); + ((IgniteCacheProxy)cache).removeAll(rmvCol); if (putMap != null) cache.putAll(putMap); @@ -110,7 +112,7 @@ public class GridDataLoadCacheUpdaters { private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override public void update(GridCache cache, Collection> entries) + @Override public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException { assert cache != null; assert !F.isEmpty(entries); @@ -123,9 +125,9 @@ public class GridDataLoadCacheUpdaters { V val = entry.getValue(); if (val == null) - cache.removex(key); + cache.remove(key); else - cache.putx(key, val); + cache.put(key, val); } } } @@ -138,7 +140,7 @@ public class GridDataLoadCacheUpdaters { private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override public void update(GridCache cache, Collection> entries) + @Override public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException { assert cache != null; assert !F.isEmpty(entries); @@ -179,7 +181,7 @@ public class GridDataLoadCacheUpdaters { private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override public void update(GridCache cache, Collection> entries) + @Override public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException { assert cache != null; assert !F.isEmpty(entries); @@ -220,12 +222,12 @@ public class GridDataLoadCacheUpdaters { private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override public void update(GridCache cache, Collection> entries) + @Override public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException { assert cache != null; assert !F.isEmpty(entries); - assert cache.configuration().getAtomicityMode() != ATOMIC; + assert cache.getConfiguration(GridCacheConfiguration.class).getAtomicityMode() != ATOMIC; Map partsCounts = new HashMap<>(); @@ -233,6 +235,8 @@ public class GridDataLoadCacheUpdaters { Map> rmvPartMap = null; Map> putPartMap = null; + GridCacheAffinity aff = cache.ignite().cache(cache.getName()).affinity(); + for (Map.Entry entry : entries) { K key = entry.getKey(); @@ -240,7 +244,7 @@ public class GridDataLoadCacheUpdaters { V val = entry.getValue(); - int part = cache.affinity().partition(key); + int part = aff.partition(key); Integer cnt = partsCounts.get(part); @@ -260,21 +264,18 @@ public class GridDataLoadCacheUpdaters { } } + IgniteTransactions txs = cache.ignite().transactions(); + for (Map.Entry e : partsCounts.entrySet()) { Integer part = e.getKey(); int cnt = e.getValue(); - IgniteTx tx = cache.txStartPartition(part, PESSIMISTIC, REPEATABLE_READ, 0, cnt); - - try { + try (IgniteTx tx = txs.txStartPartition(cache.getName(), part, PESSIMISTIC, REPEATABLE_READ, 0, cnt)) { updateAll(cache, rmvPartMap == null ? null : rmvPartMap.get(part), putPartMap == null ? null : putPartMap.get(part)); tx.commit(); } - finally { - tx.close(); - } } } } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadUpdateJob.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadUpdateJob.java index 8b01cb3..fb1b12a 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadUpdateJob.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dataload/GridDataLoadUpdateJob.java @@ -11,9 +11,8 @@ package org.gridgain.grid.kernal.processors.dataload; import org.apache.ignite.*; import org.apache.ignite.dataload.*; -import org.apache.ignite.lang.*; +import org.apache.ignite.internal.processors.cache.*; import org.gridgain.grid.kernal.*; -import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.util.lang.*; import org.jetbrains.annotations.*; @@ -71,18 +70,24 @@ class GridDataLoadUpdateJob implements GridPlainCallable { if (log.isDebugEnabled()) log.debug("Running put job [nodeId=" + ctx.localNodeId() + ", size=" + col.size() + ']'); - GridCacheAdapter cache = ctx.cache().internalCache(cacheName); +// TODO IGNITE-77: restore adapter usage. +// GridCacheAdapter cache = ctx.cache().internalCache(cacheName); +// +// IgniteFuture f = cache.context().preloader().startFuture(); +// +// if (!f.isDone()) +// f.get(); +// +// if (ignoreDepOwnership) +// cache.context().deploy().ignoreOwnership(true); - IgniteFuture f = cache.context().preloader().startFuture(); - - if (!f.isDone()) - f.get(); + IgniteCacheProxy cache = ctx.cache().jcache(cacheName); if (ignoreDepOwnership) cache.context().deploy().ignoreOwnership(true); try { - updater.update(cache.cache(), col); + updater.update(cache, col); return null; } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dr/GridDrDataLoadCacheUpdater.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dr/GridDrDataLoadCacheUpdater.java index 3522cf8..0ec679d 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dr/GridDrDataLoadCacheUpdater.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/dr/GridDrDataLoadCacheUpdater.java @@ -29,11 +29,11 @@ public class GridDrDataLoadCacheUpdater implements IgniteDataLoadCacheUpda private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override public void update(GridCache cache0, Collection> col) + @Override public void update(IgniteCache cache0, Collection> col) throws IgniteCheckedException { - String cacheName = cache0.name(); + String cacheName = cache0.getConfiguration(GridCacheConfiguration.class).getName(); - GridKernalContext ctx = ((GridKernal)cache0.gridProjection().ignite()).context(); + GridKernalContext ctx = ((GridKernal)cache0.ignite()).context(); IgniteLogger log = ctx.log(GridDrDataLoadCacheUpdater.class); GridCacheAdapter cache = ctx.cache().internalCache(cacheName); diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsDataManager.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsDataManager.java index a21c8fc..1906b95 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsDataManager.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsDataManager.java @@ -34,6 +34,7 @@ import org.gridgain.grid.util.worker.*; import org.jdk8.backport.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.nio.*; import java.util.*; @@ -1101,7 +1102,7 @@ public class GridGgfsDataManager extends GridGgfsManager { // No affinity key present, just concat and return. if (colocatedKey.affinityKey() == null) { - dataCachePrj.transform(colocatedKey, new UpdateClosure(startOff, data)); + dataCachePrj.invoke(colocatedKey, new UpdateProcessor(startOff, data)); return; } @@ -1117,24 +1118,22 @@ public class GridGgfsDataManager extends GridGgfsManager { GridGgfsBlockKey key = new GridGgfsBlockKey(colocatedKey.getFileId(), null, colocatedKey.evictExclude(), colocatedKey.getBlockId()); - IgniteTx tx = dataCachePrj.txStart(PESSIMISTIC, REPEATABLE_READ); - - try { + try (IgniteTx tx = dataCachePrj.txStart(PESSIMISTIC, REPEATABLE_READ)) { // Lock keys. Map vals = dataCachePrj.getAll(F.asList(colocatedKey, key)); boolean hasVal = false; - UpdateClosure transformClos = new UpdateClosure(startOff, data); + UpdateProcessor transformClos = new UpdateProcessor(startOff, data); if (vals.get(colocatedKey) != null) { - dataCachePrj.transform(colocatedKey, transformClos); + dataCachePrj.invoke(colocatedKey, transformClos); hasVal = true; } if (vals.get(key) != null) { - dataCachePrj.transform(key, transformClos); + dataCachePrj.invoke(key, transformClos); hasVal = true; } @@ -1146,9 +1145,6 @@ public class GridGgfsDataManager extends GridGgfsManager { tx.commit(); } - finally { - tx.close(); - } } /** @@ -1570,7 +1566,8 @@ public class GridGgfsDataManager extends GridGgfsManager { * Helper closure to update data in cache. */ @GridInternal - private static final class UpdateClosure implements IgniteClosure, Externalizable { + private static final class UpdateProcessor implements EntryProcessor, + Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -1584,7 +1581,7 @@ public class GridGgfsDataManager extends GridGgfsManager { * Empty constructor required for {@link Externalizable}. * */ - public UpdateClosure() { + public UpdateProcessor() { // No-op. } @@ -1594,7 +1591,7 @@ public class GridGgfsDataManager extends GridGgfsManager { * @param start Start position in the block to write new data from. * @param data Data block to write into cache. */ - private UpdateClosure(int start, byte[] data) { + private UpdateProcessor(int start, byte[] data) { assert start >= 0; assert data != null; assert start + data.length >= 0 : "Too much data [start=" + start + ", data.length=" + data.length + ']'; @@ -1604,7 +1601,9 @@ public class GridGgfsDataManager extends GridGgfsManager { } /** {@inheritDoc} */ - @Override public byte[] apply(byte[] e) { + @Override public Void process(MutableEntry entry, Object... args) { + byte[] e = entry.getValue(); + final int size = data.length; if (e == null || e.length == 0) @@ -1621,7 +1620,9 @@ public class GridGgfsDataManager extends GridGgfsManager { // Copy data into entry. U.arrayCopy(data, 0, e, start, size); - return e; + entry.setValue(e); + + return null; } /** {@inheritDoc} */ @@ -1638,7 +1639,7 @@ public class GridGgfsDataManager extends GridGgfsManager { /** {@inheritDoc} */ @Override public String toString() { - return S.toString(UpdateClosure.class, this, "start", start, "data.length", data.length); + return S.toString(UpdateProcessor.class, this, "start", start, "data.length", data.length); } } diff --git a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsMetaManager.java b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsMetaManager.java index eb0a728..722d142 100644 --- a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsMetaManager.java +++ b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/ggfs/GridGgfsMetaManager.java @@ -26,6 +26,7 @@ import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.grid.util.lang.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; @@ -751,7 +752,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { assert metaCache.get(parentId) != null; - id2InfoPrj.transform(parentId, new UpdateListing(fileName, new GridGgfsListingEntry(newFileInfo), false)); + id2InfoPrj.invoke(parentId, new UpdateListing(fileName, new GridGgfsListingEntry(newFileInfo), false)); return null; } @@ -868,10 +869,10 @@ public class GridGgfsMetaManager extends GridGgfsManager { assert metaCache.get(destParentId) != null; // Remove listing entry from the source parent listing. - id2InfoPrj.transform(srcParentId, new UpdateListing(srcFileName, srcEntry, true)); + id2InfoPrj.invoke(srcParentId, new UpdateListing(srcFileName, srcEntry, true)); // Add listing entry into the destination parent listing. - id2InfoPrj.transform(destParentId, new UpdateListing(destFileName, srcEntry, false)); + id2InfoPrj.invoke(destParentId, new UpdateListing(destFileName, srcEntry, false)); } /** @@ -987,7 +988,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { // Update a file info of the removed file with a file path, // which will be used by delete worker for event notifications. - id2InfoPrj.transform(fileId, new UpdatePath(path)); + id2InfoPrj.invoke(fileId, new UpdatePath(path)); return GridGgfsFileInfo.builder(fileInfo).path(path).build(); } @@ -1086,12 +1087,12 @@ public class GridGgfsMetaManager extends GridGgfsManager { id2InfoPrj.put(newInfo.id(), newInfo); // Add new info to trash listing. - id2InfoPrj.transform(TRASH_ID, new UpdateListing(newInfo.id().toString(), + id2InfoPrj.invoke(TRASH_ID, new UpdateListing(newInfo.id().toString(), new GridGgfsListingEntry(newInfo), false)); // Remove listing entries from root. for (Map.Entry entry : transferListing.entrySet()) - id2InfoPrj.transform(ROOT_ID, new UpdateListing(entry.getKey(), entry.getValue(), true)); + id2InfoPrj.invoke(ROOT_ID, new UpdateListing(entry.getKey(), entry.getValue(), true)); resId = newInfo.id(); } @@ -1228,7 +1229,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { GridGgfsListingEntry listingEntry = parentInfo.listing().get(name); if (listingEntry != null) - id2InfoPrj.transform(parentId, new UpdateListing(name, listingEntry, true)); + id2InfoPrj.invoke(parentId, new UpdateListing(name, listingEntry, true)); id2InfoPrj.remove(id); @@ -1359,7 +1360,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { assert metaCache.get(parentId) != null; - id2InfoPrj.transform(parentId, new UpdateListing(fileName, entry, false)); + id2InfoPrj.invoke(parentId, new UpdateListing(fileName, entry, false)); } return newInfo; @@ -1424,7 +1425,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { assert validTxState(false); - id2InfoPrj.transformAsync(parentId, new UpdateListingEntry(fileId, fileName, lenDelta, 0, + id2InfoPrj.invokeAsync(parentId, new UpdateListingEntry(fileId, fileName, lenDelta, 0, modificationTime)); } finally { @@ -1659,9 +1660,9 @@ public class GridGgfsMetaManager extends GridGgfsManager { id2InfoPrj.removex(oldId); // Remove the old one. id2InfoPrj.putx(newInfo.id(), newInfo); // Put the new one. - id2InfoPrj.transform(parentInfo.id(), + id2InfoPrj.invoke(parentInfo.id(), new UpdateListing(path.name(), parentInfo.listing().get(path.name()), true)); - id2InfoPrj.transform(parentInfo.id(), + id2InfoPrj.invoke(parentInfo.id(), new UpdateListing(path.name(), new GridGgfsListingEntry(newInfo), false)); IgniteFuture delFut = ggfsCtx.data().delete(oldInfo); @@ -2150,7 +2151,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { } // Update the deleted file info with path information for delete worker. - id2InfoPrj.transform(info.id(), new UpdatePath(path)); + id2InfoPrj.invoke(info.id(), new UpdatePath(path)); return true; // No additional handling is required. } @@ -2606,7 +2607,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { id2InfoPrj.putx(fileId, updated); - id2InfoPrj.transform(parentId, new UpdateListingEntry(fileId, fileName, 0, accessTime, + id2InfoPrj.invoke(parentId, new UpdateListingEntry(fileId, fileName, 0, accessTime, modificationTime)); tx.commit(); @@ -2741,7 +2742,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { /** * Updates file length information in parent listing. */ - private static final class UpdateListingEntry implements IgniteClosure, + private static final class UpdateListingEntry implements EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -2775,8 +2776,11 @@ public class GridGgfsMetaManager extends GridGgfsManager { * @param accessTime Last access time. * @param modificationTime Last modification time. */ - private UpdateListingEntry(IgniteUuid fileId, String fileName, long lenDelta, - long accessTime, long modificationTime) { + private UpdateListingEntry(IgniteUuid fileId, + String fileName, + long lenDelta, + long accessTime, + long modificationTime) { this.fileId = fileId; this.fileName = fileName; this.lenDelta = lenDelta; @@ -2785,13 +2789,15 @@ public class GridGgfsMetaManager extends GridGgfsManager { } /** {@inheritDoc} */ - @Override public GridGgfsFileInfo apply(GridGgfsFileInfo fileInfo) { + @Override public Void process(MutableEntry e, Object... args) { + GridGgfsFileInfo fileInfo = e.getValue(); + Map listing = fileInfo.listing(); GridGgfsListingEntry entry = listing.get(fileName); if (entry == null || !entry.fileId().equals(fileId)) - return fileInfo; + return null; entry = new GridGgfsListingEntry(entry, entry.length() + lenDelta, accessTime == -1 ? entry.accessTime() : accessTime, @@ -2803,7 +2809,9 @@ public class GridGgfsMetaManager extends GridGgfsManager { // Modify listing map in-place since map is serialization-safe. listing.put(fileName, entry); - return new GridGgfsFileInfo(listing, fileInfo); + e.setValue(new GridGgfsFileInfo(listing, fileInfo)); + + return null; } /** {@inheritDoc} */ @@ -2829,7 +2837,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { * Update directory listing closure. */ @GridInternal - private static final class UpdateListing implements IgniteClosure, + private static final class UpdateListing implements EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -2868,7 +2876,9 @@ public class GridGgfsMetaManager extends GridGgfsManager { } /** {@inheritDoc} */ - @Override @Nullable public GridGgfsFileInfo apply(GridGgfsFileInfo fileInfo) { + @Override public Void process(MutableEntry e, Object... args) { + GridGgfsFileInfo fileInfo = e.getValue(); + assert fileInfo != null : "File info not found for the child: " + entry.fileId(); assert fileInfo.isDirectory(); @@ -2897,7 +2907,9 @@ public class GridGgfsMetaManager extends GridGgfsManager { ", oldEntry=" + oldEntry + ']'); } - return new GridGgfsFileInfo(listing, fileInfo); + e.setValue(new GridGgfsFileInfo(listing, fileInfo)); + + return null; } /** {@inheritDoc} */ @@ -2924,7 +2936,7 @@ public class GridGgfsMetaManager extends GridGgfsManager { * Update path closure. */ @GridInternal - private static final class UpdatePath implements IgniteClosure, + private static final class UpdatePath implements EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -2943,11 +2955,16 @@ public class GridGgfsMetaManager extends GridGgfsManager { * Default constructor (required by Externalizable). */ public UpdatePath() { + // No-op. } /** {@inheritDoc} */ - @Override public GridGgfsFileInfo apply(GridGgfsFileInfo info) { - return GridGgfsFileInfo.builder(info).path(path).build(); + @Override public Void process(MutableEntry e, Object... args) { + GridGgfsFileInfo info = e.getValue(); + + e.setValue(GridGgfsFileInfo.builder(info).path(path).build()); + + return null; } /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicInvokeTest.java new file mode 100644 index 0000000..6a97b19 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicInvokeTest.java @@ -0,0 +1,47 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheAtomicWriteOrderMode.*; +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public class IgniteCacheAtomicInvokeTest extends IgniteCacheInvokeAbstractTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 3; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return ATOMIC; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicWriteOrderMode atomicWriteOrderMode() { + return CLOCK; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalInvokeTest.java new file mode 100644 index 0000000..7048f18 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalInvokeTest.java @@ -0,0 +1,41 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public class IgniteCacheAtomicLocalInvokeTest extends IgniteCacheInvokeAbstractTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 1; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return LOCAL; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return ATOMIC; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalWithStoreInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalWithStoreInvokeTest.java new file mode 100644 index 0000000..2ff0468 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicLocalWithStoreInvokeTest.java @@ -0,0 +1,22 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.store.*; + +/** + * + */ +public class IgniteCacheAtomicLocalWithStoreInvokeTest extends IgniteCacheAtomicLocalInvokeTest { + /** {@inheritDoc} */ + @Override protected GridCacheStore cacheStore() { + return new TestStore(); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicNearEnabledInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicNearEnabledInvokeTest.java new file mode 100644 index 0000000..8f4d71c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicNearEnabledInvokeTest.java @@ -0,0 +1,24 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class IgniteCacheAtomicNearEnabledInvokeTest extends IgniteCacheAtomicInvokeTest { + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return NEAR_PARTITIONED; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderInvokeTest.java new file mode 100644 index 0000000..8f8b479 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderInvokeTest.java @@ -0,0 +1,47 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheAtomicWriteOrderMode.*; +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public class IgniteCacheAtomicPrimaryWriteOrderInvokeTest extends IgniteCacheInvokeAbstractTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 3; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return ATOMIC; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicWriteOrderMode atomicWriteOrderMode() { + return PRIMARY; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderWithStoreInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderWithStoreInvokeTest.java new file mode 100644 index 0000000..5fa85e3 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAtomicPrimaryWriteOrderWithStoreInvokeTest.java @@ -0,0 +1,23 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.store.*; + +/** + * + */ +public class IgniteCacheAtomicPrimaryWriteOrderWithStoreInvokeTest extends + IgniteCacheAtomicPrimaryWriteOrderInvokeTest { + /** {@inheritDoc} */ + @Override protected GridCacheStore cacheStore() { + return new IgniteCacheAbstractTest.TestStore(); + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInvokeAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInvokeAbstractTest.java new file mode 100644 index 0000000..bda973f --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheInvokeAbstractTest.java @@ -0,0 +1,647 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.apache.ignite.*; +import org.apache.ignite.lang.*; +import org.apache.ignite.transactions.*; +import org.gridgain.grid.cache.*; +import org.gridgain.grid.util.typedef.internal.*; +import org.gridgain.testframework.*; +import org.jetbrains.annotations.*; + +import javax.cache.processor.*; + +import java.util.*; +import java.util.concurrent.*; + +import static org.apache.ignite.transactions.IgniteTxConcurrency.*; +import static org.apache.ignite.transactions.IgniteTxIsolation.*; +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheFlag.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public abstract class IgniteCacheInvokeAbstractTest extends IgniteCacheAbstractTest { + /** */ + private Integer lastKey = 0; + + /** + * @throws Exception If failed. + */ + public void testInvoke() throws Exception { + IgniteCache cache = jcache(); + + invoke(cache, null); + + if (atomicityMode() == TRANSACTIONAL) { + invoke(cache, PESSIMISTIC); + + invoke(cache, OPTIMISTIC); + } + else if (gridCount() > 1) { + cache = cache.flagsOn(FORCE_TRANSFORM_BACKUP); + + invoke(cache, null); + } + } + + /** + * @param cache Cache. + * @param txMode Not null transaction concurrency mode if explicit transaction should be started. + * @throws Exception If failed. + */ + private void invoke(final IgniteCache cache, @Nullable IgniteTxConcurrency txMode) + throws Exception { + IncrementProcessor incProcessor = new IncrementProcessor(); + + for (final Integer key : keys()) { + log.info("Test invoke [key=" + key + ", txMode=" + txMode + ']'); + + cache.remove(key); + + IgniteTx tx = startTx(txMode); + + Integer res = cache.invoke(key, incProcessor); + + if (tx != null) + tx.commit(); + + assertEquals(-1, (int)res); + + checkValue(key, 1); + + tx = startTx(txMode); + + res = cache.invoke(key, incProcessor); + + if (tx != null) + tx.commit(); + + assertEquals(1, (int)res); + + checkValue(key, 2); + + tx = startTx(txMode); + + res = cache.invoke(key, incProcessor); + + if (tx != null) + tx.commit(); + + assertEquals(2, (int)res); + + checkValue(key, 3); + + tx = startTx(txMode); + + res = cache.invoke(key, new ArgumentsSumProcessor(), 10, 20, 30); + + if (tx != null) + tx.commit(); + + assertEquals(3, (int)res); + + checkValue(key, 63); + + tx = startTx(txMode); + + String strRes = cache.invoke(key, new ToStringProcessor()); + + if (tx != null) + tx.commit(); + + assertEquals("63", strRes); + + checkValue(key, 63); + + tx = startTx(txMode); + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + cache.invoke(key, new ExceptionProcessor(63)); + + return null; + } + }, EntryProcessorException.class, "Test processor exception."); + + if (tx != null) + tx.commit(); + + checkValue(key, 63); + + IgniteCache asyncCache = cache.enableAsync(); + + assertTrue(asyncCache.isAsync()); + + assertNull(asyncCache.invoke(key, incProcessor)); + + IgniteFuture fut = asyncCache.future(); + + assertNotNull(fut); + + assertEquals(63, (int)fut.get()); + + checkValue(key, 64); + + tx = startTx(txMode); + + assertNull(cache.invoke(key, new RemoveProcessor(64))); + + if (tx != null) + tx.commit(); + + checkValue(key, null); + } + } + + /** + * @throws Exception If failed. + */ + public void testInvokeAll() throws Exception { + IgniteCache cache = jcache(); + + invokeAll(cache, null); + + if (atomicityMode() == TRANSACTIONAL) { + invokeAll(cache, PESSIMISTIC); + + invokeAll(cache, OPTIMISTIC); + } + else if (gridCount() > 1) { + cache = cache.flagsOn(FORCE_TRANSFORM_BACKUP); + + invokeAll(cache, null); + } + } + + /** + * @param cache Cache. + * @param txMode Not null transaction concurrency mode if explicit transaction should be started. + * @throws Exception If failed. + */ + private void invokeAll(IgniteCache cache, @Nullable IgniteTxConcurrency txMode) throws Exception { + invokeAll(cache, new HashSet<>(primaryKeys(cache, 3, 0)), txMode); + + if (gridCount() > 1) { + invokeAll(cache, new HashSet<>(backupKeys(cache, 3, 0)), txMode); + + invokeAll(cache, new HashSet<>(nearKeys(cache, 3, 0)), txMode); + + Set keys = new HashSet<>(); + + keys.addAll(primaryKeys(jcache(0), 3, 0)); + keys.addAll(primaryKeys(jcache(1), 3, 0)); + keys.addAll(primaryKeys(jcache(2), 3, 0)); + + invokeAll(cache, keys, txMode); + } + + Set keys = new HashSet<>(); + + for (int i = 0; i < 1000; i++) + keys.add(i); + + invokeAll(cache, keys, txMode); + } + + /** + * @param cache Cache. + * @param keys Keys. + * @param txMode Not null transaction concurrency mode if explicit transaction should be started. + * @throws Exception If failed. + */ + private void invokeAll(IgniteCache cache, + Set keys, + @Nullable IgniteTxConcurrency txMode) throws Exception { + cache.removeAll(keys); + + log.info("Test invokeAll [keys=" + keys + ", txMode=" + txMode + ']'); + + IncrementProcessor incProcessor = new IncrementProcessor(); + + IgniteTx tx = startTx(txMode); + + Map> resMap = cache.invokeAll(keys, incProcessor); + + if (tx != null) + tx.commit(); + + Map exp = new HashMap<>(); + + for (Integer key : keys) + exp.put(key, -1); + + checkResult(resMap, exp); + + for (Integer key : keys) + checkValue(key, 1); + + tx = startTx(txMode); + + resMap = cache.invokeAll(keys, incProcessor); + + if (tx != null) + tx.commit(); + + exp = new HashMap<>(); + + for (Integer key : keys) + exp.put(key, 1); + + checkResult(resMap, exp); + + for (Integer key : keys) + checkValue(key, 2); + + tx = startTx(txMode); + + resMap = cache.invokeAll(keys, new ArgumentsSumProcessor(), 10, 20, 30); + + if (tx != null) + tx.commit(); + + for (Integer key : keys) + exp.put(key, 3); + + checkResult(resMap, exp); + + for (Integer key : keys) + checkValue(key, 62); + + tx = startTx(txMode); + + resMap = cache.invokeAll(keys, new ExceptionProcessor(null)); + + if (tx != null) + tx.commit(); + + for (Integer key : keys) { + final EntryProcessorResult res = resMap.get(key); + + assertNotNull("No result for " + key); + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + res.get(); + + return null; + } + }, EntryProcessorException.class, "Test processor exception."); + } + + for (Integer key : keys) + checkValue(key, 62); + + tx = startTx(txMode); + + Map> invokeMap = new HashMap<>(); + + for (Integer key : keys) { + switch (key % 4) { + case 0: invokeMap.put(key, new IncrementProcessor()); break; + + case 1: invokeMap.put(key, new RemoveProcessor(62)); break; + + case 2: invokeMap.put(key, new ArgumentsSumProcessor()); break; + + case 3: invokeMap.put(key, new ExceptionProcessor(62)); break; + + default: + fail(); + } + } + + resMap = cache.invokeAll(invokeMap, 10, 20, 30); + + if (tx != null) + tx.commit(); + + for (Integer key : keys) { + final EntryProcessorResult res = resMap.get(key); + + switch (key % 4) { + case 0: { + assertNotNull("No result for " + key); + + assertEquals(62, (int)res.get()); + + checkValue(key, 63); + + break; + } + + case 1: { + assertNull(res); + + checkValue(key, null); + + break; + } + + case 2: { + assertNotNull("No result for " + key); + + assertEquals(3, (int)res.get()); + + checkValue(key, 122); + + break; + } + + case 3: { + assertNotNull("No result for " + key); + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + res.get(); + + return null; + } + }, EntryProcessorException.class, "Test processor exception."); + + checkValue(key, 62); + + break; + } + } + } + + cache.invokeAll(keys, new IncrementProcessor()); + + tx = startTx(txMode); + + resMap = cache.invokeAll(keys, new RemoveProcessor(null)); + + if (tx != null) + tx.commit(); + + assertEquals("Unexpected results: " + resMap, 0, resMap.size()); + + for (Integer key : keys) + checkValue(key, null); + + IgniteCache asyncCache = cache.enableAsync(); + + assertTrue(asyncCache.isAsync()); + + assertNull(asyncCache.invokeAll(keys, new IncrementProcessor())); + + IgniteFuture>> fut = asyncCache.future(); + + resMap = fut.get(); + + exp = new HashMap<>(); + + for (Integer key : keys) + exp.put(key, -1); + + checkResult(resMap, exp); + + for (Integer key : keys) + checkValue(key, 1); + + invokeMap = new HashMap<>(); + + for (Integer key : keys) + invokeMap.put(key, incProcessor); + + assertNull(asyncCache.invokeAll(invokeMap)); + + fut = asyncCache.future(); + + resMap = fut.get(); + + for (Integer key : keys) + exp.put(key, 1); + + checkResult(resMap, exp); + + for (Integer key : keys) + checkValue(key, 2); + } + + /** + * @param resMap Result map. + * @param exp Expected results. + */ + private void checkResult(Map> resMap, Map exp) { + assertNotNull(resMap); + + assertEquals(exp.size(), resMap.size()); + + for (Map.Entry expVal : exp.entrySet()) { + EntryProcessorResult res = resMap.get(expVal.getKey()); + + assertNotNull("No result for " + expVal.getKey()); + + assertEquals("Unexpected result for " + expVal.getKey(), res.get(), expVal.getValue()); + } + } + + /** + * @param key Key. + * @param expVal Expected value. + */ + protected void checkValue(Object key, @Nullable Object expVal) { + if (expVal != null) { + for (int i = 0; i < gridCount(); i++) { + IgniteCache cache = jcache(i); + + Object val = cache.localPeek(key); + + if (val == null) + assertFalse(cache(0).affinity().isPrimaryOrBackup(ignite(i).cluster().localNode(), key)); + else + assertEquals("Unexpected value for grid " + i, expVal, val); + } + } + else { + for (int i = 0; i < gridCount(); i++) { + IgniteCache cache = jcache(i); + + assertNull("Unexpected non null value for grid " + i, cache.localPeek(key)); + } + } + } + + /** + * @return Test keys. + * @throws Exception If failed. + */ + protected Collection keys() throws Exception { + GridCache cache = cache(0); + + ArrayList keys = new ArrayList<>(); + + keys.add(primaryKeys(cache, 1, lastKey).get(0)); + + if (gridCount() > 1) { + keys.add(backupKeys(cache, 1, lastKey).get(0)); + + if (cache.configuration().getCacheMode() != REPLICATED) + keys.add(nearKeys(cache, 1, lastKey).get(0)); + } + + lastKey = Collections.max(keys) + 1; + + return keys; + } + + /** + * @param txMode Transaction concurrency mode. + * @return Transaction. + */ + @Nullable private IgniteTx startTx(@Nullable IgniteTxConcurrency txMode) { + return txMode == null ? null : ignite(0).transactions().txStart(txMode, REPEATABLE_READ); + } + + /** + * + */ + private static class ArgumentsSumProcessor implements EntryProcessor { + /** {@inheritDoc} */ + @Override public Integer process(MutableEntry e, Object... args) + throws EntryProcessorException { + assertEquals(3, args.length); + assertEquals(10, args[0]); + assertEquals(20, args[1]); + assertEquals(30, args[2]); + + assertTrue(e.exists()); + + Integer res = e.getValue(); + + for (Object arg : args) + res += (Integer)arg; + + e.setValue(res); + + return args.length; + } + } + + /** + * + */ + protected static class ToStringProcessor implements EntryProcessor { + /** {@inheritDoc} */ + @Override public String process(MutableEntry e, Object... arguments) + throws EntryProcessorException { + return String.valueOf(e.getValue()); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(ToStringProcessor.class, this); + } + } + + /** + * + */ + protected static class IncrementProcessor implements EntryProcessor { + /** {@inheritDoc} */ + @Override public Integer process(MutableEntry e, + Object... arguments) throws EntryProcessorException { + if (e.exists()) { + Integer val = e.getValue(); + + assertNotNull(val); + + e.setValue(val + 1); + + assertTrue(e.exists()); + + assertEquals(val + 1, (int) e.getValue()); + + return val; + } + else { + e.setValue(1); + + return -1; + } + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(IncrementProcessor.class, this); + } + } + + /** + * + */ + private static class RemoveProcessor implements EntryProcessor { + /** */ + private Integer expVal; + + /** + * @param expVal Expected value. + */ + RemoveProcessor(@Nullable Integer expVal) { + this.expVal = expVal; + } + + /** {@inheritDoc} */ + @Override public Integer process(MutableEntry e, + Object... arguments) throws EntryProcessorException { + assertTrue(e.exists()); + + if (expVal != null) + assertEquals(expVal, e.getValue()); + + e.remove(); + + assertFalse(e.exists()); + + return null; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(RemoveProcessor.class, this); + } + } + + /** + * + */ + private static class ExceptionProcessor implements EntryProcessor { + /** */ + private Integer expVal; + + /** + * @param expVal Expected value. + */ + ExceptionProcessor(@Nullable Integer expVal) { + this.expVal = expVal; + } + + /** {@inheritDoc} */ + @Override public Integer process(MutableEntry e, + Object... arguments) throws EntryProcessorException { + assertTrue(e.exists()); + + if (expVal != null) + assertEquals(expVal, e.getValue()); + + throw new EntryProcessorException("Test processor exception."); + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(ExceptionProcessor.class, this); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxInvokeTest.java new file mode 100644 index 0000000..aaa2a21 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxInvokeTest.java @@ -0,0 +1,41 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public class IgniteCacheTxInvokeTest extends IgniteCacheInvokeAbstractTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 3; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return PARTITIONED; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxLocalInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxLocalInvokeTest.java new file mode 100644 index 0000000..20576ab --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxLocalInvokeTest.java @@ -0,0 +1,41 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; +import static org.gridgain.grid.cache.GridCacheMode.*; + +/** + * + */ +public class IgniteCacheTxLocalInvokeTest extends IgniteCacheInvokeAbstractTest { + /** {@inheritDoc} */ + @Override protected int gridCount() { + return 1; + } + + /** {@inheritDoc} */ + @Override protected GridCacheMode cacheMode() { + return LOCAL; + } + + /** {@inheritDoc} */ + @Override protected GridCacheAtomicityMode atomicityMode() { + return TRANSACTIONAL; + } + + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return PARTITIONED_ONLY; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxNearEnabledInvokeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxNearEnabledInvokeTest.java new file mode 100644 index 0000000..ffc50ff --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheTxNearEnabledInvokeTest.java @@ -0,0 +1,24 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.internal.processors.cache; + +import org.gridgain.grid.cache.*; + +import static org.gridgain.grid.cache.GridCacheDistributionMode.*; + +/** + * + */ +public class IgniteCacheTxNearEnabledInvokeTest extends IgniteCacheTxInvokeTest { + /** {@inheritDoc} */ + @Override protected GridCacheDistributionMode distributionMode() { + return NEAR_PARTITIONED; + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyAbstractTest.java index a57da71..0d3b54f 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/expiry/IgniteCacheExpiryPolicyAbstractTest.java @@ -363,12 +363,7 @@ public abstract class IgniteCacheExpiryPolicyAbstractTest extends IgniteCacheAbs createUpdatePutAll(null); if (atomicityMode() == TRANSACTIONAL) { - IgniteTxConcurrency[] txModes; - - if (cacheMode() == LOCAL) - txModes= new IgniteTxConcurrency[]{PESSIMISTIC}; - else - txModes= new IgniteTxConcurrency[]{PESSIMISTIC, OPTIMISTIC}; + IgniteTxConcurrency[] txModes = new IgniteTxConcurrency[]{PESSIMISTIC, OPTIMISTIC}; for (IgniteTxConcurrency tx : txModes) { for (final Integer key : keys()) { diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java index 2ffc327..54397cc 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java @@ -25,6 +25,7 @@ import org.gridgain.testframework.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -42,17 +43,29 @@ import static org.gridgain.testframework.GridTestUtils.*; * Full API cache test. */ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstractSelfTest { - /** Increment closure for transform operations. */ - public static final IgniteClosure INCR_CLOS = new IgniteClosure() { - @Override public Integer apply(Integer old) { - return old == null ? 1 : old + 1; + /** Increment processor for invoke operations. */ + public static final EntryProcessor INCR_PROCESSOR = new EntryProcessor() { + @Override public String process(MutableEntry e, Object... args) { + assertNotNull(e.getKey()); + + Integer old = e.getValue(); + + e.setValue(old == null ? 1 : old + 1); + + return String.valueOf(old); } }; - /** Remove closure for transform operations. */ - public static final IgniteClosure RMV_CLOS = new IgniteClosure() { - @Override public Integer apply(Integer e) { - return null; + /** Increment processor for invoke operations. */ + public static final EntryProcessor RMV_PROCESSOR = new EntryProcessor() { + @Override public String process(MutableEntry e, Object... args) { + assertNotNull(e.getKey()); + + Integer old = e.getValue(); + + e.remove(); + + return String.valueOf(old); } }; @@ -772,18 +785,17 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract * @throws Exception If failed. */ private void checkTransform(IgniteTxConcurrency concurrency, IgniteTxIsolation isolation) throws Exception { - GridCacheProjection cache = cache(); + IgniteCache cache = jcache(); cache.put("key2", 1); cache.put("key3", 3); - - IgniteTx tx = txEnabled() ? cache.txStart(concurrency, isolation) : null; + IgniteTx tx = txEnabled() ? ignite(0).transactions().txStart(concurrency, isolation) : null; try { - cache.transform("key1", INCR_CLOS); - cache.transform("key2", INCR_CLOS); - cache.transform("key3", RMV_CLOS); + assertEquals("null", cache.invoke("key1", INCR_PROCESSOR)); + assertEquals("1", cache.invoke("key2", INCR_PROCESSOR)); + assertEquals("3", cache.invoke("key3", RMV_PROCESSOR)); if (tx != null) tx.commit(); @@ -809,9 +821,9 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract cache.put("key2", 1); cache.put("key3", 3); - cache.transform("key1", INCR_CLOS); - cache.transform("key2", INCR_CLOS); - cache.transform("key3", RMV_CLOS); + assertEquals("null", cache.invoke("key1", INCR_PROCESSOR)); + assertEquals("1", cache.invoke("key2", INCR_PROCESSOR)); + assertEquals("3", cache.invoke("key3", RMV_PROCESSOR)); assertEquals((Integer)1, cache.get("key1")); assertEquals((Integer)2, cache.get("key2")); @@ -856,25 +868,36 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract */ private void checkTransformAll(IgniteTxConcurrency concurrency, IgniteTxIsolation isolation) throws Exception { - GridCacheProjection cache = cache(); + final IgniteCache cache = jcache(); cache.put("key2", 1); cache.put("key3", 3); if (txEnabled()) { - CU.inTx(cache, concurrency, isolation, new CIX1>() { - @Override - public void applyx(GridCacheProjection c) throws IgniteCheckedException { - c.transformAll(F.asSet("key1", "key2", "key3"), INCR_CLOS); - } - }); + Map> res; + + try (IgniteTx tx = ignite(0).transactions().txStart(concurrency, isolation)) { + res = cache.invokeAll(F.asSet("key1", "key2", "key3"), INCR_PROCESSOR); + + tx.commit(); + } assertEquals((Integer)1, cache.get("key1")); assertEquals((Integer)2, cache.get("key2")); assertEquals((Integer)4, cache.get("key3")); + + assertEquals("null", res.get("key1").get()); + assertEquals("1", res.get("key2").get()); + assertEquals("3", res.get("key3").get()); + + assertEquals(3, res.size()); + + cache.remove("key1"); + cache.put("key2", 1); + cache.put("key3", 3); } - cache.transformAll(F.asSet("key1", "key2", "key3"), RMV_CLOS); + Map> res = cache.invokeAll(F.asSet("key1", "key2", "key3"), RMV_PROCESSOR); for (int i = 0; i < gridCount(); i++) { assertNull(cache(i).peek("key1")); @@ -882,24 +905,66 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract assertNull(cache(i).peek("key3")); } + assertEquals("null", res.get("key1").get()); + assertEquals("1", res.get("key2").get()); + assertEquals("3", res.get("key3").get()); + + assertEquals(3, res.size()); + cache.remove("key1"); cache.put("key2", 1); cache.put("key3", 3); - cache.transformAll(F.asMap("key1", INCR_CLOS, "key2", INCR_CLOS, "key3", INCR_CLOS)); + res = cache.invokeAll(F.asSet("key1", "key2", "key3"), INCR_PROCESSOR); assertEquals((Integer)1, cache.get("key1")); assertEquals((Integer)2, cache.get("key2")); assertEquals((Integer)4, cache.get("key3")); + + assertEquals("null", res.get("key1").get()); + assertEquals("1", res.get("key2").get()); + assertEquals("3", res.get("key3").get()); + + assertEquals(3, res.size()); + + cache.remove("key1"); + cache.put("key2", 1); + cache.put("key3", 3); + + res = cache.invokeAll(F.asMap("key1", INCR_PROCESSOR, "key2", INCR_PROCESSOR, "key3", INCR_PROCESSOR)); + + assertEquals((Integer)1, cache.get("key1")); + assertEquals((Integer)2, cache.get("key2")); + assertEquals((Integer)4, cache.get("key3")); + + assertEquals("null", res.get("key1").get()); + assertEquals("1", res.get("key2").get()); + assertEquals("3", res.get("key3").get()); + + assertEquals(3, res.size()); } /** * @throws Exception If failed. */ public void testTransformAllWithNulls() throws Exception { - final GridCacheProjection cache = cache(); + final IgniteCache cache = jcache(); + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + cache.invokeAll((Set)null, INCR_PROCESSOR); - cache.transformAll(null); // This should be no-op. + return null; + } + }, NullPointerException.class, null); + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + cache.invokeAll(F.asSet("key1"), null); + + return null; + } + }, NullPointerException.class, null); { Map m = new HashMap<>(2); @@ -913,38 +978,14 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract } { - Map> tm = new HashMap<>(2); + Set keys = new HashSet<>(2); - tm.put("key1", INCR_CLOS); - tm.put(null, INCR_CLOS); - - // WARN: F.asMap() doesn't work here, because it will throw NPE. - - cache.transformAll(tm); - } - - { - Map> tm = new HashMap<>(2); - - tm.put("key1", INCR_CLOS); - tm.put("key2", null); - - // WARN: F.asMap() doesn't work here, because it will throw NPE. - - cache.transformAll(tm); - } - - cache.transformAll(null, INCR_CLOS); // This should be no-op. - - { - Set ts = new HashSet<>(3); - - ts.add("key1"); - ts.add(null); + keys.add("key1"); + keys.add(null); // WARN: F.asSet() doesn't work here, because it will throw NPE. - cache.transformAll(ts, INCR_CLOS); + cache.invokeAll(keys, INCR_PROCESSOR); } } @@ -983,17 +1024,17 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract */ private void checkTransformSequential0(boolean startVal, IgniteTxConcurrency concurrency) throws Exception { - GridCacheProjection cache = cache(); + IgniteCache cache = jcache(); - IgniteTx tx = txEnabled() ? cache.txStart(concurrency, READ_COMMITTED) : null; + IgniteTx tx = txEnabled() ? ignite(0).transactions().txStart(concurrency, READ_COMMITTED) : null; try { if (startVal) cache.put("key", 2); - cache.transform("key", INCR_CLOS); - cache.transform("key", INCR_CLOS); - cache.transform("key", INCR_CLOS); + cache.invoke("key", INCR_PROCESSOR); + cache.invoke("key", INCR_PROCESSOR); + cache.invoke("key", INCR_PROCESSOR); if (tx != null) tx.commit(); @@ -1032,18 +1073,18 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract * @throws Exception If failed. */ private void checkTransformAfterRemove(IgniteTxConcurrency concurrency) throws Exception { - GridCacheProjection cache = cache(); + IgniteCache cache = jcache(); cache.put("key", 4); - IgniteTx tx = txEnabled() ? cache.txStart(concurrency, READ_COMMITTED) : null; + IgniteTx tx = txEnabled() ? ignite(0).transactions().txStart(concurrency, READ_COMMITTED) : null; try { cache.remove("key"); - cache.transform("key", INCR_CLOS); - cache.transform("key", INCR_CLOS); - cache.transform("key", INCR_CLOS); + cache.invoke("key", INCR_PROCESSOR); + cache.invoke("key", INCR_PROCESSOR); + cache.invoke("key", INCR_PROCESSOR); if (tx != null) tx.commit(); @@ -1097,20 +1138,23 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract * @param isolation Isolation. * @throws Exception If failed. */ - private void checkTransformReturnValue(boolean put, IgniteTxConcurrency concurrency, - IgniteTxIsolation isolation) throws Exception { - GridCacheProjection cache = cache(); + private void checkTransformReturnValue(boolean put, + IgniteTxConcurrency concurrency, + IgniteTxIsolation isolation) + throws Exception + { + IgniteCache cache = jcache(); if (!put) cache.put("key", 1); - IgniteTx tx = txEnabled() ? cache.txStart(concurrency, isolation) : null; + IgniteTx tx = txEnabled() ? ignite(0).transactions().txStart(concurrency, isolation) : null; try { if (put) cache.put("key", 1); - cache.transform("key", INCR_CLOS); + cache.invoke("key", INCR_PROCESSOR); assertEquals((Integer)2, cache.get("key")); @@ -1180,33 +1224,25 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract /** * @throws Exception If failed. */ - public void testTransformEntry() throws Exception { - GridCacheEntry entry = cache().entry("test"); + public void testInvokeAsync() throws Exception { + IgniteCache cache = jcache(); - entry.setValue(1); + cache.put("key2", 1); + cache.put("key3", 3); - // Make user entry capture cache entry. - entry.version(); + cache = cache.enableAsync(); - assertEquals((Integer)1, entry.getValue()); + assertNull(cache.invoke("key1", INCR_PROCESSOR)); - entry.transform(INCR_CLOS); + IgniteFuture fut0 = cache.future(); - assertEquals((Integer)2, entry.getValue()); - } + assertNull(cache.invoke("key2", INCR_PROCESSOR)); - /** - * @throws Exception If failed. - */ - public void testTransformAsync() throws Exception { - GridCacheProjection cache = cache(); + IgniteFuture fut1 = cache.future(); - cache.put("key2", 1); - cache.put("key3", 3); + assertNull(cache.invoke("key3", RMV_PROCESSOR)); - IgniteFuture fut0 = cache.transformAsync("key1", INCR_CLOS); - IgniteFuture fut1 = cache.transformAsync("key2", INCR_CLOS); - IgniteFuture fut2 = cache.transformAsync("key3", RMV_CLOS); + IgniteFuture fut2 = cache.future(); fut0.get(); fut1.get(); @@ -1223,46 +1259,54 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract /** * @throws Exception If failed. */ - public void testTransformCompute() throws Exception { - GridCacheProjection cache = cache(); - - IgniteClosure> c; + public void testInvoke() throws Exception { + final IgniteCache cache = jcache(); - c = new IgniteClosure>() { - @Override public IgniteBiTuple apply(Integer val) { - return val == null ? new IgniteBiTuple<>(0, "null") : new IgniteBiTuple<>(val + 1, String.valueOf(val)); - } - }; - - assertEquals("null", cache.transformAndCompute("k0", c)); + assertEquals("null", cache.invoke("k0", INCR_PROCESSOR)); - assertEquals((Integer)0, cache.get("k0")); + assertEquals((Integer)1, cache.get("k0")); - assertEquals("0", cache.transformAndCompute("k0", c)); + assertEquals("1", cache.invoke("k0", INCR_PROCESSOR)); - assertEquals((Integer)1, cache.get("k0")); + assertEquals((Integer)2, cache.get("k0")); cache.put("k1", 1); - assertEquals("1", cache.transformAndCompute("k1", c)); + assertEquals("1", cache.invoke("k1", INCR_PROCESSOR)); assertEquals((Integer)2, cache.get("k1")); - assertEquals("2", cache.transformAndCompute("k1", c)); + assertEquals("2", cache.invoke("k1", INCR_PROCESSOR)); assertEquals((Integer)3, cache.get("k1")); - c = new IgniteClosure>() { - @Override public IgniteBiTuple apply(Integer integer) { - return new IgniteBiTuple<>(null, null); + EntryProcessor c = new EntryProcessor() { + @Override public Integer process(MutableEntry e, Object... args) { + e.remove(); + + return null; } }; - assertNull(cache.transformAndCompute("k1", c)); + assertNull(cache.invoke("k1", c)); assertNull(cache.get("k1")); for (int i = 0; i < gridCount(); i++) assertNull(cache(i).peek("k1")); + + final EntryProcessor errProcessor = new EntryProcessor() { + @Override public Integer process(MutableEntry e, Object... args) { + throw new EntryProcessorException("Test entry processor exception."); + } + }; + + GridTestUtils.assertThrows(log, new Callable() { + @Override public Void call() throws Exception { + cache.invoke("k1", errProcessor); + + return null; + } + }, EntryProcessorException.class, "Test entry processor exception."); } /** diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractSelfTest.java index 314df0b..b4cd689 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractSelfTest.java @@ -348,6 +348,21 @@ public abstract class GridCacheAbstractSelfTest extends GridCommonAbstractTest { } /** + * @return Default cache instance. + */ + protected IgniteCache jcache() { + return jcache(0); + } + + /** + * @param idx Index of grid. + * @return Default cache. + */ + protected IgniteCache jcache(int idx) { + return ignite(idx).jcache(null); + } + + /** * @param idx Index of grid. * @return Cache context. */ diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheGetAndTransformStoreAbstractTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheGetAndTransformStoreAbstractTest.java index 8a929bf..c204e00 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheGetAndTransformStoreAbstractTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheGetAndTransformStoreAbstractTest.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; @@ -17,6 +18,8 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; +import java.io.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -108,19 +111,21 @@ public abstract class GridCacheGetAndTransformStoreAbstractTest extends GridComm startGrid(1); startGrid(2); - final IgniteClosure trans = new TransformClosure(); + final Processor entryProcessor = new Processor(); IgniteFuture fut = multithreadedAsync( new Callable() { @Override public Object call() throws Exception { - GridCache c = cache(ThreadLocalRandom.current().nextInt(3)); + IgniteCache c = jcache(ThreadLocalRandom.current().nextInt(3)); while (!finish.get() && !Thread.currentThread().isInterrupted()) { c.get(ThreadLocalRandom.current().nextInt(100)); + c.put(ThreadLocalRandom.current().nextInt(100), "s"); - c.transform( + + c.invoke( ThreadLocalRandom.current().nextInt(100), - trans); + entryProcessor); } return null; @@ -147,10 +152,12 @@ public abstract class GridCacheGetAndTransformStoreAbstractTest extends GridComm /** * */ - private static class TransformClosure implements IgniteClosure { + private static class Processor implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public String apply(String s) { - return "str"; + @Override public Void process(MutableEntry e, Object... args) { + e.setValue("str"); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheIncrementTransformTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheIncrementTransformTest.java index 44b8618..0e8602c 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheIncrementTransformTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheIncrementTransformTest.java @@ -10,16 +10,17 @@ package org.gridgain.grid.kernal.processors.cache; import org.apache.ignite.*; +import org.apache.ignite.cache.*; import org.apache.ignite.configuration.*; import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; import org.apache.ignite.spi.discovery.tcp.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; -import org.gridgain.grid.util.typedef.*; import org.gridgain.testframework.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; import java.util.concurrent.atomic.*; @@ -162,7 +163,7 @@ public class GridCacheIncrementTransformTest extends GridCommonAbstractTest { ignite = restarts ? grids.getAndSet(idx, null) : grid(idx); } - GridCache cache = ignite.cache(null); + IgniteCache cache = ignite.jcache(null); assertNotNull(cache); @@ -173,11 +174,11 @@ public class GridCacheIncrementTransformTest extends GridCommonAbstractTest { while (true) { try { - cache.transform("key", new Transformer()); + cache.invoke("key", new Processor()); break; } - catch (GridCachePartialUpdateException ignored) { + catch (CachePartialUpdateException ignored) { // Need to re-check if update actually succeeded. TestObject updated = cache.get("key"); @@ -210,12 +211,16 @@ public class GridCacheIncrementTransformTest extends GridCommonAbstractTest { } /** */ - private static class Transformer implements C1 { + private static class Processor implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public TestObject apply(TestObject obj) { + @Override public Void process(MutableEntry e, Object... args) { + TestObject obj = e.getValue(); + assert obj != null; - return new TestObject(obj.val + 1); + e.setValue(new TestObject(obj.val + 1)); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheInterceptorAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheInterceptorAbstractSelfTest.java index b42406d..3f3d3a6 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheInterceptorAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheInterceptorAbstractSelfTest.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; import org.apache.ignite.lang.*; import org.apache.ignite.transactions.*; @@ -18,6 +19,7 @@ import org.gridgain.grid.util.typedef.*; import org.jdk8.backport.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.atomic.*; @@ -1172,26 +1174,26 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst private void cacheUpdate(int grid, boolean rmv, Operation op, String key, final Integer val, @Nullable final Integer expOld, @Nullable final Integer expRmvRet) throws Exception { - GridCache cache = cache(grid); + IgniteCache cache = jcache(grid); if (rmv) { assertNull(val); switch (op) { case UPDATE: { - assertEquals(expRmvRet, cache.remove(key)); + assertEquals(expRmvRet, cache.getAndRemove(key)); break; } case UPDATEX: { - cache.removex(key); + cache.remove(key); break; } case UPDATE_FILTER: { - Object old = cache.remove(key, new IgnitePredicate>() { + Object old = cache.getAndRemoveIf(key, new IgnitePredicate>() { @Override public boolean apply(GridCacheEntry entry) { return true; } @@ -1203,10 +1205,14 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst } case TRANSFORM: { - cache.transform(key, new IgniteClosure() { - @Nullable @Override public Integer apply(Integer old) { + cache.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer old = e.getValue(); + assertEquals(expOld, old); + e.remove(); + return null; } }); @@ -1221,19 +1227,19 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst else { switch (op) { case UPDATE: { - assertEquals(expOld, cache.put(key, val)); + assertEquals(expOld, cache.getAndPut(key, val)); break; } case UPDATEX: { - cache.putx(key, val); + cache.put(key, val); break; } case UPDATE_FILTER: { - Object old = cache.put(key, val, new P1>() { + Object old = cache.getAndPutIf(key, val, new P1>() { @Override public boolean apply(GridCacheEntry entry) { return true; } @@ -1245,11 +1251,15 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst } case TRANSFORM: { - cache.transform(key, new IgniteClosure() { - @Override public Integer apply(Integer old) { + cache.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer old = e.getValue(); + assertEquals(expOld, old); - return val; + e.setValue(val); + + return null; } }); @@ -1294,7 +1304,7 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst @SuppressWarnings("unchecked") private void cacheBatchUpdate(int grid, boolean rmv, Operation op, final Map map) throws Exception { - GridCache cache = cache(grid); + IgniteCache cache = jcache(grid); if (rmv) { switch (op) { @@ -1305,8 +1315,10 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst } case TRANSFORM: { - cache.transformAll(map.keySet(), new IgniteClosure() { - @Nullable @Override public Integer apply(Integer old) { + cache.invokeAll(map.keySet(), new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + e.remove(); + return null; } }); @@ -1327,17 +1339,13 @@ public abstract class GridCacheInterceptorAbstractSelfTest extends GridCacheAbst } case TRANSFORM: { - Map> m = new HashMap<>(); - - for (final String key : map.keySet()) { - m.put(key, new IgniteClosure() { - @Override public Integer apply(Integer old) { - return map.get(key); - } - }); - } + cache.invokeAll(map.keySet(), new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(map.get(e.getKey())); - cache.transformAll(m); + return null; + } + }); break; } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheMultinodeUpdateAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheMultinodeUpdateAbstractSelfTest.java index 844fc5c..3c2d32c 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheMultinodeUpdateAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheMultinodeUpdateAbstractSelfTest.java @@ -9,12 +9,14 @@ package org.gridgain.grid.kernal.processors.cache; -import org.apache.ignite.lang.*; +import org.apache.ignite.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.cache.store.*; import org.gridgain.testframework.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; +import java.io.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -51,8 +53,8 @@ public abstract class GridCacheMultinodeUpdateAbstractSelfTest extends GridCache /** * @throws Exception If failed. */ - public void testTransform() throws Exception { - GridCache cache = grid(0).cache(null); + public void testInvoke() throws Exception { + IgniteCache cache = grid(0).jcache(null); final Integer key = primaryKey(cache); @@ -72,16 +74,16 @@ public abstract class GridCacheMultinodeUpdateAbstractSelfTest extends GridCache @Override public Void call() throws Exception { int idx = gridIdx.incrementAndGet() - 1; - final GridCache cache = grid(idx).cache(null); + final IgniteCache cache = grid(idx).jcache(null); for (int i = 0; i < ITERATIONS_PER_THREAD && !failed; i++) - cache.transform(key, new IncClosure()); + cache.invoke(key, new IncProcessor()); return null; } - }, THREADS, "transform"); + }, THREADS, "invoke"); - assertFalse("Got null in transform.", failed); + assertFalse("Got null in processor.", failed); expVal += ITERATIONS_PER_THREAD * THREADS; @@ -103,18 +105,22 @@ public abstract class GridCacheMultinodeUpdateAbstractSelfTest extends GridCache /** * */ - protected static class IncClosure implements IgniteClosure { + protected static class IncProcessor implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public Integer apply(Integer val) { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); + if (val == null) { failed = true; - System.out.println(Thread.currentThread() + " got null in transform: " + val); + System.out.println(Thread.currentThread() + " got null in processor: " + val); return null; } - return val + 1; + e.setValue(val + 1); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest.java index e1f5c5a..5a97b7f 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest.java @@ -9,10 +9,13 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; import org.gridgain.testframework.*; +import javax.cache.processor.*; +import java.io.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -76,7 +79,7 @@ public abstract class GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest extend * @throws Exception If failed. */ private void testTransform(final Integer key) throws Exception { - final GridCache cache = grid(0).cache(null); + final IgniteCache cache = grid(0).jcache(null); cache.put(key, 0); @@ -89,7 +92,7 @@ public abstract class GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest extend if (i % 500 == 0) log.info("Iteration " + i); - cache.transform(key, new IncClosure()); + cache.invoke(key, new IncProcessor()); } return null; @@ -339,23 +342,29 @@ public abstract class GridCacheOffHeapMultiThreadedUpdateAbstractSelfTest extend } /** + * */ - protected static class IncClosure implements IgniteClosure { + protected static class IncProcessor implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public Integer apply(Integer val) { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); + if (val == null) { failed = true; - System.out.println(Thread.currentThread() + " got null in transform: " + val); + System.out.println(Thread.currentThread() + " got null in processor: " + val); return null; } - return val + 1; + e.setValue(val + 1); + + return null; } } /** + * */ protected static class TestFilter implements IgnitePredicate> { /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateSelfTest.java index f84e9c7..baa03c2 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapMultiThreadedUpdateSelfTest.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.transactions.*; import org.gridgain.grid.cache.*; import org.gridgain.testframework.*; @@ -48,7 +49,7 @@ public class GridCacheOffHeapMultiThreadedUpdateSelfTest extends GridCacheOffHea * @throws Exception If failed. */ private void testTransformTx(final Integer key, final IgniteTxConcurrency txConcurrency) throws Exception { - final GridCache cache = grid(0).cache(null); + final IgniteCache cache = grid(0).jcache(null); cache.put(key, 0); @@ -57,12 +58,14 @@ public class GridCacheOffHeapMultiThreadedUpdateSelfTest extends GridCacheOffHea GridTestUtils.runMultiThreaded(new Callable() { @Override public Void call() throws Exception { + IgniteTransactions txs = ignite(0).transactions(); + for (int i = 0; i < ITERATIONS_PER_THREAD && !failed; i++) { if (i % 500 == 0) log.info("Iteration " + i); - try (IgniteTx tx = cache.txStart(txConcurrency, REPEATABLE_READ)) { - cache.transform(key, new IncClosure()); + try (IgniteTx tx = txs.txStart(txConcurrency, REPEATABLE_READ)) { + cache.invoke(key, new IncProcessor()); tx.commit(); } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredAbstractSelfTest.java index 4456346..7e8daf8 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredAbstractSelfTest.java @@ -9,6 +9,7 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; import org.apache.ignite.lang.*; import org.apache.ignite.portables.*; @@ -18,6 +19,7 @@ import org.gridgain.grid.util.typedef.*; import org.jetbrains.annotations.*; import org.junit.*; +import javax.cache.processor.*; import java.util.*; import static org.gridgain.grid.cache.GridCacheAtomicWriteOrderMode.*; @@ -92,48 +94,61 @@ public abstract class GridCacheOffHeapTieredAbstractSelfTest extends GridCacheAb * @throws Exception If failed. */ private void checkTransform(Integer key) throws Exception { - GridCache c = grid(0).cache(null); + IgniteCache c = grid(0).jcache(null); + + c.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); - c.transform(key, new C1() { - @Override public Integer apply(Integer val) { assertNull("Unexpected value: " + val, val); return null; } }); - c.putx(key, 1); + c.put(key, 1); + + c.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); - c.transform(key, new C1() { - @Override public Integer apply(Integer val) { assertNotNull("Unexpected value: " + val, val); assertEquals((Integer) 1, val); - return val + 1; + e.setValue(val + 1); + + return null; } }); assertEquals((Integer)2, c.get(key)); - c.transform(key, new C1() { - @Override public Integer apply(Integer val) { + c.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); + assertNotNull("Unexpected value: " + val, val); assertEquals((Integer)2, val); - return val; + e.setValue(val); + + return null; } }); - assertEquals((Integer) 2, c.get(key)); + assertEquals((Integer)2, c.get(key)); + + c.invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); - c.transform(key, new C1() { - @Override - public Integer apply(Integer val) { assertNotNull("Unexpected value: " + val, val); - assertEquals((Integer) 2, val); + assertEquals((Integer)2, val); + + e.remove(); return null; } @@ -309,7 +324,7 @@ public abstract class GridCacheOffHeapTieredAbstractSelfTest extends GridCacheAb for (int i = 0; i < 100; i++) map.put(i, i); - GridCache c = grid(0).cache(null); + IgniteCache c = grid(0).jcache(null); Map map0 = c.getAll(map.keySet()); @@ -324,9 +339,13 @@ public abstract class GridCacheOffHeapTieredAbstractSelfTest extends GridCacheAb for (Map.Entry e : map.entrySet()) checkValue(e.getKey(), e.getValue()); - c.transformAll(map.keySet(), new C1() { - @Override public Integer apply(Integer val) { - return val + 1; + c.invokeAll(map.keySet(), new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); + + e.setValue(val + 1); + + return null; } }); diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredEvictionAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredEvictionAbstractSelfTest.java index b25fcbd..d4eb179 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredEvictionAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheOffHeapTieredEvictionAbstractSelfTest.java @@ -9,14 +9,16 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; -import org.apache.ignite.lang.*; import org.apache.ignite.portables.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.testframework.*; +import javax.cache.processor.*; +import java.io.*; import java.util.*; import java.util.concurrent.*; @@ -171,7 +173,7 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri * @throws Exception If failed. */ public void testTransform() throws Exception { - final GridCache cache = grid(0).cache(null); + final IgniteCache cache = grid(0).jcache(null); GridTestUtils.runMultiThreaded(new Callable() { @Override public Void call() throws Exception { @@ -182,9 +184,9 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri final TestValue val = vals.get(key % VAL_SIZE); - TestClosure c = testClosure(val.val, false); + TestProcessor c = testClosure(val.val, false); - cache.transform(key, c); + cache.invoke(key, c); } return null; @@ -208,7 +210,7 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri * @param acceptNull If {@code true} value can be null; * @return Predicate. */ - private TestClosure testClosure(String expVal, boolean acceptNull) { + private TestProcessor testClosure(String expVal, boolean acceptNull) { return portableEnabled() ? new PortableValueClosure(expVal, acceptNull) : new TestValueClosure(expVal, acceptNull); @@ -326,7 +328,7 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri /** * */ - protected abstract static class TestClosure implements IgniteClosure { + protected abstract static class TestProcessor implements EntryProcessor, Serializable { /** */ protected String expVal; @@ -337,23 +339,29 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri * @param expVal Expected value. * @param acceptNull If {@code true} value can be null; */ - protected TestClosure(String expVal, boolean acceptNull) { + protected TestProcessor(String expVal, boolean acceptNull) { this.expVal = expVal; this.acceptNull = acceptNull; } /** {@inheritDoc} */ - @Override public final Object apply(Object val) { + @Override public Void process(MutableEntry e, Object... args) { + Object val = e.getValue(); + if (val == null) { if (!acceptNull) assertNotNull(val); - return true; + e.setValue(true); + + return null; } checkValue(val); - return val; + e.setValue(val); + + return null; } /** @@ -366,7 +374,7 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri * */ @SuppressWarnings("PackageVisibleInnerClass") - static class PortableValueClosure extends TestClosure { + static class PortableValueClosure extends TestProcessor { /** * @param expVal Expected value. * @param acceptNull If {@code true} value can be null; @@ -387,7 +395,7 @@ public abstract class GridCacheOffHeapTieredEvictionAbstractSelfTest extends Gri * */ @SuppressWarnings("PackageVisibleInnerClass") - static class TestValueClosure extends TestClosure { + static class TestValueClosure extends TestProcessor { /** * @param expVal Expected value. * @param acceptNull If {@code true} value can be null; diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturnValueTransferSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturnValueTransferSelfTest.java index 4b88530..b65fcad 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturnValueTransferSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheReturnValueTransferSelfTest.java @@ -9,11 +9,12 @@ package org.gridgain.grid.kernal.processors.cache; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; -import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; @@ -104,6 +105,9 @@ public class GridCacheReturnValueTransferSelfTest extends GridCommonAbstractTest } /** + * @param mode Atomicity mode. + * @param order Atomic cache write order mode. + * @param b Number of backups. * @throws Exception If failed. */ private void checkTransform(GridCacheAtomicityMode mode, GridCacheAtomicWriteOrderMode order, int b) @@ -126,7 +130,7 @@ public class GridCacheReturnValueTransferSelfTest extends GridCommonAbstractTest failDeserialization = false; // Get client grid. - GridCacheProjection cache = grid(2).cache(null); + IgniteCache cache = grid(2).jcache(null); if (backups > 0 && atomicityMode == ATOMIC) cache = cache.flagsOn(FORCE_TRANSFORM_BACKUP); @@ -138,17 +142,17 @@ public class GridCacheReturnValueTransferSelfTest extends GridCommonAbstractTest info(">>>>>> Transforming"); - // Transform (check non-existent keys also. + // Transform (check non-existent keys also). for (int i = 0; i < 200; i++) - cache.transform(i, new Transform()); + cache.invoke(i, new Transform()); - Map transformMap = new HashMap<>(); + Set keys = new HashSet<>(); // Check transformAll. for (int i = 0; i < 300; i++) - transformMap.put(i, new Transform()); + keys.add(i); - cache.transformAll(transformMap); + cache.invokeAll(keys, new Transform()); // Avoid errors during stop. failDeserialization = false; @@ -158,10 +162,15 @@ public class GridCacheReturnValueTransferSelfTest extends GridCommonAbstractTest } } - private static class Transform implements IgniteClosure { + /** + * + */ + private static class Transform implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public TestObject apply(TestObject testObject) { - return new TestObject(); + @Override public Void process(MutableEntry entry, Object... args) { + entry.setValue(new TestObject()); + + return null; } } @@ -169,7 +178,11 @@ public class GridCacheReturnValueTransferSelfTest extends GridCommonAbstractTest * */ private static class TestObject implements Externalizable { + /** + * + */ public TestObject() { + // No-op. } /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheTestEntryEx.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheTestEntryEx.java index 64218d2..89c1efa 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheTestEntryEx.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheTestEntryEx.java @@ -19,6 +19,7 @@ import org.gridgain.grid.util.typedef.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.util.*; /** @@ -423,9 +424,10 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter impleme } /** {@inheritDoc} */ - @Override public IgniteBiTuple innerUpdateLocal(GridCacheVersion ver, + @Override public GridTuple3> innerUpdateLocal(GridCacheVersion ver, GridCacheOperation op, @Nullable Object writeObj, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable ExpiryPolicy expiryPlc, @@ -436,7 +438,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter impleme UUID subjId, String taskName) throws IgniteCheckedException, GridCacheEntryRemovedException { - return new IgniteBiTuple<>(false, null); + return new GridTuple3<>(false, null, null); } /** {@inheritDoc} */ @@ -447,6 +449,7 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter impleme GridCacheOperation op, @Nullable Object val, @Nullable byte[] valBytes, + @Nullable Object[] invokeArgs, boolean writeThrough, boolean retval, @Nullable IgniteCacheExpiryPolicy expiryPlc, @@ -464,7 +467,15 @@ public class GridCacheTestEntryEx extends GridMetadataAwareAdapter impleme UUID subjId, String taskName) throws IgniteCheckedException, GridCacheEntryRemovedException { - return new GridCacheUpdateAtomicResult<>(true, rawPut((V)val, 0), (V)val, 0L, 0L, null, null, true); + return new GridCacheUpdateAtomicResult<>(true, + rawPut((V)val, 0), + (V)val, + null, + 0L, + 0L, + null, + null, + true); } /** @inheritDoc */ diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxExceptionAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxExceptionAbstractSelfTest.java index 0be91f0..8cf48bf 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxExceptionAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxExceptionAbstractSelfTest.java @@ -21,6 +21,8 @@ import org.gridgain.grid.kernal.processors.cache.distributed.near.*; import org.gridgain.testframework.*; import org.jetbrains.annotations.*; +import javax.cache.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.*; @@ -417,17 +419,21 @@ public abstract class IgniteTxExceptionAbstractSelfTest extends GridCacheAbstrac info("Going to transform: " + key); - GridTestUtils.assertThrows(log, new Callable() { + Throwable e = GridTestUtils.assertThrows(log, new Callable() { @Override public Void call() throws Exception { - grid(0).cache(null).transform(key, new IgniteClosure() { - @Override public Object apply(Object o) { - return 2; + grid(0).jcache(null).invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(2); + + return null; } }); return null; } - }, IgniteTxHeuristicException.class, null); + }, CacheException.class, null); + + assertTrue("Unexpected cause: " +e, e.getCause() instanceof IgniteTxHeuristicException); checkEmpty(key); } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxStoreExceptionAbstractSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxStoreExceptionAbstractSelfTest.java index 39eb728..a46353e 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxStoreExceptionAbstractSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/IgniteTxStoreExceptionAbstractSelfTest.java @@ -21,6 +21,8 @@ import org.gridgain.grid.kernal.processors.cache.distributed.near.*; import org.gridgain.testframework.*; import org.jetbrains.annotations.*; +import javax.cache.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.*; @@ -422,17 +424,21 @@ public abstract class IgniteTxStoreExceptionAbstractSelfTest extends GridCacheAb info("Going to transform: " + key); - GridTestUtils.assertThrows(log, new Callable() { + Throwable e = GridTestUtils.assertThrows(log, new Callable() { @Override public Void call() throws Exception { - grid(0).cache(null).transform(key, new IgniteClosure() { - @Override public Object apply(Object o) { - return 2; + grid(0).jcache(null).invoke(key, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(2); + + return null; } }); return null; } - }, IgniteTxRollbackException.class, null); + }, CacheException.class, null); + + assertTrue("Unexpected cause: " + e, e.getCause() instanceof IgniteTxRollbackException); checkValue(key, putBefore); } @@ -588,41 +594,48 @@ public abstract class IgniteTxStoreExceptionAbstractSelfTest extends GridCacheAb this.fail = fail; } - + /** {@inheritDoc} */ @Nullable @Override public Object load(@Nullable IgniteTx tx, Object key) throws IgniteCheckedException { return null; } + /** {@inheritDoc} */ @Override public void loadCache(IgniteBiInClosure clo, @Nullable Object... args) throws IgniteCheckedException { if (fail) throw new IgniteCheckedException("Store exception"); } + /** {@inheritDoc} */ @Override public void loadAll(@Nullable IgniteTx tx, Collection keys, IgniteBiInClosure c) throws IgniteCheckedException { } + /** {@inheritDoc} */ @Override public void put(@Nullable IgniteTx tx, Object key, Object val) throws IgniteCheckedException { if (fail) throw new IgniteCheckedException("Store exception"); } + /** {@inheritDoc} */ @Override public void putAll(@Nullable IgniteTx tx, Map map) throws IgniteCheckedException { if (fail) throw new IgniteCheckedException("Store exception"); } + /** {@inheritDoc} */ @Override public void remove(@Nullable IgniteTx tx, Object key) throws IgniteCheckedException { if (fail) throw new IgniteCheckedException("Store exception"); } + /** {@inheritDoc} */ @Override public void removeAll(@Nullable IgniteTx tx, Collection keys) throws IgniteCheckedException { if (fail) throw new IgniteCheckedException("Store exception"); } + /** {@inheritDoc} */ @Override public void txEnd(IgniteTx tx, boolean commit) throws IgniteCheckedException { if (fail && commit) throw new IgniteCheckedException("Store exception"); diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/GridCacheTransformEventSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/GridCacheTransformEventSelfTest.java index 5c7ba54..1ced531 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/GridCacheTransformEventSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/GridCacheTransformEventSelfTest.java @@ -19,9 +19,12 @@ import org.gridgain.grid.cache.*; import org.apache.ignite.spi.discovery.tcp.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.gridgain.grid.cache.affinity.*; import org.gridgain.grid.util.typedef.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; +import java.io.*; import java.util.*; import static org.gridgain.grid.cache.GridCacheAtomicWriteOrderMode.*; @@ -68,7 +71,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { private UUID[] ids; /** Caches. */ - private GridCache[] caches; + private IgniteCache[] caches; /** Recorded events.*/ private ConcurrentHashSet evts; @@ -157,14 +160,14 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { ignites = new Ignite[GRID_CNT]; ids = new UUID[GRID_CNT]; - caches = new GridCache[GRID_CNT]; + caches = new IgniteCache[GRID_CNT]; for (int i = 0; i < GRID_CNT; i++) { ignites[i] = grid(i); ids[i] = ignites[i].cluster().localNode().id(); - caches[i] = ignites[i].cache(CACHE_NAME); + caches[i] = ignites[i].jcache(CACHE_NAME); ignites[i].events().localListen(new IgnitePredicate() { @Override public boolean apply(IgniteEvent evt) { @@ -184,7 +187,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { int key = 0; while (true) { - if (cacheMode != PARTITIONED || (caches[0].entry(key).primary() && caches[1].entry(key).backup())) { + if (cacheMode != PARTITIONED || (primary(0, key) && backup(1, key))) { key1 = key++; break; @@ -194,7 +197,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { } while (true) { - if (cacheMode != PARTITIONED || (caches[0].entry(key).primary() && caches[1].entry(key).backup())) { + if (cacheMode != PARTITIONED || (primary(0, key) && backup(1, key))) { key2 = key; break; @@ -226,6 +229,28 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { } /** + * @param gridIdx Grid index. + * @param key Key. + * @return {@code True} if grid is primary for given key. + */ + private boolean primary(int gridIdx, Object key) { + GridCacheAffinity aff = grid(0).cache(CACHE_NAME).affinity(); + + return aff.isPrimary(grid(gridIdx).cluster().localNode(), key); + } + + /** + * @param gridIdx Grid index. + * @param key Key. + * @return {@code True} if grid is primary for given key. + */ + private boolean backup(int gridIdx, Object key) { + GridCacheAffinity aff = grid(0).cache(CACHE_NAME).affinity(); + + return aff.isBackup(grid(gridIdx).cluster().localNode(), key); + } + + /** * Test TRANSACTIONAL LOCAL cache with OPTIMISTIC/REPEATABLE_READ transaction. * * @throws Exception If failed. @@ -423,13 +448,13 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { private void checkAtomic(GridCacheMode cacheMode) throws Exception { initialize(cacheMode, ATOMIC, null, null); - caches[0].transform(key1, new Transformer()); + caches[0].invoke(key1, new Transformer()); checkEventNodeIdsStrict(primaryIdsForKeys(key1)); assert evts.isEmpty(); - caches[0].transformAll(keys, new Transformer()); + caches[0].invokeAll(keys, new Transformer()); checkEventNodeIdsStrict(primaryIdsForKeys(key1, key2)); } @@ -449,7 +474,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { System.out.println("BEFORE: " + evts.size()); - caches[0].transform(key1, new Transformer()); + caches[0].invoke(key1, new Transformer()); System.out.println("AFTER: " + evts.size()); @@ -457,7 +482,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { assert evts.isEmpty(); - caches[0].transformAll(keys, new Transformer()); + caches[0].invokeAll(keys, new Transformer()); checkEventNodeIdsStrict(idsForKeys(key1, key2)); } @@ -500,9 +525,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { else if (cacheMode == PARTITIONED) { for (int key : keys) { for (int i = 0; i < GRID_CNT; i++) { - GridCacheEntry entry = caches[i].entry(key); - - if (entry.primary() || (!primaryOnly && entry.backup())) + if (primary(i, key) || (!primaryOnly && backup(i, key))) res.add(ids[i]); } } @@ -510,7 +533,7 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { else if (cacheMode == REPLICATED) { for (int key : keys) { if (primaryOnly) - res.add(caches[0].affinity().mapKeyToNode(key).id()); + res.add(grid(0).cache(CACHE_NAME).affinity().mapKeyToNode(key).id()); else res.addAll(Arrays.asList(ids)); } @@ -544,22 +567,19 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { } if (foundEvt == null) { - GridCache affectedCache = null; + int gridIdx = -1; for (int i = 0; i < GRID_CNT; i++) { if (F.eq(this.ids[i], id)) { - affectedCache = caches[i]; + gridIdx = i; break; } } - GridCacheEntry entry1 = affectedCache.entry(key1); - GridCacheEntry entry2 = affectedCache.entry(key2); - fail("Expected transform event was not triggered on the node [nodeId=" + id + - ", key1Primary=" + entry1.primary() + ", key1Backup=" + entry1.backup() + - ", key2Primary=" + entry2.primary() + ", key2Backup=" + entry2.backup() + ']'); + ", key1Primary=" + primary(gridIdx, key1) + ", key1Backup=" + backup(gridIdx, key1) + + ", key2Primary=" + primary(gridIdx, key2) + ", key2Backup=" + backup(gridIdx, key2) + ']'); } else evts.remove(foundEvt); @@ -570,10 +590,12 @@ public class GridCacheTransformEventSelfTest extends GridCommonAbstractTest { /** * Transform closure. */ - private static class Transformer implements IgniteClosure { + private static class Transformer implements EntryProcessor, Serializable { /** {@inheritDoc} */ - @Override public Integer apply(Integer val) { - return ++val; + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(e.getValue() + 1); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/IgniteTxPreloadAbstractTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/IgniteTxPreloadAbstractTest.java index 2227e56..2b1fdff 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/IgniteTxPreloadAbstractTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/IgniteTxPreloadAbstractTest.java @@ -9,14 +9,15 @@ package org.gridgain.grid.kernal.processors.cache.distributed; +import org.apache.ignite.*; import org.apache.ignite.lang.*; import org.apache.ignite.transactions.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.kernal.processors.cache.*; -import org.gridgain.grid.util.typedef.*; import org.gridgain.testframework.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -58,7 +59,7 @@ public abstract class IgniteTxPreloadAbstractTest extends GridCacheAbstractSelfT * @throws Exception If failed. */ public void testRemoteTxPreloading() throws Exception { - GridCache cache = cache(0); + IgniteCache cache = jcache(0); for (int i = 0; i < 10000; i++) cache.put(String.valueOf(i), 0); @@ -86,12 +87,21 @@ public abstract class IgniteTxPreloadAbstractTest extends GridCacheAbstractSelfT for (int i = 0; i < 10; i++) keys.add(String.valueOf(i * 1000)); - cache.transformAll(keys, new C1() { - @Override public Integer apply(Integer val) { - if (val == null) + cache.invokeAll(keys, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); + + if (val == null) { keyNotLoaded = true; - return val + 1; + e.setValue(1); + + return null; + } + + e.setValue(val + 1); + + return null; } }); @@ -135,7 +145,7 @@ public abstract class IgniteTxPreloadAbstractTest extends GridCacheAbstractSelfT for (int i = 0; i < 10000; i++) map.put(String.valueOf(i), 0); - GridCache cache0 = cache(0); + IgniteCache cache0 = jcache(0); cache0.putAll(map); @@ -148,18 +158,26 @@ public abstract class IgniteTxPreloadAbstractTest extends GridCacheAbstractSelfT startGrid(i); - GridCache cache = cache(i); + IgniteCache cache = jcache(i); + + IgniteTransactions txs = ignite(i).transactions(); + + try (IgniteTx tx = txs.txStart(txConcurrency, IgniteTxIsolation.READ_COMMITTED)) { + cache.invoke(TX_KEY, new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Integer val = e.getValue(); - try (IgniteTx tx = cache.txStart(txConcurrency, IgniteTxIsolation.READ_COMMITTED)) { - cache.transform(TX_KEY, new C1() { - @Override public Integer apply(Integer val) { if (val == null) { keyNotLoaded = true; - return 1; + e.setValue(1); + + return null; } - return val + 1; + e.setValue(val + 1); + + return null; } }); diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAbstractTransformWriteThroughSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAbstractTransformWriteThroughSelfTest.java index 5635ac8..d4d3396 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAbstractTransformWriteThroughSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAbstractTransformWriteThroughSelfTest.java @@ -9,8 +9,9 @@ package org.gridgain.grid.kernal.processors.cache.distributed.dht; +import org.apache.ignite.*; import org.apache.ignite.configuration.*; -import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.transactions.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.kernal.processors.cache.*; @@ -19,6 +20,7 @@ import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; import java.util.*; import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; @@ -55,16 +57,23 @@ public abstract class GridCacheAbstractTransformWriteThroughSelfTest extends Gri /** IP finder. */ private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); - /** Value increment closure. */ - private static final IgniteClosure INCR_CLOS = new IgniteClosure() { - @Override public Integer apply(Integer src) { - return src == null ? 1 : src + 1; + /** Value increment processor. */ + private static final EntryProcessor INCR_CLOS = new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + if (!e.exists()) + e.setValue(1); + else + e.setValue(e.getValue() + 1); + + return null; } }; - /** Value remove closure. */ - private static final IgniteClosure RMV_CLOS = new IgniteClosure() { - @Override public Integer apply(Integer src) { + /** Value remove processor. */ + private static final EntryProcessor RMV_CLOS = new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + e.remove(); + return null; } }; @@ -82,6 +91,8 @@ public abstract class GridCacheAbstractTransformWriteThroughSelfTest extends Gri @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(gridName); + cfg.setMarshaller(new IgniteOptimizedMarshaller(false)); + TcpDiscoverySpi discoSpi = new TcpDiscoverySpi(); discoSpi.setIpFinder(IP_FINDER); @@ -221,7 +232,7 @@ public abstract class GridCacheAbstractTransformWriteThroughSelfTest extends Gri * @throws Exception If failed. */ protected void checkTransform(IgniteTxConcurrency concurrency, int nodeType, int op) throws Exception { - GridCacheProjection cache = cache(0); + IgniteCache cache = jcache(0); Collection keys = keysForType(nodeType); @@ -233,18 +244,18 @@ public abstract class GridCacheAbstractTransformWriteThroughSelfTest extends Gri nearStore.reset(); for (String key : keys) - cache.clear(key); + cache(0).clear(key); info(">>> Starting transform transaction"); - try (IgniteTx tx = cache.txStart(concurrency, READ_COMMITTED)) { + try (IgniteTx tx = ignite(0).transactions().txStart(concurrency, READ_COMMITTED)) { if (op == OP_UPDATE) { for (String key : keys) - cache.transform(key, INCR_CLOS); + cache.invoke(key, INCR_CLOS); } else { for (String key : keys) - cache.transform(key, RMV_CLOS); + cache.invoke(key, RMV_CLOS); } tx.commit(); diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAtomicNearCacheSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAtomicNearCacheSelfTest.java index f84d006..ab2024a 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAtomicNearCacheSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/GridCacheAtomicNearCacheSelfTest.java @@ -11,8 +11,6 @@ package org.gridgain.grid.kernal.processors.cache.distributed.dht; import org.apache.ignite.*; import org.apache.ignite.configuration.*; -import org.apache.ignite.lang.*; -import org.gridgain.grid.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.cache.affinity.*; import org.gridgain.grid.kernal.*; @@ -23,6 +21,8 @@ import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.testframework.junits.common.*; import org.jetbrains.annotations.*; +import javax.cache.processor.*; +import java.io.*; import java.util.*; import static org.gridgain.grid.cache.GridCacheAtomicWriteOrderMode.*; @@ -255,9 +255,9 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { Ignite ignite0 = grid(0); - GridCache cache0 = ignite0.cache(null); + IgniteCache cache0 = ignite0.jcache(null); - GridCacheAffinity aff = cache0.affinity(); + GridCacheAffinity aff = cache(0).affinity(); UUID id0 = ignite0.cluster().localNode().id(); @@ -265,7 +265,7 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { log.info("Transform from primary."); - cache0.transform(primaryKey, new TransformClosure(primaryKey)); + cache0.invoke(primaryKey, new Processor(primaryKey)); for (int i = 0; i < GRID_CNT; i++) checkEntry(grid(i), primaryKey, primaryKey, false); @@ -275,7 +275,7 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { log.info("Transform from backup."); - cache0.transform(backupKey, new TransformClosure(backupKey)); + cache0.invoke(backupKey, new Processor(backupKey)); for (int i = 0; i < GRID_CNT; i++) checkEntry(grid(i), backupKey, backupKey, false); @@ -285,7 +285,7 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { log.info("Transform from near."); - cache0.transform(nearKey, new TransformClosure(nearKey)); + cache0.invoke(nearKey, new Processor(nearKey)); for (int i = 0; i < GRID_CNT; i++) { UUID[] expReaders = aff.isPrimary(grid(i).localNode(), nearKey) ? new UUID[]{id0} : new UUID[]{}; @@ -302,11 +302,11 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { for (int i = 0; i < GRID_CNT; i++) { delay(); - GridCache cache = grid(i).cache(null); + IgniteCache cache = grid(i).jcache(null); log.info("Transform [grid=" + grid(i).name() + ", val=" + val + ']'); - cache.transform(nearKey, new TransformClosure(val)); + cache.invoke(nearKey, new Processor(val)); if (!aff.isPrimaryOrBackup(grid(i).localNode(), nearKey)) readers.add(grid(i).localNode().id()); @@ -332,53 +332,53 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { Ignite ignite0 = grid(0); - GridCache cache0 = ignite0.cache(null); + IgniteCache cache0 = ignite0.jcache(null); - GridCacheAffinity aff = cache0.affinity(); + GridCacheAffinity aff = ignite0.cache(null).affinity(); UUID id0 = ignite0.cluster().localNode().id(); - Map primaryKeys = new HashMap<>(); + Set primaryKeys = new HashSet<>(); for (int i = 0; i < 10; i++) - primaryKeys.put(key(ignite0, PRIMARY), new TransformClosure(1)); + primaryKeys.add(key(ignite0, PRIMARY)); log.info("TransformAll from primary."); - cache0.transformAll(primaryKeys); + cache0.invokeAll(primaryKeys, new Processor(1)); for (int i = 0; i < GRID_CNT; i++) { - for (Integer primaryKey : primaryKeys.keySet()) + for (Integer primaryKey : primaryKeys) checkEntry(grid(i), primaryKey, 1, false); } if (backups > 0) { - Map backupKeys = new HashMap<>(); + Set backupKeys = new HashSet<>(); for (int i = 0; i < 10; i++) - backupKeys.put(key(ignite0, BACKUP), new TransformClosure(2)); + backupKeys.add(key(ignite0, BACKUP)); log.info("TransformAll from backup."); - cache0.transformAll(backupKeys); + cache0.invokeAll(backupKeys, new Processor(2)); for (int i = 0; i < GRID_CNT; i++) { - for (Integer backupKey : backupKeys.keySet()) + for (Integer backupKey : backupKeys) checkEntry(grid(i), backupKey, 2, false); } } - Map nearKeys = new HashMap<>(); + Set nearKeys = new HashSet<>(); for (int i = 0; i < 30; i++) - nearKeys.put(key(ignite0, NOT_PRIMARY_AND_BACKUP), new TransformClosure(3)); + nearKeys.add(key(ignite0, NOT_PRIMARY_AND_BACKUP)); log.info("TransformAll from near."); - cache0.transformAll(nearKeys); + cache0.invokeAll(nearKeys, new Processor(3)); for (int i = 0; i < GRID_CNT; i++) { - for (Integer nearKey : nearKeys.keySet()) { + for (Integer nearKey : nearKeys) { UUID[] expReaders = aff.isPrimary(grid(i).localNode(), nearKey) ? new UUID[]{id0} : new UUID[]{}; checkEntry(grid(i), nearKey, 3, i == 0, expReaders); @@ -387,7 +387,7 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { Map> readersMap = new HashMap<>(); - for (Integer key : nearKeys.keySet()) + for (Integer key : nearKeys) readersMap.put(key, new HashSet()); int val = 4; @@ -395,22 +395,22 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { for (int i = 0; i < GRID_CNT; i++) { delay(); - GridCache cache = grid(i).cache(null); + IgniteCache cache = grid(i).jcache(null); - for (Integer key : nearKeys.keySet()) - nearKeys.put(key, new TransformClosure(val)); + for (Integer key : nearKeys) + nearKeys.add(key); log.info("TransformAll [grid=" + grid(i).name() + ", val=" + val + ']'); - cache.transformAll(nearKeys); + cache.invokeAll(nearKeys, new Processor(val)); - for (Integer key : nearKeys.keySet()) { + for (Integer key : nearKeys) { if (!aff.isPrimaryOrBackup(grid(i).localNode(), key)) readersMap.get(key).add(grid(i).localNode().id()); } for (int j = 0; j < GRID_CNT; j++) { - for (Integer key : nearKeys.keySet()) { + for (Integer key : nearKeys) { boolean primaryNode = aff.isPrimary(grid(j).localNode(), key); Collection readers = readersMap.get(key); @@ -789,21 +789,23 @@ public class GridCacheAtomicNearCacheSelfTest extends GridCommonAbstractTest { } /** + * */ - private static class TransformClosure implements IgniteClosure { + private static class Processor implements EntryProcessor, Serializable { /** */ private final Integer newVal; /** * @param newVal New value. */ - private TransformClosure(Integer newVal) { + private Processor(Integer newVal) { this.newVal = newVal; } - /** {@inheritDoc} */ - @Override public Integer apply(Integer val) { - return newVal; + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(newVal); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridCacheValueConsistencyAtomicSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridCacheValueConsistencyAtomicSelfTest.java index 252ac3a..402cb24 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridCacheValueConsistencyAtomicSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/dht/atomic/GridCacheValueConsistencyAtomicSelfTest.java @@ -10,13 +10,14 @@ package org.gridgain.grid.kernal.processors.cache.distributed.dht.atomic; import org.apache.ignite.*; -import org.apache.ignite.lang.*; import org.gridgain.grid.cache.*; import org.gridgain.grid.kernal.processors.cache.*; import org.gridgain.grid.util.typedef.internal.*; import org.gridgain.testframework.*; import org.jdk8.backport.*; +import javax.cache.processor.*; +import java.io.*; import java.util.concurrent.atomic.*; import static org.gridgain.grid.cache.GridCacheAtomicityMode.*; @@ -62,14 +63,14 @@ public class GridCacheValueConsistencyAtomicSelfTest extends GridCacheValueConsi for (int i = rangeStart; i < rangeStart + range; i++) { int idx = ThreadLocalRandom8.current().nextInt(gridCount()); - GridCacheProjection cache = grid(idx).cache(null); + IgniteCache cache = grid(idx).jcache(null); cache = cache.flagsOn(GridCacheFlag.FORCE_TRANSFORM_BACKUP); - cache.transform(i, new Transformer(i)); + cache.invoke(i, new Transformer(i)); } } - catch (IgniteCheckedException e) { + catch (Exception e) { throw new IgniteException(e); } } @@ -102,20 +103,28 @@ public class GridCacheValueConsistencyAtomicSelfTest extends GridCacheValueConsi /** * */ - private static class Transformer implements IgniteClosure { + private static class Transformer implements EntryProcessor, Serializable { + /** */ private int key; + /** + * @param key Key. + */ private Transformer(int key) { this.key = key; } /** {@inheritDoc} */ - @Override public Integer apply(Integer old) { + @Override public Void process(MutableEntry e, Object... args) { + Integer old = e.getValue(); + if (key < 5) System.err.println(Thread.currentThread().getName() + " <> Transforming value [key=" + key + ", val=" + old + ']'); - return old == null ? 1 : old + 1; + e.setValue(old == null ? 1 : old + 1); + + return null; } } } diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheMockEntry.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheMockEntry.java index 6519617..6827e66 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheMockEntry.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/eviction/GridCacheMockEntry.java @@ -201,17 +201,6 @@ public class GridCacheMockEntry extends GridMetadataAwareAdapter implement } /** {@inheritDoc} */ - @Override public void transform(IgniteClosure transformer) throws IgniteCheckedException { - // No-op. - } - - /** {@inheritDoc} */ - @Override public IgniteFuture transformAsync(IgniteClosure transformer) { - // No-op. - return null; - } - - /** {@inheritDoc} */ @Nullable @Override public V replace(V val) throws IgniteCheckedException { // No-op. return null; diff --git a/modules/core/src/test/java/org/gridgain/testframework/junits/common/GridCommonAbstractTest.java b/modules/core/src/test/java/org/gridgain/testframework/junits/common/GridCommonAbstractTest.java index 8e858da..f40d941 100644 --- a/modules/core/src/test/java/org/gridgain/testframework/junits/common/GridCommonAbstractTest.java +++ b/modules/core/src/test/java/org/gridgain/testframework/junits/common/GridCommonAbstractTest.java @@ -24,6 +24,7 @@ import org.gridgain.grid.kernal.processors.cache.distributed.near.*; import org.gridgain.grid.kernal.processors.cache.local.*; import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; +import org.gridgain.testframework.*; import org.gridgain.testframework.junits.*; import org.jetbrains.annotations.*; @@ -60,6 +61,14 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest { /** * @param idx Grid index. + * @return Cache. + */ + protected IgniteCache jcache(int idx) { + return grid(idx).jcache(null); + } + + /** + * @param idx Grid index. * @param name Cache name. * @return Cache. */ @@ -274,7 +283,7 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest { /** * @param cache Cache. - * @return Collection of keys for which given cache is primary. + * @return Key for which given cache is primary. * @throws IgniteCheckedException If failed. */ protected Integer primaryKey(GridCacheProjection cache) @@ -326,7 +335,7 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest { /** * @param cache Cache. - * @return Collection of keys for which given cache is backup. + * @return Key for which given cache is backup. * @throws IgniteCheckedException If failed. */ protected Integer backupKey(GridCacheProjection cache) @@ -378,7 +387,7 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest { /** * @param cache Cache. - * @return Collection of keys for which given cache is neither primary nor backup. + * @return Keys for which given cache is neither primary nor backup. * @throws IgniteCheckedException If failed. */ protected Integer nearKey(GridCacheProjection cache) @@ -429,6 +438,84 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest { } /** + * @param cache Cache. + * @param cnt Keys count. + * @param startFrom Start value for keys search. + * @return Collection of keys for which given cache is primary. + * @throws IgniteCheckedException If failed. + */ + protected List primaryKeys(IgniteCache cache, int cnt, int startFrom) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return primaryKeys(prj, cnt, startFrom); + } + + /** + * @param cache Cache. + * @param cnt Keys count. + * @param startFrom Start value for keys search. + * @return Collection of keys for which given cache is backup. + * @throws IgniteCheckedException If failed. + */ + protected List backupKeys(IgniteCache cache, int cnt, int startFrom) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return backupKeys(prj, cnt, startFrom); + } + + /** + * @param cache Cache. + * @param cnt Keys count. + * @param startFrom Start value for keys search. + * @return Collection of keys for which given cache is neither primary nor backup. + * @throws IgniteCheckedException If failed. + */ + protected List nearKeys(IgniteCache cache, int cnt, int startFrom) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return nearKeys(prj, cnt, startFrom); + } + + /** + * @param cache Cache. + * @return Collection of keys for which given cache is primary. + * @throws IgniteCheckedException If failed. + */ + protected Integer primaryKey(IgniteCache cache) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return primaryKey(prj); + } + + /** + * @param cache Cache. + * @return Keys for which given cache is backup. + * @throws IgniteCheckedException If failed. + */ + protected Integer backupKey(IgniteCache cache) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return backupKey(prj); + } + + /** + * @param cache Cache. + * @return Key for which given cache is neither primary nor backup. + * @throws IgniteCheckedException If failed. + */ + protected Integer nearKey(IgniteCache cache) + throws IgniteCheckedException { + GridCacheProjection prj = GridTestUtils.getFieldValue(cache, "delegate"); + + return nearKey(prj); + } + + /** * @param comp Compute. * @param task Task. * @param arg Task argument. diff --git a/modules/core/src/test/java/org/gridgain/testsuites/bamboo/GridDataGridTestSuite.java b/modules/core/src/test/java/org/gridgain/testsuites/bamboo/GridDataGridTestSuite.java index e642753..d9a5e22 100644 --- a/modules/core/src/test/java/org/gridgain/testsuites/bamboo/GridDataGridTestSuite.java +++ b/modules/core/src/test/java/org/gridgain/testsuites/bamboo/GridDataGridTestSuite.java @@ -10,6 +10,7 @@ package org.gridgain.testsuites.bamboo; import junit.framework.*; +import org.apache.ignite.internal.processors.cache.*; import org.apache.ignite.internal.processors.cache.expiry.*; import org.gridgain.grid.*; import org.gridgain.grid.cache.affinity.fair.*; @@ -31,14 +32,24 @@ import org.gridgain.testsuites.*; */ public class GridDataGridTestSuite extends TestSuite { /** - * @return GridGain TeamCity in-memory data grid test suite. + * @return IgniteCache test suite. * @throws Exception Thrown in case of the failure. */ public static TestSuite suite() throws Exception { - TestSuite suite = new TestSuite("Gridgain In-Memory Data Grid Test Suite"); + TestSuite suite = new TestSuite("IgniteCache Test Suite"); suite.addTest(IgniteCacheExpiryPolicyTestSuite.suite()); + suite.addTestSuite(IgniteCacheAtomicInvokeTest.class); + suite.addTestSuite(IgniteCacheAtomicNearEnabledInvokeTest.class); + suite.addTestSuite(IgniteCacheAtomicPrimaryWriteOrderInvokeTest.class); + suite.addTestSuite(IgniteCacheAtomicPrimaryWriteOrderWithStoreInvokeTest.class); + suite.addTestSuite(IgniteCacheAtomicLocalInvokeTest.class); + suite.addTestSuite(IgniteCacheAtomicLocalWithStoreInvokeTest.class); + suite.addTestSuite(IgniteCacheTxInvokeTest.class); + suite.addTestSuite(IgniteCacheTxNearEnabledInvokeTest.class); + suite.addTestSuite(IgniteCacheTxLocalInvokeTest.class); + // Affinity tests. suite.addTestSuite(GridCachePartitionFairAffinityNodesSelfTest.class); suite.addTestSuite(GridCacheAffinityBackupsSelfTest.class); diff --git a/modules/hadoop/src/main/java/org/gridgain/grid/kernal/processors/hadoop/jobtracker/GridHadoopJobTracker.java b/modules/hadoop/src/main/java/org/gridgain/grid/kernal/processors/hadoop/jobtracker/GridHadoopJobTracker.java index 75cc266..6b3260f 100644 --- a/modules/hadoop/src/main/java/org/gridgain/grid/kernal/processors/hadoop/jobtracker/GridHadoopJobTracker.java +++ b/modules/hadoop/src/main/java/org/gridgain/grid/kernal/processors/hadoop/jobtracker/GridHadoopJobTracker.java @@ -29,6 +29,8 @@ import org.jdk8.backport.*; import org.jetbrains.annotations.*; import javax.cache.expiry.*; +import javax.cache.processor.*; +import java.io.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -46,10 +48,10 @@ public class GridHadoopJobTracker extends GridHadoopComponent { private final GridMutex mux = new GridMutex(); /** */ - private volatile GridCacheProjection jobMetaPrj; + private volatile GridCacheProjectionEx jobMetaPrj; /** Projection with expiry policy for finished job updates. */ - private volatile GridCacheProjection finishedJobMetaPrj; + private volatile GridCacheProjectionEx finishedJobMetaPrj; /** Map-reduce execution planner. */ @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") @@ -96,8 +98,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @return Job meta projection. */ @SuppressWarnings("NonPrivateFieldAccessedInSynchronizedContext") - private GridCacheProjection jobMetaCache() { - GridCacheProjection prj = jobMetaPrj; + private GridCacheProjectionEx jobMetaCache() { + GridCacheProjectionEx prj = jobMetaPrj; if (prj == null) { synchronized (mux) { @@ -118,7 +120,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { throw new IllegalStateException(e); } - jobMetaPrj = prj = sysCache.projection(GridHadoopJobId.class, GridHadoopJobMetadata.class); + jobMetaPrj = prj = (GridCacheProjectionEx) + sysCache.projection(GridHadoopJobId.class, GridHadoopJobMetadata.class); if (ctx.configuration().getFinishedJobInfoTtl() > 0) { ExpiryPolicy finishedJobPlc = new ModifiedExpiryPolicy( @@ -139,8 +142,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * @return Projection with expiry policy for finished job updates. */ - private GridCacheProjection finishedJobMetaCache() { - GridCacheProjection prj = finishedJobMetaPrj; + private GridCacheProjectionEx finishedJobMetaCache() { + GridCacheProjectionEx prj = finishedJobMetaPrj; if (prj == null) { jobMetaCache(); @@ -430,10 +433,10 @@ public class GridHadoopJobTracker extends GridHadoopComponent { assert state != null || (ctx.jobUpdateLeader() && (info.type() == COMMIT || info.type() == ABORT)): "Missing local state for finished task [info=" + info + ", status=" + status + ']'; - StackedClosure incrCntrs = null; + StackedProcessor incrCntrs = null; if (status.state() == COMPLETED) - incrCntrs = new IncrementCountersClosure(null, status.counters()); + incrCntrs = new IncrementCountersProcessor(null, status.counters()); switch (info.type()) { case SETUP: { @@ -462,9 +465,9 @@ public class GridHadoopJobTracker extends GridHadoopComponent { case COMMIT: case ABORT: { - GridCacheProjection cache = finishedJobMetaCache(); + GridCacheProjectionEx cache = finishedJobMetaCache(); - cache.transformAsync(info.jobId(), new UpdatePhaseClosure(incrCntrs, PHASE_COMPLETE)). + cache.invokeAsync(info.jobId(), new UpdatePhaseProcessor(incrCntrs, PHASE_COMPLETE)). listenAsync(failsLog); break; @@ -480,8 +483,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param jobId Job id. * @param c Closure of operation. */ - private void transform(GridHadoopJobId jobId, IgniteClosure c) { - jobMetaCache().transformAsync(jobId, c).listenAsync(failsLog); + private void transform(GridHadoopJobId jobId, EntryProcessor c) { + jobMetaCache().invokeAsync(jobId, c).listenAsync(failsLog); } /** @@ -493,7 +496,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { */ public void onExternalMappersInitialized(GridHadoopJobId jobId, Collection reducers, GridHadoopProcessDescriptor desc) { - transform(jobId, new InitializeReducersClosure(null, reducers, desc)); + transform(jobId, new InitializeReducersProcessor(null, reducers, desc)); } /** @@ -601,7 +604,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { } if (cancelSplits != null || cancelReducers != null) - jobMetaCache().transform(meta.jobId(), new CancelJobClosure(null, new IgniteCheckedException( + jobMetaCache().invoke(meta.jobId(), new CancelJobProcessor(null, new IgniteCheckedException( "One or more nodes participating in map-reduce job execution failed."), cancelSplits, cancelReducers)); } @@ -615,8 +618,10 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * @param updated Updated cache entries. + * @throws IgniteCheckedException If failed. */ - private void processJobMetadataUpdates(Iterable> updated) throws IgniteCheckedException { + private void processJobMetadataUpdates(Iterable> updated) + throws IgniteCheckedException { UUID locNodeId = ctx.localNodeId(); for (Map.Entry entry : updated) { @@ -637,7 +642,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { U.error(log, "Failed to process job state changed callback (will fail the job) " + "[locNodeId=" + locNodeId + ", jobId=" + jobId + ", meta=" + meta + ']', e); - transform(jobId, new CancelJobClosure(null, e)); + transform(jobId, new CancelJobProcessor(null, e)); continue; } @@ -647,7 +652,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { } /** - * + * @param jobId Job ID. + * @param plan Map-reduce plan. */ private void printPlan(GridHadoopJobId jobId, GridHadoopMapReducePlan plan) { log.info("Plan for " + jobId); @@ -780,7 +786,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { } if (!cancelMappers.isEmpty() || !cancelReducers.isEmpty()) - transform(jobId, new CancelJobClosure(null, cancelMappers, cancelReducers)); + transform(jobId, new CancelJobProcessor(null, cancelMappers, cancelReducers)); } break; @@ -1017,7 +1023,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { if (meta != null && meta.phase() != PHASE_COMPLETE && meta.phase() != PHASE_CANCELLING) { GridHadoopTaskCancelledException err = new GridHadoopTaskCancelledException("Job cancelled."); - jobMetaCache().transform(jobId, new CancelJobClosure(null, err)); + jobMetaCache().invoke(jobId, new CancelJobProcessor(null, err)); } } finally { @@ -1146,13 +1152,13 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param status Task status. * @param prev Previous closure. */ - private void onSetupFinished(final GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, StackedClosure prev) { + private void onSetupFinished(final GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, StackedProcessor prev) { final GridHadoopJobId jobId = taskInfo.jobId(); if (status.state() == FAILED || status.state() == CRASHED) - transform(jobId, new CancelJobClosure(prev, status.failCause())); + transform(jobId, new CancelJobProcessor(prev, status.failCause())); else - transform(jobId, new UpdatePhaseClosure(prev, PHASE_MAP)); + transform(jobId, new UpdatePhaseProcessor(prev, PHASE_MAP)); } /** @@ -1161,14 +1167,14 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. */ private void onMapFinished(final GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, - final StackedClosure prev) { + final StackedProcessor prev) { final GridHadoopJobId jobId = taskInfo.jobId(); boolean lastMapperFinished = completedMappersCnt.incrementAndGet() == currMappers.size(); if (status.state() == FAILED || status.state() == CRASHED) { // Fail the whole job. - transform(jobId, new RemoveMappersClosure(prev, taskInfo.inputSplit(), status.failCause())); + transform(jobId, new RemoveMappersProcessor(prev, taskInfo.inputSplit(), status.failCause())); return; } @@ -1186,7 +1192,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { } } - transform(jobId, new RemoveMappersClosure(prev, taskInfo.inputSplit(), err)); + transform(jobId, new RemoveMappersProcessor(prev, taskInfo.inputSplit(), err)); } }; @@ -1201,13 +1207,13 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param status Task status. * @param prev Previous closure. */ - private void onReduceFinished(GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, StackedClosure prev) { + private void onReduceFinished(GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, StackedProcessor prev) { GridHadoopJobId jobId = taskInfo.jobId(); if (status.state() == FAILED || status.state() == CRASHED) // Fail the whole job. - transform(jobId, new RemoveReducerClosure(prev, taskInfo.taskNumber(), status.failCause())); + transform(jobId, new RemoveReducerProcessor(prev, taskInfo.taskNumber(), status.failCause())); else - transform(jobId, new RemoveReducerClosure(prev, taskInfo.taskNumber())); + transform(jobId, new RemoveReducerProcessor(prev, taskInfo.taskNumber())); } /** @@ -1216,12 +1222,12 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. */ private void onCombineFinished(GridHadoopTaskInfo taskInfo, GridHadoopTaskStatus status, - final StackedClosure prev) { + final StackedProcessor prev) { final GridHadoopJobId jobId = taskInfo.jobId(); if (status.state() == FAILED || status.state() == CRASHED) // Fail the whole job. - transform(jobId, new RemoveMappersClosure(prev, currMappers, status.failCause())); + transform(jobId, new RemoveMappersProcessor(prev, currMappers, status.failCause())); else { ctx.shuffle().flush(jobId).listenAsync(new CIX1>() { @Override public void applyx(IgniteFuture f) { @@ -1236,7 +1242,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { } } - transform(jobId, new RemoveMappersClosure(prev, currMappers, err)); + transform(jobId, new RemoveMappersProcessor(prev, currMappers, err)); } }); } @@ -1272,7 +1278,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Update job phase transform closure. */ - private static class UpdatePhaseClosure extends StackedClosure { + private static class UpdatePhaseProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1283,7 +1289,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. * @param phase Phase to update. */ - private UpdatePhaseClosure(@Nullable StackedClosure prev, GridHadoopJobPhase phase) { + private UpdatePhaseProcessor(@Nullable StackedProcessor prev, GridHadoopJobPhase phase) { super(prev); this.phase = phase; @@ -1298,7 +1304,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Remove mapper transform closure. */ - private static class RemoveMappersClosure extends StackedClosure { + private static class RemoveMappersProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1313,15 +1319,16 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param split Mapper split to remove. * @param err Error. */ - private RemoveMappersClosure(@Nullable StackedClosure prev, GridHadoopInputSplit split, Throwable err) { + private RemoveMappersProcessor(@Nullable StackedProcessor prev, GridHadoopInputSplit split, Throwable err) { this(prev, Collections.singletonList(split), err); } /** * @param prev Previous closure. * @param splits Mapper splits to remove. + * @param err Error. */ - private RemoveMappersClosure(@Nullable StackedClosure prev, Collection splits, + private RemoveMappersProcessor(@Nullable StackedProcessor prev, Collection splits, Throwable err) { super(prev); @@ -1354,7 +1361,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Remove reducer transform closure. */ - private static class RemoveReducerClosure extends StackedClosure { + private static class RemoveReducerProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1368,7 +1375,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. * @param rdc Reducer to remove. */ - private RemoveReducerClosure(@Nullable StackedClosure prev, int rdc) { + private RemoveReducerProcessor(@Nullable StackedProcessor prev, int rdc) { super(prev); this.rdc = rdc; @@ -1377,8 +1384,9 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * @param prev Previous closure. * @param rdc Reducer to remove. + * @param err Error. */ - private RemoveReducerClosure(@Nullable StackedClosure prev, int rdc, Throwable err) { + private RemoveReducerProcessor(@Nullable StackedProcessor prev, int rdc, Throwable err) { super(prev); this.rdc = rdc; @@ -1403,7 +1411,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Initialize reducers. */ - private static class InitializeReducersClosure extends StackedClosure { + private static class InitializeReducersProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1418,7 +1426,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param rdc Reducers to initialize. * @param desc External process descriptor. */ - private InitializeReducersClosure(@Nullable StackedClosure prev, Collection rdc, + private InitializeReducersProcessor(@Nullable StackedProcessor prev, + Collection rdc, GridHadoopProcessDescriptor desc) { super(prev); @@ -1446,7 +1455,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Remove reducer transform closure. */ - private static class CancelJobClosure extends StackedClosure { + private static class CancelJobProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1463,7 +1472,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. * @param err Fail cause. */ - private CancelJobClosure(@Nullable StackedClosure prev, Throwable err) { + private CancelJobProcessor(@Nullable StackedProcessor prev, Throwable err) { this(prev, err, null, null); } @@ -1472,7 +1481,8 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param splits Splits to remove. * @param rdc Reducers to remove. */ - private CancelJobClosure(@Nullable StackedClosure prev, Collection splits, + private CancelJobProcessor(@Nullable StackedProcessor prev, + Collection splits, Collection rdc) { this(prev, null, splits, rdc); } @@ -1483,7 +1493,9 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param splits Splits to remove. * @param rdc Reducers to remove. */ - private CancelJobClosure(@Nullable StackedClosure prev, Throwable err, Collection splits, + private CancelJobProcessor(@Nullable StackedProcessor prev, + Throwable err, + Collection splits, Collection rdc) { super(prev); @@ -1522,7 +1534,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Increment counter values closure. */ - private static class IncrementCountersClosure extends StackedClosure { + private static class IncrementCountersProcessor extends StackedProcessor { /** */ private static final long serialVersionUID = 0L; @@ -1533,7 +1545,7 @@ public class GridHadoopJobTracker extends GridHadoopComponent { * @param prev Previous closure. * @param counters Task counters to add into job counters. */ - private IncrementCountersClosure(@Nullable StackedClosure prev, GridHadoopCounters counters) { + private IncrementCountersProcessor(@Nullable StackedProcessor prev, GridHadoopCounters counters) { super(prev); assert counters != null; @@ -1554,22 +1566,33 @@ public class GridHadoopJobTracker extends GridHadoopComponent { /** * Abstract stacked closure. */ - private abstract static class StackedClosure implements IgniteClosure { + private abstract static class StackedProcessor implements + EntryProcessor, Serializable { /** */ private static final long serialVersionUID = 0L; /** */ - private final StackedClosure prev; + private final StackedProcessor prev; /** * @param prev Previous closure. */ - private StackedClosure(@Nullable StackedClosure prev) { + private StackedProcessor(@Nullable StackedProcessor prev) { this.prev = prev; } /** {@inheritDoc} */ - @Override public final GridHadoopJobMetadata apply(GridHadoopJobMetadata meta) { + @Override public Void process(MutableEntry e, Object... args) { + e.setValue(apply(e.getValue())); + + return null; + } + + /** + * @param meta Old value. + * @return New value. + */ + private GridHadoopJobMetadata apply(GridHadoopJobMetadata meta) { if (meta == null) return null; diff --git a/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedHitsAndMissesSelfTest.java b/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedHitsAndMissesSelfTest.java index a0db474..0143a92 100644 --- a/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedHitsAndMissesSelfTest.java +++ b/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedHitsAndMissesSelfTest.java @@ -11,7 +11,7 @@ package org.gridgain.grid.kernal.processors.cache.distributed.near; import org.apache.ignite.*; import org.apache.ignite.configuration.*; import org.apache.ignite.dataload.*; -import org.apache.ignite.lang.*; +import org.apache.ignite.marshaller.optimized.*; import org.apache.ignite.spi.discovery.tcp.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.*; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; @@ -20,6 +20,7 @@ import org.gridgain.grid.cache.*; import org.gridgain.grid.cache.query.*; import org.gridgain.testframework.junits.common.*; +import javax.cache.processor.*; import java.util.*; import static org.gridgain.grid.cache.GridCacheDistributionMode.*; @@ -43,6 +44,8 @@ public class GridCachePartitionedHitsAndMissesSelfTest extends GridCommonAbstrac @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { IgniteConfiguration cfg = super.getConfiguration(gridName); + cfg.setMarshaller(new IgniteOptimizedMarshaller(false)); + // DiscoverySpi TcpDiscoverySpi disco = new TcpDiscoverySpi(); disco.setIpFinder(IP_FINDER); @@ -114,8 +117,8 @@ public class GridCachePartitionedHitsAndMissesSelfTest extends GridCommonAbstrac misses += m.misses(); } - assertEquals(CNT/2, hits); - assertEquals(CNT/2, misses); + assertEquals(CNT / 2, hits); + assertEquals(CNT / 2, misses); } finally { stopAllGrids(); @@ -146,17 +149,21 @@ public class GridCachePartitionedHitsAndMissesSelfTest extends GridCommonAbstrac */ private static class IncrementingUpdater implements IgniteDataLoadCacheUpdater { /** */ - private static final IgniteClosure INC = new IgniteClosure() { - @Override public Long apply(Long e) { - return e == null ? 1L : e + 1; + private static final EntryProcessor INC = new EntryProcessor() { + @Override public Void process(MutableEntry e, Object... args) { + Long val = e.getValue(); + + e.setValue(val == null ? 1 : val + 1); + + return null; } }; /** {@inheritDoc} */ - @Override public void update(GridCache cache, + @Override public void update(IgniteCache cache, Collection> entries) throws IgniteCheckedException { for (Map.Entry entry : entries) - cache.transform(entry.getKey(), INC); + cache.invoke(entry.getKey(), INC); } } } diff --git a/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionFilter.java b/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionFilter.java index 6f7a5b2..bc293e5 100644 --- a/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionFilter.java +++ b/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionFilter.java @@ -10,6 +10,7 @@ package org.gridgain.grid.cache.websession; import org.apache.ignite.*; +import org.apache.ignite.cache.*; import org.apache.ignite.lang.*; import org.apache.ignite.transactions.*; import org.gridgain.grid.cache.*; @@ -18,6 +19,7 @@ import org.gridgain.grid.startup.servlet.*; import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; +import javax.cache.*; import javax.cache.expiry.*; import javax.servlet.*; import javax.servlet.http.*; @@ -144,7 +146,10 @@ public class GridWebSessionFilter implements Filter { public static final int DFLT_MAX_RETRIES_ON_FAIL = 3; /** Cache. */ - private GridCache cache; + private IgniteCache cache; + + /** Transactions. */ + private IgniteTransactions txs; /** Listener. */ private GridWebSessionListener lsnr; @@ -192,18 +197,20 @@ public class GridWebSessionFilter implements Filter { throw new IgniteException("Grid for web sessions caching is not started (is it configured?): " + gridName); + txs = webSesIgnite.transactions(); + log = webSesIgnite.log(); if (webSesIgnite == null) throw new IgniteException("Grid for web sessions caching is not started (is it configured?): " + gridName); - cache = webSesIgnite.cache(cacheName); + cache = webSesIgnite.jcache(cacheName); if (cache == null) throw new IgniteException("Cache for web sessions is not started (is it configured?): " + cacheName); - GridCacheConfiguration cacheCfg = cache.configuration(); + GridCacheConfiguration cacheCfg = cache.getConfiguration(GridCacheConfiguration.class); if (cacheCfg.getWriteSynchronizationMode() == FULL_ASYNC) throw new IgniteException("Cache for web sessions cannot be in FULL_ASYNC mode: " + cacheName); @@ -274,7 +281,7 @@ public class GridWebSessionFilter implements Filter { try { if (txEnabled) { - try (IgniteTx tx = cache.txStart(PESSIMISTIC, REPEATABLE_READ)) { + try (IgniteTx tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) { sesId = doFilter0(httpReq, res, chain); tx.commit(); @@ -380,19 +387,19 @@ public class GridWebSessionFilter implements Filter { try { while (true) { try { - GridCacheProjection cache0; + IgniteCache cache0; if (cached.getMaxInactiveInterval() > 0) { long ttl = cached.getMaxInactiveInterval() * 1000; ExpiryPolicy plc = new ModifiedExpiryPolicy(new Duration(MILLISECONDS, ttl)); - cache0 = ((GridCacheProjectionEx)cache).withExpiryPolicy(plc); + cache0 = cache.withExpiryPolicy(plc); } else cache0 = cache; - GridWebSession old = cache0.putIfAbsent(sesId, cached); + GridWebSession old = cache0.getAndPutIfAbsent(sesId, cached); if (old != null) { cached = old; @@ -403,13 +410,13 @@ public class GridWebSessionFilter implements Filter { break; } - catch (GridCachePartialUpdateException e) { + catch (CachePartialUpdateException e) { if (log.isDebugEnabled()) log.debug(e.getMessage()); } } } - catch (IgniteCheckedException e) { + catch (CacheException e) { throw new IgniteException("Failed to save session: " + sesId, e); } diff --git a/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionListener.java b/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionListener.java index 401b7ff..ff0c738 100644 --- a/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionListener.java +++ b/modules/web/src/main/java/org/gridgain/grid/cache/websession/GridWebSessionListener.java @@ -10,13 +10,13 @@ package org.gridgain.grid.cache.websession; import org.apache.ignite.*; -import org.gridgain.grid.cache.*; -import org.gridgain.grid.kernal.processors.cache.*; +import org.apache.ignite.cache.*; import org.gridgain.grid.util.typedef.*; import org.gridgain.grid.util.typedef.internal.*; -import org.jetbrains.annotations.*; +import javax.cache.*; import javax.cache.expiry.*; +import javax.cache.processor.*; import java.io.*; import java.util.*; @@ -30,7 +30,7 @@ class GridWebSessionListener { private static final long RETRY_DELAY = 1; /** Cache. */ - private final GridCache cache; + private final IgniteCache cache; /** Maximum retries. */ private final int retries; @@ -43,7 +43,7 @@ class GridWebSessionListener { * @param cache Cache. * @param retries Maximum retries. */ - GridWebSessionListener(Ignite ignite, GridCache cache, int retries) { + GridWebSessionListener(Ignite ignite, IgniteCache cache, int retries) { assert ignite != null; assert cache != null; @@ -60,10 +60,10 @@ class GridWebSessionListener { assert sesId != null; try { - if (cache.removex(sesId) && log.isDebugEnabled()) + if (cache.remove(sesId) && log.isDebugEnabled()) log.debug("Session destroyed: " + sesId); } - catch (IgniteCheckedException e) { + catch (CacheException e) { U.error(log, "Failed to remove session: " + sesId, e); } } @@ -84,23 +84,23 @@ class GridWebSessionListener { try { for (int i = 0; i < retries; i++) { try { - GridCacheProjection cache0; + IgniteCache cache0; if (maxInactiveInterval > 0) { long ttl = maxInactiveInterval * 1000; ExpiryPolicy plc = new ModifiedExpiryPolicy(new Duration(MILLISECONDS, ttl)); - cache0 = ((GridCacheProjectionEx)cache).withExpiryPolicy(plc); + cache0 = cache.withExpiryPolicy(plc); } else cache0 = cache; - cache0.transform(sesId, new AttributesUpdated(updates)); + cache0.invoke(sesId, new AttributesProcessor(updates)); break; } - catch (GridCachePartialUpdateException ignored) { + catch (CachePartialUpdateException ignored) { if (i == retries - 1) { U.warn(log, "Failed to apply updates for session (maximum number of retries exceeded) [sesId=" + sesId + ", retries=" + retries + ']'); @@ -113,7 +113,7 @@ class GridWebSessionListener { } } } - catch (IgniteCheckedException e) { + catch (CacheException | IgniteCheckedException e) { U.error(log, "Failed to update session attributes [id=" + sesId + ']', e); } } @@ -126,7 +126,7 @@ class GridWebSessionListener { /** * Multiple attributes update transformer. */ - private static class AttributesUpdated implements C1, Externalizable { + private static class AttributesProcessor implements EntryProcessor, Externalizable { /** */ private static final long serialVersionUID = 0L; @@ -136,26 +136,25 @@ class GridWebSessionListener { /** * Required by {@link Externalizable}. */ - public AttributesUpdated() { + public AttributesProcessor() { // No-op. } /** * @param updates Updates list. */ - AttributesUpdated(Collection> updates) { + AttributesProcessor(Collection> updates) { assert updates != null; this.updates = updates; } /** {@inheritDoc} */ - @SuppressWarnings("NonSerializableObjectBoundToHttpSession") - @Nullable @Override public GridWebSession apply(@Nullable GridWebSession ses) { - if (ses == null) + @Override public Void process(MutableEntry entry, Object... args) { + if (!entry.exists()) return null; - ses = new GridWebSession(ses); + GridWebSession ses = new GridWebSession(entry.getValue()); for (T2 update : updates) { String name = update.get1(); @@ -170,7 +169,9 @@ class GridWebSessionListener { ses.removeAttribute(name); } - return ses; + entry.setValue(ses); + + return null; } /** {@inheritDoc} */