ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From yzhda...@apache.org
Subject [04/50] [abbrv] incubator-ignite git commit: # IGNITE-261 Cleanup API: WIP scalar.
Date Mon, 16 Feb 2015 13:49:17 GMT
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7007771c/modules/scalar/src/main/scala/org/apache/ignite/scalar/pimps/ScalarCachePimp.scala
----------------------------------------------------------------------
diff --git a/modules/scalar/src/main/scala/org/apache/ignite/scalar/pimps/ScalarCachePimp.scala b/modules/scalar/src/main/scala/org/apache/ignite/scalar/pimps/ScalarCachePimp.scala
index de38166..ec2249b 100644
--- a/modules/scalar/src/main/scala/org/apache/ignite/scalar/pimps/ScalarCachePimp.scala
+++ b/modules/scalar/src/main/scala/org/apache/ignite/scalar/pimps/ScalarCachePimp.scala
@@ -17,16 +17,54 @@
 
 package org.apache.ignite.scalar.pimps
 
-import org.apache.ignite.cache.GridCache
+import org.apache.ignite.cache.query.{SqlQuery, QueryCursor}
+import org.apache.ignite.configuration.CacheConfiguration
+
+import javax.cache.Cache
+
+import org.apache.ignite._
+import org.apache.ignite.cluster.ClusterGroup
+import org.apache.ignite.internal.util.scala.impl
+import org.apache.ignite.lang.{IgniteBiTuple, IgniteClosure, IgnitePredicate, IgniteReducer}
+import org.apache.ignite.scalar.pimps.ScalarCacheConfigurationHelper._
+import org.apache.ignite.scalar.scalar._
+import org.jetbrains.annotations.Nullable
+
+import java.util.{Set => JavaSet}
+
+import scala.collection._
+import scala.collection.JavaConversions._
+
+
+/**
+ * Companion object.
+ */
+object ScalarCachePimp {
+    /**
+     * Creates new Scalar cache projection pimp with given Java-side implementation.
+     *
+     * @param impl Java-side implementation.
+     */
+    def apply[K, V](impl: IgniteCache[K, V]) = {
+        if (impl == null)
+            throw new NullPointerException("impl")
+
+        val pimp = new ScalarCachePimp[K, V]
+
+        pimp.impl = impl
+
+        pimp
+    }
+}
 
 /**
  * ==Overview==
- * Defines Scalar "pimp" for `Cache` on Java side.
+ * Defines Scalar "pimp" for `IgniteCache` on Java side.
  *
- * Essentially this class extends Java `GridProjection` interface with Scala specific
+ * Essentially this class extends Java `IgniteCache` interface with Scala specific
  * API adapters using primarily implicit conversions defined in `ScalarConversions` object. What
  * it means is that you can use functions defined in this class on object
- * of Java `GridProjection` type. Scala will automatically (implicitly) convert it into
+ * of Java `IgniteCache` type. Scala will automatically (implicitly) convert it into
  * Scalar's pimp and replace the original call with a call on that pimp.
  *
  * Note that Scalar provide extensive library of implicit conversion between Java and
@@ -38,32 +76,1889 @@ import org.apache.ignite.cache.GridCache
  * Instead of giving two different names to the same function we've decided to simply mark
  * Scala's side method with `$` suffix.
  */
-class ScalarCachePimp[K, V] extends ScalarCacheProjectionPimp[K, V] with Ordered[GridCache[K, V]] {
+class ScalarCachePimp[@specialized K, @specialized V] extends PimpedType[IgniteCache[K, V]]
+with Iterable[Cache.Entry[K, V]] with Ordered[IgniteCache[K, V]] {
+    /** */
+    lazy val value: IgniteCache[K, V] = impl
+
+    /** */
+    protected var impl: IgniteCache[K, V] = _
+
+    /** Type alias. */
+    protected type EntryPred = (Cache.Entry[K, V]) => Boolean
+
+    /** Type alias. */
+    protected type KvPred = (K, V) => Boolean
+
+    protected def toJavaSet[T](it: Iterable[T]): JavaSet[T] = new java.util.HashSet[T](asJavaCollection(it))
+
     /**
      * Compares this cache name to the given cache name.
      *
      * @param that Another cache instance to compare names with.
      */
-    def compare(that: GridCache[K, V]): Int = that.name.compareTo(value.name)
-}
+    def compare(that: IgniteCache[K, V]): Int = that.getName.compareTo(value.getName)
+
+    def configuration(): CacheConfiguration = extract(value)
+
+    /**
+     * Gets iterator for cache entries.
+     */
+    def iterator = toScalaSeq(value.iterator).iterator
+
+    /**
+     * Unwraps sequence of functions to sequence of Ignite predicates.
+     */
+    private def unwrap(@Nullable p: Seq[EntryPred]): Seq[IgnitePredicate[Cache.Entry[K, V]]] =
+        if (p == null)
+            null
+        else
+            p map ((f: EntryPred) => toPredicate(f))
 
-/**
- * Companion object.
- */
-object ScalarCachePimp {
     /**
-     * Creates new Scalar cache pimp with given Java-side implementation.
+     * Converts reduce function to Grid Reducer that takes map entries.
      *
-     * @param impl Java-side implementation.
+     * @param rdc Reduce function.
+     * @return Entry reducer.
      */
-    def apply[K, V](impl: GridCache[K, V]) = {
-        if (impl == null)
-            throw new NullPointerException("impl")
+    private def toEntryReducer[R](rdc: Iterable[(K, V)] => R): IgniteReducer[java.util.Map.Entry[K, V], R] = {
+        new IgniteReducer[java.util.Map.Entry[K, V], R] {
+            private var seq = Seq.empty[(K, V)]
 
-        val pimp = new ScalarCachePimp[K, V]
+            def collect(e: java.util.Map.Entry[K, V]): Boolean = {
+                seq +:= (e.getKey, e.getValue)
 
-        pimp.impl = impl
+                true
+            }
 
-        pimp
+            def reduce(): R = {
+                rdc(seq)
+            }
+        }
+    }
+
+    private def toRemoteTransformer[K, V, T](trans: V => T):
+    IgniteClosure[java.util.Map.Entry[K, V], java.util.Map.Entry[K, T]] = {
+        new IgniteClosure[java.util.Map.Entry[K, V], java.util.Map.Entry[K, T]] {
+            @impl def apply(e: java.util.Map.Entry[K, V]): java.util.Map.Entry[K, T] = {
+                new IgniteBiTuple[K, T](e.getKey, trans(e.getValue))
+            }
+        }
+    }
+
+    /**
+     * Retrieves value mapped to the specified key from cache. The return value of `null`
+     * means entry did not pass the provided filter or cache has no mapping for the key.
+     *
+     * @param k Key to retrieve the value for.
+     * @return Value for the given key.
+     */
+    def apply(k: K): V =
+        value.get(k)
+
+    /**
+     * Returns the value associated with a key, or a default value if the key is not contained in the map.
+     *
+     * @param k The key.
+     * @param default A computation that yields a default value in case key is not in cache.
+     * @return The cache value associated with `key` if it exists, otherwise the result
+     *      of the `default` computation.
+     */
+    def getOrElse(k: K, default: => V) = {
+        opt(k) match {
+            case Some(v) => v
+            case None => default
+        }
+    }
+
+    /**
+     * Retrieves value mapped to the specified key from cache as an option. The return value
+     * of `null` means entry did not pass the provided filter or cache has no mapping for the key.
+     *
+     * @param k Key to retrieve the value for.
+     * @return Value for the given key.
+     * @see `IgniteCache.get(...)`
+     */
+    def opt(k: K): Option[V] =
+        Option(value.get(k))
+
+    /**
+     * Converts given type of corresponding Java type, if Scala does
+     * auto-conversion for a given type. Only primitive types and Strings
+     * are supported.
+     *
+     * @param c Type to convert.
+     */
+    private def toJavaType(c: Class[_]) = {
+        assert(c != null)
+
+        // Hopefully if-else is faster here than a normal matching.
+        if (c == classOf[Int])
+            classOf[java.lang.Integer]
+        else if (c == classOf[Boolean])
+            classOf[java.lang.Boolean]
+        else if (c == classOf[String])
+            classOf[java.lang.String]
+        else if (c == classOf[Char])
+            classOf[java.lang.Character]
+        else if (c == classOf[Long])
+            classOf[java.lang.Long]
+        else if (c == classOf[Double])
+            classOf[java.lang.Double]
+        else if (c == classOf[Float])
+            classOf[java.lang.Float]
+        else if (c == classOf[Short])
+            classOf[java.lang.Short]
+        else if (c == classOf[Byte])
+            classOf[java.lang.Byte]
+        else if (c == classOf[Symbol])
+            throw new IgniteCheckedException("Cache type projeciton on 'scala.Symbol' are not supported.")
+        else
+            c
+    }
+
+    /**
+     * 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.
+     * <p>
+     * If write-through is enabled, the stored value will be persisted to `GridCacheStore`
+     * via `GridCacheStore#put(String, GridCacheTx, 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param kv Key-Value pair to store in cache.
+     * @return `True` if value was stored in cache, `false` otherwise.
+     * @see `IgniteCache#putx(...)`
+     */
+    def putx$(kv: (K, V)): Boolean = value.putIfAbsent(kv._1, kv._2)
+
+    /**
+     * 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.
+     * <p>
+     * If write-through is enabled, the stored value will be persisted to `GridCacheStore`
+     * via `GridCacheStore#put(String, GridCacheTx, 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param kv Key-Value pair to store in cache.
+     * @return Previous value associated with specified key, or `null`
+     *      if entry did not pass the filter, or if there was no mapping for the key in swap
+     *      or in persistent storage.
+     * @see `IgniteCache#put(...)`
+     */
+    def put$(kv: (K, V)): V = value.getAndReplace(kv._1, kv._2)
+
+    /**
+     * 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.
+     * <p>
+     * If write-through is enabled, the stored value will be persisted to `GridCacheStore`
+     * via `GridCacheStore#put(String, GridCacheTx, 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param kv Key-Value pair to store in cache.
+     * @return Previous value associated with specified key as an option.
+     * @see `IgniteCache#put(...)`
+     */
+    def putOpt$(kv: (K, V)): Option[V] = Option(value.getAndReplace(kv._1, kv._2))
+
+    /**
+     * Operator alias for the same function `putx$`.
+     *
+     * @param kv Key-Value pair to store in cache.
+     * @return `True` if value was stored in cache, `false` otherwise.
+     * @see `IgniteCache#putx(...)`
+     */
+    def +=(kv: (K, V)): Boolean =
+        putx$(kv)
+
+    /**
+     * Stores given key-value pairs in cache.
+     *
+     * If write-through is enabled, the stored values will be persisted to `GridCacheStore`
+     * via `GridCacheStore#putAll(String, GridCacheTx, Map)` 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param kv1 Key-value pair to store in cache.
+     * @param kv2 Key-value pair to store in cache.
+     * @param kvs Optional key-value pairs to store in cache.
+     * @see `IgniteCache#putAll(...)`
+     */
+    def putAll$(kv1: (K, V), kv2: (K, V), @Nullable kvs: (K, V)*) {
+        var m = mutable.Map.empty[K, V]
+
+        m += (kv1, kv2)
+
+        if (kvs != null)
+            kvs foreach (m += _)
+
+        value.putAll(m)
+    }
+
+    /**
+     * Stores given key-value pairs from the sequence in cache.
+     *
+     * If write-through is enabled, the stored values will be persisted to `GridCacheStore`
+     * via `GridCacheStore#putAll(String, GridCacheTx, Map)` 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param kvs Key-value pairs to store in cache. If `null` this function is no-op.
+     * @see `IgniteCache#putAll(...)`
+     */
+    def putAll$(@Nullable kvs: Seq[(K, V)]) {
+        if (kvs != null)
+            value.putAll(mutable.Map(kvs: _*))
+    }
+
+    /**
+     * Removes given key mappings from cache.
+     *
+     * If write-through is enabled, the values will be removed from `GridCacheStore`
+     * via `GridCacheStore#removeAll(String, GridCacheTx, Collection)` 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param ks Sequence of additional keys to remove. If `null` - this function is no-op.
+     * @see `IgniteCache#removeAll(...)`
+     */
+    def removeAll$(@Nullable ks: Seq[K]) {
+        if (ks != null)
+            value.removeAll(toJavaSet(ks))
+    }
+
+    /**
+     * Operator alias for the same function `putAll$`.
+     *
+     * @param kv1 Key-value pair to store in cache.
+     * @param kv2 Key-value pair to store in cache.
+     * @param kvs Optional key-value pairs to store in cache.
+     * @see `IgniteCache#putAll(...)`
+     */
+    def +=(kv1: (K, V), kv2: (K, V), @Nullable kvs: (K, V)*) {
+        putAll$(kv1, kv2, kvs: _*)
+    }
+
+    /**
+     * Removes given key mapping from cache. If cache previously contained value for the given key,
+     * then this value is returned. Otherwise, in case of `CacheMode#REPLICATED` caches,
+     * the value will be loaded from swap and, if it's not there, and read-through is allowed,
+     * from the underlying `GridCacheStore` storage. In case of `CacheMode#PARTITIONED`
+     * 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 and read-through is allowed,
+     * from the underlying persistent storage. If value has to be loaded from persistent
+     * storage, `GridCacheStore#load(String, GridCacheTx, Object)` method will be used.
+     *
+     * If the returned value is not needed, method `removex$(...)` 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 'GridCacheStore'
+     * via `GridCacheStore#remove(String, GridCacheTx, 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param k Key whose mapping is to be removed from cache.
+     * @return Previous value associated with specified key, or `null`
+     *      if there was no value for this key.
+     * @see `IgniteCache#remove(...)`
+     */
+    def remove$(k: K): V = value.getAndRemove(k)
+
+    /**
+     * Removes given key mapping from cache. If cache previously contained value for the given key,
+     * then this value is returned. Otherwise, in case of `CacheMode#REPLICATED` caches,
+     * the value will be loaded from swap and, if it's not there, and read-through is allowed,
+     * from the underlying `GridCacheStore` storage. In case of `CacheMode#PARTITIONED`
+     * 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 and read-through is allowed,
+     * from the underlying persistent storage. If value has to be loaded from persistent
+     * storage, `GridCacheStore#load(String, GridCacheTx, Object)` method will be used.
+     *
+     * If the returned value is not needed, method `removex$(...)` 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 'GridCacheStore'
+     * via `GridCacheStore#remove(String, GridCacheTx, 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param k Key whose mapping is to be removed from cache.
+     * @return Previous value associated with specified key as an option.
+     * @see `IgniteCache#remove(...)`
+     */
+    def removeOpt$(k: K): Option[V] =
+        Option(value.getAndRemove(k))
+
+    /**
+     * Operator alias for the same function `remove$`.
+     *
+     * @param k Key whose mapping is to be removed from cache.
+     * @return Previous value associated with specified key, or `null`
+     *      if there was no value for this key.
+     * @see `IgniteCache#remove(...)`
+     */
+    def -=(k: K): V = remove$(k)
+
+    /**
+     * Removes given key mappings from cache.
+     *
+     * If write-through is enabled, the values will be removed from `GridCacheStore`
+     * via `GridCacheStore#removeAll(String, GridCacheTx, Collection)` 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:
+     * `CacheFlag#LOCAL`, `CacheFlag#READ`.
+     *
+     * @param k1 1st key to remove.
+     * @param k2 2nd key to remove.
+     * @param ks Optional sequence of additional keys to remove.
+     * @see `IgniteCache#removeAll(...)`
+     */
+    def removeAll$(k1: K, k2: K, @Nullable ks: K*) {
+        val s = new mutable.ArrayBuffer[K](2 + (if (ks == null) 0 else ks.length))
+
+        s += k1
+        s += k2
+
+        if (ks != null)
+            ks foreach (s += _)
+
+        value.removeAll(toJavaSet(s))
+    }
+
+    /**
+     * Operator alias for the same function `remove$`.
+     *
+     * @param k1 1st key to remove.
+     * @param k2 2nd key to remove.
+     * @param ks Optional sequence of additional keys to remove.
+     * @see `IgniteCache#removeAll(...)`
+     */
+    def -=(k1: K, k2: K, @Nullable ks: K*) {
+        removeAll$(k1, k2, ks: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def scan(@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], kvp: KvPred): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(kvp != null)
+
+        //        val q = value.queries().createScanQuery(kvp)
+        //
+        //        (if (grid != null) q.projection(grid) else q).execute().get.map(e => (e.getKey, e.getValue))
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def scan(@Nullable grid: ClusterGroup, kvp: KvPred)
+        (implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(kvp != null)
+
+        scan(grid, m.erasure.asInstanceOf[Class[V]], kvp)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def scan(cls: Class[_ <: V], kvp: KvPred): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(kvp != null)
+
+        scan(null, cls, kvp)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def scan(kvp: KvPred)(implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(kvp != null)
+
+        scan(m.erasure.asInstanceOf[Class[V]], kvp)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sql(@Nullable grid: ClusterGroup, cls: Class[_ <: V], clause: String, args: Any*): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(args != null)
+
+        value.query(new SqlQuery(cls, clause).setArgs(args))
+
+        return Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def sql(@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(clause != null)
+
+        sql(grid, cls, clause, Nil: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sql(@Nullable grid: ClusterGroup, clause: String, args: Any*)
+        (implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(clause != null)
+        assert(args != null)
+
+        sql(grid, m.erasure.asInstanceOf[Class[V]], clause, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sql(cls: Class[_ <: V], clause: String, args: Any*): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(clause != null)
+
+        sql(null.asInstanceOf[ClusterGroup], cls, clause, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sql(clause: String, args: Any*)(implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(clause != null)
+
+        sql(m.erasure.asInstanceOf[Class[V]], clause, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def text(@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(clause != null)
+
+        //        val q = value.cache().queries().createFullTextQuery(cls, clause)
+        //
+        //        (if (grid != null) q.projection(grid) else q).execute().get.map(e => (e.getKey, e.getValue))
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def text(@Nullable grid: ClusterGroup, clause: String)(implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(clause != null)
+
+        text(grid, m.erasure.asInstanceOf[Class[V]], clause)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def text(cls: Class[_ <: V], clause: String): Iterable[(K, V)] = {
+        assert(cls != null)
+        assert(clause != null)
+
+        text(null, cls, clause)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @return Collection of cache key-value pairs.
+     */
+    def text(clause: String)(implicit m: Manifest[V]): Iterable[(K, V)] = {
+        assert(clause != null)
+
+        text(m.erasure.asInstanceOf[Class[V]], clause)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def scanTransform[T](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], kvp: KvPred, trans: V => T):
+    Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(trans != null)
+
+        //        val q = value.cache[K, V]().queries().createScanQuery(kvp)
+        //
+        //        toScalaItr[K, T]((if (grid != null) q.projection(grid) else q).execute(toRemoteTransformer[K, V, T](trans)).get)
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the global projection will be used.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def scanTransform[T](@Nullable grid: ClusterGroup, kvp: KvPred, trans: V => T)(implicit m: Manifest[V]):
+    Iterable[(K, T)] = {
+        assert(kvp != null)
+        assert(trans != null)
+
+        scanTransform(grid, m.erasure.asInstanceOf[Class[V]], kvp, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def scanTransform[T](cls: Class[_ <: V], kvp: KvPred, trans: V => T): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(trans != null)
+
+        scanTransform(null, cls, kvp, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def scanTransform[T](kvp: KvPred, trans: V => T)
+        (implicit m: Manifest[V]): Iterable[(K, T)] = {
+        assert(kvp != null)
+        assert(trans != null)
+
+        scanTransform(m.erasure.asInstanceOf[Class[V]], kvp, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sqlTransform[T](@Nullable grid: ClusterGroup, cls: Class[_ <: V], clause: String,
+        trans: V => T, args: Any*): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(trans != null)
+        assert(args != null)
+
+        //        val q = value.cache[K, V]().queries().createSqlQuery(cls, clause)
+        //
+        //        toScalaItr((if (grid != null) q.projection(grid) else q)
+        //            .execute(toRemoteTransformer[K, V, T](trans), args.asInstanceOf[Seq[Object]]: _*).get)
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def sqlTransform[T](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        trans: V => T): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(trans != null)
+
+        sqlTransform(grid, cls, clause, trans, Nil: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sqlTransform[T](@Nullable grid: ClusterGroup, clause: String, trans: V => T, args: Any*)
+        (implicit m: Manifest[V]): Iterable[(K, T)] = {
+        assert(clause != null)
+        assert(trans != null)
+        assert(args != null)
+
+        sqlTransform(grid, m.erasure.asInstanceOf[Class[V]], clause, trans, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sqlTransform[T](cls: Class[_ <: V], clause: String, trans: V => T, args: Any*): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(trans != null)
+        assert(args != null)
+
+        sqlTransform(null, cls, clause, trans, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @param args Optional list of query arguments.
+     * @return Collection of cache key-value pairs.
+     */
+    def sqlTransform[T](clause: String, trans: V => T, args: Any*)
+        (implicit m: Manifest[V]): Iterable[(K, T)] = {
+        assert(clause != null)
+        assert(trans != null)
+        assert(args != null)
+
+        sqlTransform(m.erasure.asInstanceOf[Class[V]], clause, trans, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def textTransform[T](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        trans: V => T): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(trans != null)
+
+        //        val q = value.cache[K, V]().queries().createFullTextQuery(cls, clause)
+        //
+        //        toScalaItr((if (grid != null) q.projection(grid) else q).execute(toRemoteTransformer[K, V, T](trans)).get)
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` transform query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def textTransform[T](@Nullable grid: ClusterGroup, clause: String, trans: V => T)
+        (implicit m: Manifest[V]): Iterable[(K, T)] = {
+        assert(clause != null)
+        assert(trans != null)
+
+        textTransform(grid, m.erasure.asInstanceOf[Class[V]], clause, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def textTransform[T](cls: Class[_ <: V], clause: String, trans: V => T): Iterable[(K, T)] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(trans != null)
+
+        textTransform(null, cls, clause, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` transform query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param trans Transform function that will be applied to each returned value.
+     * @return Collection of cache key-value pairs.
+     */
+    def textTransform[T](clause: String, trans: V => T)
+        (implicit m: Manifest[V]): Iterable[(K, T)] = {
+        assert(clause != null)
+        assert(trans != null)
+
+        textTransform(m.erasure.asInstanceOf[Class[V]], clause, trans)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def scanReduce[R1, R2](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], kvp: KvPred,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2): R2 = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        //        val q = value.cache[K, V]().queries().createScanQuery(kvp)
+        //
+        //        locRdc((if (grid != null) q.projection(grid) else q).execute(toEntryReducer(rmtRdc)).get)
+
+        null.asInstanceOf[R2]
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def scanReduce[R1, R2](@Nullable grid: ClusterGroup, kvp: KvPred,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2)(implicit m: Manifest[V]): R2 = {
+        assert(kvp != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        scanReduce(grid, m.erasure.asInstanceOf[Class[V]], kvp, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def scanReduce[R1, R2](cls: Class[_ <: V], kvp: KvPred,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2): R2 = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        scanReduce(null, cls, kvp, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def scanReduce[R1, R2](kvp: KvPred, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2)(implicit m: Manifest[V]): R2 = {
+        assert(kvp != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        scanReduce(m.erasure.asInstanceOf[Class[V]], kvp, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @param args Optional list of query arguments.
+     * @return Reduced value.
+     */
+    def sqlReduce[R1, R2](@Nullable grid: ClusterGroup, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2, args: Any*): R2 = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+        assert(args != null)
+
+        //        val q = value.cache[K, V]().queries().createSqlQuery(cls, clause)
+        //
+        //        locRdc((if (grid != null) q.projection(grid) else q)
+        //            .execute(toEntryReducer(rmtRdc), args.asInstanceOf[Seq[Object]]: _*).get)
+
+        null.asInstanceOf[R2]
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def sqlReduce[R1, R2](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2): R2 = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        sqlReduce(grid, cls, clause, rmtRdc, locRdc, Nil: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @param args Optional list of query arguments.
+     * @return Reduced value.
+     */
+    def sqlReduce[R1, R2](@Nullable grid: ClusterGroup, clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2, args: Any*)(implicit m: Manifest[V]): R2 = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+        assert(args != null)
+
+        sqlReduce(grid, m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, locRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @param args Optional list of query arguments.
+     * @return Reduced value.
+     */
+    def sqlReduce[R1, R2](cls: Class[_ <: V], clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2, args: Any*): R2 = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+        assert(args != null)
+
+        sqlReduce(null, cls, clause, rmtRdc, locRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @param args Optional list of query arguments.
+     * @return Reduced value.
+     */
+    def sqlReduce[R1, R2](clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2, args: Any*)(implicit m: Manifest[V]): R2 = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+        assert(args != null)
+
+        sqlReduce(m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, locRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def textReduce[R1, R2](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R1, locRdc: Iterable[R1] => R2): R2 = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        //        val q = value.cache[K, V]().queries().createFullTextQuery(cls, clause)
+        //
+        //        locRdc((if (grid != null) q.projection(grid) else q).execute(toEntryReducer(rmtRdc)).get)
+
+        null.asInstanceOf[R2]
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def textReduce[R1, R2](@Nullable grid: ClusterGroup, clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2)(implicit m: Manifest[V]): R2 = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        textReduce(grid, m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def textReduce[R1, R2](cls: Class[_ <: V], clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2): R2 = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        textReduce(null, cls, clause, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param locRdc Reduce function that will be called on local node.
+     * @return Reduced value.
+     */
+    def textReduce[R1, R2](clause: String, rmtRdc: Iterable[(K, V)] => R1,
+        locRdc: Iterable[R1] => R2)(implicit m: Manifest[V]): R2 = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(locRdc != null)
+
+        textReduce(m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, locRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def scanReduceRemote[R](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], kvp: KvPred,
+        rmtRdc: Iterable[(K, V)] => R): Iterable[R] = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(rmtRdc != null)
+
+        //        val q = value.cache[K, V]().queries().createScanQuery(kvp)
+        //
+        //        (if (grid != null) q.projection(grid) else q).execute(toEntryReducer(rmtRdc)).get
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the global projection will be used.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def scanReduceRemote[R](@Nullable grid: ClusterGroup, kvp: KvPred,
+        rmtRdc: Iterable[(K, V)] => R)(implicit m: Manifest[V]): Iterable[R] = {
+        assert(kvp != null)
+        assert(rmtRdc != null)
+
+        scanReduceRemote(grid, m.erasure.asInstanceOf[Class[V]], kvp, rmtRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def scanReduceRemote[R](cls: Class[_ <: V], kvp: KvPred, rmtRdc: Iterable[(K, V)] => R): Iterable[R] = {
+        assert(cls != null)
+        assert(kvp != null)
+        assert(rmtRdc != null)
+
+        scanReduceRemote(null, cls, kvp, rmtRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SCAN` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param kvp Filter to be used prior to returning key-value pairs to user. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def scanReduceRemote[R](kvp: KvPred, rmtRdc: Iterable[(K, V)] => R)(implicit m: Manifest[V]): Iterable[R] = {
+        assert(kvp != null)
+        assert(rmtRdc != null)
+
+        scanReduceRemote(m.erasure.asInstanceOf[Class[V]], kvp, rmtRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param args Optional list of query arguments.
+     * @return Collection of reduced values.
+     */
+    def sqlReduceRemote[R](@Nullable grid: ClusterGroup, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R, args: Any*): Iterable[R] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(args != null)
+
+        //        val q = value.cache[K, V]().queries().createSqlQuery(cls, clause)
+        //
+        //        (if (grid != null) q.projection(grid) else q)
+        //            .execute(toEntryReducer(rmtRdc), args.asInstanceOf[Seq[Object]]: _*).get
+
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def sqlReduceRemote[R](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R): Iterable[R] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+
+        sqlReduceRemote(grid, cls, clause, rmtRdc, Nil: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param args Optional list of query arguments.
+     * @return Collection of reduced values.
+     */
+    def sqlReduceRemote[R](@Nullable grid: ClusterGroup, clause: String, rmtRdc: Iterable[(K, V)] => R,
+        args: Any*)(implicit m: Manifest[V]): Iterable[R] = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(args != null)
+
+        sqlReduceRemote(grid, m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param args Optional list of query arguments.
+     * @return Collection of reduced values.
+     */
+    def sqlReduceRemote[R](cls: Class[_ <: V], clause: String, rmtRdc: Iterable[(K, V)] => R,
+        args: Any*): Iterable[R] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(args != null)
+
+        sqlReduceRemote(null, cls, clause, rmtRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `SQL` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param clause Query SQL clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @param args Optional list of query arguments.
+     * @return Collection of reduced values.
+     */
+    def sqlReduceRemote[R](clause: String, rmtRdc: Iterable[(K, V)] => R, args: Any*)
+        (implicit m: Manifest[V]): Iterable[R] = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+        assert(args != null)
+
+        sqlReduceRemote(m.erasure.asInstanceOf[Class[V]], clause, rmtRdc, args: _*)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def textReduceRemote[R](@Nullable grid: ClusterGroup = null, cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R): Iterable[R] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+
+        //        val q = value.cache[K, V]().queries().createFullTextQuery(cls, clause)
+        //
+        //        (if (grid != null) q.projection(grid) else q).execute(toEntryReducer(rmtRdc)).get
+        Iterable.empty
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on given projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * Note that query value class will be taken implicitly as exact type `V` of this
+     * cache projection.
+     *
+     * @param grid Grid projection on which this query will be executed. If `null` the
+     *     global projection will be used.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def textReduceRemote[R](@Nullable grid: ClusterGroup, clause: String, rmtRdc: Iterable[(K, V)] => R)
+        (implicit m: Manifest[V]): Iterable[R] = {
+        assert(clause != null)
+        assert(rmtRdc != null)
+
+        textReduceRemote(grid, m.erasure.asInstanceOf[Class[V]], clause, rmtRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on global projection returning its result.
+     *
+     * Note that if query is executed more than once (potentially with different
+     * arguments) it is more performant to create query via standard mechanism
+     * and execute it multiple times with different arguments. The analogy is
+     * similar to JDBC `PreparedStatement`. Note also that this function will return
+     * all results at once without pagination and therefore memory limits should be
+     * taken into account.
+     *
+     * @param cls Query values class. Since cache can, in general, contain values of any subtype of `V`
+     *     query needs to know the exact type it should operate on.
+     * @param clause Query text clause. See `CacheQuery` for more details.
+     * @param rmtRdc Reduce function that will be called on each remote node.
+     * @return Collection of reduced values.
+     */
+    def textReduceRemote[R](cls: Class[_ <: V], clause: String,
+        rmtRdc: Iterable[(K, V)] => R): Iterable[R] = {
+        assert(cls != null)
+        assert(clause != null)
+        assert(rmtRdc != null)
+
+        textReduceRemote(null, cls, clause, rmtRdc)
+    }
+
+    /**
+     * Creates and executes ad-hoc `TEXT` reduce query on glob

<TRUNCATED>

Mime
View raw message