Return-Path: X-Original-To: apmail-ignite-commits-archive@minotaur.apache.org Delivered-To: apmail-ignite-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 31CF517352 for ; Fri, 8 May 2015 14:14:25 +0000 (UTC) Received: (qmail 86800 invoked by uid 500); 8 May 2015 14:14:25 -0000 Delivered-To: apmail-ignite-commits-archive@ignite.apache.org Received: (qmail 86691 invoked by uid 500); 8 May 2015 14:14:25 -0000 Mailing-List: contact commits-help@ignite.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.incubator.apache.org Delivered-To: mailing list commits@ignite.incubator.apache.org Received: (qmail 86532 invoked by uid 99); 8 May 2015 14:14:25 -0000 Received: from Unknown (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 May 2015 14:14:25 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 4F1D8C092D for ; Fri, 8 May 2015 14:14:19 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.03 X-Spam-Level: X-Spam-Status: No, score=-4.03 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from mx1-us-west.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id f_r93hoElECW for ; Fri, 8 May 2015 14:14:07 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-us-west.apache.org (ASF Mail Server at mx1-us-west.apache.org) with SMTP id BAE6D28718 for ; Fri, 8 May 2015 14:13:42 +0000 (UTC) Received: (qmail 82730 invoked by uid 99); 8 May 2015 14:13:42 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 08 May 2015 14:13:42 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 6D885E444F; Fri, 8 May 2015 14:13:42 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: yzhdanov@apache.org To: commits@ignite.incubator.apache.org Date: Fri, 08 May 2015 14:14:17 -0000 Message-Id: In-Reply-To: <6f334daff9254e679500ba8c625f70a8@git.apache.org> References: <6f334daff9254e679500ba8c625f70a8@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [37/50] [abbrv] incubator-ignite git commit: # Remove unused methods from GridFunc. http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/942abe45/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java index c86c5a4..6f544e0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java @@ -20,10 +20,8 @@ package org.apache.ignite.internal.util.lang; import org.apache.ignite.*; import org.apache.ignite.cluster.*; import org.apache.ignite.compute.*; -import org.apache.ignite.events.*; import org.apache.ignite.internal.*; import org.apache.ignite.internal.util.*; -import org.apache.ignite.internal.util.future.*; import org.apache.ignite.internal.util.typedef.*; import org.apache.ignite.internal.util.typedef.internal.*; import org.apache.ignite.lang.*; @@ -31,9 +29,6 @@ import org.jetbrains.annotations.*; import org.jsr166.*; import javax.cache.*; -import java.io.*; -import java.lang.reflect.*; -import java.math.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; @@ -74,13 +69,6 @@ public class GridFunc { }; /** */ - private static final IgnitePredicate IDENTITY_PRED = new P1() { - @Override public boolean apply(Boolean e) { - return e; - } - }; - - /** */ private static final IgnitePredicate ALWAYS_TRUE = new P1() { @Override public boolean apply(Object e) { return true; @@ -128,34 +116,6 @@ public class GridFunc { }; /** */ - public static final IgnitePredicate EMPTY_STRING = new P1() { - @Override public boolean apply(String s) { - return isEmpty(s); - } - }; - - /** */ - public static final IgnitePredicate NOT_EMPTY_STRING = new P1() { - @Override public boolean apply(String s) { - return !isEmpty(s); - } - }; - - /** */ - public static final IgnitePredicate EMPTY_COLLECTION = new P1() { - @Override public boolean apply(Collection c) { - return isEmpty(c); - } - }; - - /** */ - public static final IgnitePredicate NOT_EMPTY_COLLECTION = new P1() { - @Override public boolean apply(Collection c) { - return !isEmpty(c); - } - }; - - /** */ private static final IgniteCallable LIST_FACTORY = new IgniteCallable() { @Override public List call() { return new ArrayList(); @@ -266,84 +226,6 @@ public class GridFunc { }; /** */ - private static final IgniteInClosure PRINTLN = new CI1() { - @Override public void apply(Object o) { - System.out.println(o); - } - - @Override public String toString() { - return "Print line closure."; - } - }; - - /** */ - private static final IgniteInClosure PRINT = new CI1() { - @Override public void apply(Object o) { - System.out.print(o); - } - - @Override public String toString() { - return "Print closure."; - } - }; - - /** */ - private static final IgniteOutClosure NILL = new CO() { - @Nullable @Override public Object apply() { - return null; - } - - @Override public String toString() { - return "Nill closure."; - } - }; - - /** */ - private static final IgniteClosure R2C = new C1() { - @Override public GridAbsClosure apply(Runnable r) { - return as(r); - } - - @Override public String toString() { - return "Runnable to absolute closure transformer."; - } - }; - - /** */ - private static final IgniteClosure> P2P = - new C1>() { - @Override public IgnitePredicate apply(ClusterGroup e) { - return e.predicate(); - } - - @Override public String toString() { - return "Projection to its predicate transformer closure."; - } - }; - - /** */ - private static final IgniteClosure> CLAZZ = new C1>() { - @Override public Class apply(Object o) { - return o.getClass(); - } - - @Override public String toString() { - return "Object to class transformer closure."; - } - }; - - /** */ - private static final IgniteClosure MAP_ENTRY_KEY = new IgniteClosure() { - @Override public Object apply(Object o) { - return ((Map.Entry)o).getKey(); - } - - @Override public String toString() { - return "Map entry to key transformer closure."; - } - }; - - /** */ private static final IgniteClosure CACHE_ENTRY_KEY = new IgniteClosure() { @Override public Object apply(Object o) { return ((Cache.Entry)o).getKey(); @@ -354,16 +236,6 @@ public class GridFunc { } }; - /** */ - private static final IgniteClosure MAP_ENTRY_VAL = new IgniteClosure() { - @Override public Object apply(Object o) { - return ((Map.Entry)o).getValue(); - } - - @Override public String toString() { - return "Map entry to value transformer closure."; - } - }; /** */ private static final IgniteClosure CACHE_ENTRY_VAL_GET = new IgniteClosure() { @@ -390,18 +262,6 @@ public class GridFunc { }; /** */ - private static final IgnitePredicate CACHE_ENTRY_NO_PEEK_VAL = new IgnitePredicate() { - @SuppressWarnings({"unchecked"}) - @Override public boolean apply(Object o) { - return ((Cache.Entry)o).getValue() == null; - } - - @Override public String toString() { - return "Cache entry no-peek-value predicate."; - } - }; - - /** */ private static final IgniteClosure NODE2ID = new IgniteClosure() { @Override public UUID apply(ClusterNode n) { return n.id(); @@ -442,44 +302,6 @@ public class GridFunc { }; /** - * Gets breaker predicate which will return a predicate that will - * evaluate to {@code firstVal} when checked the first time, - * but then will always evaluate to the opposite value. - * - * @param firstVal First value. - * @param Predicate type. - * @return Breaker predicate. - */ - public static IgnitePredicate breaker(final boolean firstVal) { - return new IgnitePredicate() { - private boolean b = true; - - @Override public boolean apply(T e) { - if (b) { - b = false; - - return firstVal; - } - - return !firstVal; - } - - @Override public String toString() { - return "Breaker predicate."; - } - }; - } - - /** - * Gets closure that transform a grid projection into its predicate. - * - * @return Closure transforming a grid projection into its predicate. - */ - public static IgniteClosure> predicate() { - return P2P; - } - - /** * Gets predicate that evaluates to {@code true} only for given local node ID. * * @param locNodeId Local node ID. @@ -510,4868 +332,2608 @@ public class GridFunc { } /** - * Returns out closure that always returns {@code null}. - * - * @return Out closure that always returns {@code null}. - */ - @SuppressWarnings("unchecked") - public static IgniteOutClosure nill() { - return (IgniteOutClosure)NILL; - } - - /** - * Creates closure that will reflectively call a method with the given name on - * closure's argument and return result of that call. - *

- * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteClosure} which is {@link C1}. + * Creates new collection by removing duplicates from the given collection. * - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param Type of closure return value. - * @param Type of closure argument. - * @return Reflective closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @param c Collection to remove duplicates from. + * @param Type of the collection. + * @return De-duped collection. */ - public static IgniteClosure cInvoke(final String mtdName, final Object... args) { - A.notNull(mtdName, "mtdName"); - - return new C1() { - private Method mtd; + public static Collection dedup(Collection c) { + A.notNull(c, "c"); - @SuppressWarnings("unchecked") - @Override public R apply(T t) { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(t.getClass(), mtdName, args); + Collection set = new GridLeanSet<>(); - mtd.setAccessible(true); - } + set.addAll(c); - return (R)mtd.invoke(t, args); - } - catch (Exception e) { - throw wrap(e); - } - } - }; + return set; } /** - * Creates in closure that will reflectively call a method with the given name on - * closure's argument. + * Calculates sum of all elements. *

- * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteClosure} which is {@link C1}. + * * - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param Type of closure argument. - * @return Reflective in closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @param c Collection of elements. + * @return Sum of all elements. */ - public static IgniteInClosure ciInvoke(final String mtdName, final Object... args) { - A.notNull(mtdName, "mtdName"); - - return new CI1() { - private Method mtd; + public static int sumInt(Iterable c) { + A.notNull(c, "c"); - @Override public void apply(T t) { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(t.getClass(), mtdName, args); + int sum = 0; - mtd.setAccessible(true); - } + for (int t : c) + sum += t; - mtd.invoke(t, args); - } - catch (Exception e) { - throw wrap(e); - } - } - }; + return sum; } /** - * Creates out closure that will reflectively call a method with the given name on provided - * object and return result of that call. - *

- * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteOutClosure} which is {@link CO}. + * Gets reducer which always returns {@code true} from {@link org.apache.ignite.lang.IgniteReducer#collect(Object)} + * method and passed in {@code element} from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. * - * @param o Target object to call the method on. - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param Type of closure return value. - * @return Reflective out closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @param elem Element to return from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. + * @param Reducer element type. + * @return Passed in element. */ - public static IgniteOutClosure coInvoke(final Object o, final String mtdName, final Object... args) { - A.notNull(o, "o", mtdName, "mtdName"); - - return new CO() { - private Method mtd; - - @SuppressWarnings("unchecked") - @Override public R apply() { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(o.getClass(), mtdName, args); - - mtd.setAccessible(true); - } + public static IgniteReducer identityReducer(final T elem) { + return new R1() { + @Override public boolean collect(T e) { + return true; + } - return (R)mtd.invoke(o, args); - } - catch (Exception e) { - throw wrap(e); - } + @Override public T reduce() { + return elem; } }; } /** - * Creates absolute closure that will reflectively call a method with the given name on provided object. + * Gets reducer closure that calculates sum of integer elements. *

- * Method reflects the typedef for {@link GridAbsClosure} which is {@link CA}. + * * - * @param o Target object to call the method on. - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @return Reflective absolute closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @return Reducer that calculates sum of integer elements. */ - public static GridAbsClosure caInvoke(final Object o, final String mtdName, @Nullable final Object... args) { - A.notNull(o, "o", mtdName, "mtdName"); - - return new CA() { - /** */ - private Method mtd; + public static IgniteReducer sumIntReducer() { + return new R1() { + private AtomicInteger sum = new AtomicInteger(0); - @SuppressWarnings("unchecked") - @Override public void apply() { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(o.getClass(), mtdName, args); + @Override public boolean collect(Integer e) { + if (e != null) + sum.addAndGet(e); - mtd.setAccessible(true); - } + return true; + } - mtd.invoke(o, args); - } - catch (Exception e) { - throw wrap(e); - } + @Override public Integer reduce() { + return sum.get(); } }; } /** - * Creates out closure that will reflectively call a static method with the given name - * and return result of that call. + * Gets reducer closure that calculates sum of long integer elements. *

- * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteOutClosure} which is {@link CO}. + * * - * @param cls Class to call a static method on. - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param Type of closure return value. - * @return Reflective out closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @return Reducer that calculates sum of long integer elements. */ - public static IgniteOutClosure coInvoke(final Class cls, final String mtdName, - @Nullable final Object... args) { - A.notNull(cls, "cls", mtdName, "mtdName"); - - return new CO() { - /** */ - private Method mtd; + public static IgniteReducer sumLongReducer() { + return new R1() { + private AtomicLong sum = new AtomicLong(0); - @SuppressWarnings("unchecked") - @Override public R apply() { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(cls, mtdName, args); + @Override public boolean collect(Long e) { + if (e != null) + sum.addAndGet(e); - mtd.setAccessible(true); - } + return true; + } - return (R)mtd.invoke(null, args); - } - catch (Exception e) { - throw wrap(e); - } + @Override public Long reduce() { + return sum.get(); } }; } /** - * Creates absolute closure that will reflectively call a static method with the given name. - *

- * Method reflects the typedef for {@link GridAbsClosure} which is {@link CA}. + * Creates a range list containing numbers in given range. * - * @param cls Class to call a static method on. - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @return Reflective absolute closure. - * @throws GridClosureException Thrown in case of any reflective invocation errors. + * @param fromIncl Inclusive start of the range. + * @param toExcl Exclusive stop of the range. + * @return List containing numbers in range. */ - public static GridAbsClosure caInvoke(final Class cls, final String mtdName, @Nullable final Object... args) { - A.notNull(cls, "cls", mtdName, "mtdName"); + public static List range(int fromIncl, int toExcl) { + A.ensure(fromIncl >= 0, "fromIncl >= 0"); + A.ensure(toExcl >= 0, "toExcl >= 0"); + A.ensure(toExcl >= fromIncl, "toExcl > fromIncl"); - return new CA() { - /** */ - private Method mtd; + if (toExcl == fromIncl) + return Collections.emptyList(); - @SuppressWarnings("unchecked") - @Override public void apply() { - try { - // No synchronization allows for double creation - ignoring... - if (mtd == null) { - mtd = method(cls, mtdName, args); + List list = new ArrayList<>(toExcl - fromIncl); - mtd.setAccessible(true); - } + for (int i = fromIncl; i < toExcl; i++) + list.add(i); - mtd.invoke(null, args); - } - catch (Exception e) { - throw wrap(e); - } - } - }; + return list; } /** - * Looks up the method with given parameters. + * Gets reducer closure that concatenates strings using provided delimiter. * - * @param cls Class to look up in. - * @param mtdName Method name to look up. - * @param args Optional set of method parameters. - * @return Method instance. - * @throws Exception Thrown in case of any reflective errors. + * @param delim Delimiter (optional). + * @return Reducer that concatenates strings using provided delimeter. */ - private static Method method(Class cls, String mtdName, @Nullable Object... args) throws Exception { - assert cls != null; - assert mtdName != null; - - int cnt = 0; - - Method m = null; - - for (Method mtd : cls.getDeclaredMethods()) - if (mtd.getName().equals(mtdName)) { - cnt++; - - m = mtd; - } + public static IgniteReducer concatReducer(@Nullable final String delim) { + return new R1() { + private SB sb = new SB(); - if (cnt == 0) - throw new NoSuchMethodException(cls.getName() + '#' + mtdName); + private boolean first = true; - // If there is only one method with provided name we - // don't use lookup that requires parameters' types since - // it is a lot more complex to deal with type inheritance there. - if (cnt == 1) - return m; + private final Object lock = new Object(); - if (!isEmpty(args)) { - assert args != null; + @Override public boolean collect(String s) { + synchronized (lock) { + if (!first && !isEmpty(delim)) + sb.a(delim); - Class[] types = new Class[args.length]; + sb.a(s); - int i = 0; + first = false; + } - for (Object arg : args) { - // This is not going to work in cases when method expects - // an interface or supertype. Accept this limitation for now... - types[i++] = arg.getClass(); + return true; } - return cls.getDeclaredMethod(mtdName, types); - } - else - return cls.getDeclaredMethod(mtdName); + @Override public String reduce() { + synchronized (lock) { + return sb.toString(); + } + } + }; } /** - * Gets closure that converts object to its runtime class. + * Concatenates strings using provided delimiter. * - * @return Closure that converts object to its runtime class. - */ - public static IgniteClosure> clazz() { - return CLAZZ; - } - - /** - * Creates new collection by removing duplicates from the given collection. - * - * @param c Collection to remove duplicates from. - * @param Type of the collection. - * @return De-duped collection. + * @param c Input collection. + * @param delim Delimiter (optional). + * @return Concatenated string. */ - public static Collection dedup(Collection c) { + public static String concat(Iterable c, @Nullable String delim) { A.notNull(c, "c"); - Collection set = new GridLeanSet<>(); - - set.addAll(c); - - return set; + return reduce(c, concatReducer(delim)); } /** - * Calculates sum of all elements. + * Gets collections of data items from grid job res casted to specified type. *

- * - * - * @param c Collection of elements. - * @return Sum of all elements. - */ - public static int sumInt(Iterable c) { - A.notNull(c, "c"); - - int sum = 0; - - for (int t : c) { - sum += t; - } - - return sum; - } - - /** - * Calculates sum of all elements. + * Here's the typical example of how this method is used in {@code reduce()} method + * implementation (this example sums up all the values of {@code Integer} type): + *

+     * public Integer reduce(List<GridComputeJobResult> res) throws IgniteCheckedException {
+     *     return F.sum(F.<Integer>jobResults(res));
+     * }
+     * 
*

- * + * Note that this method doesn't create a new collection but simply iterates over the input one. * - * @param c Collection of elements. - * @return Sum of all elements. + * @param res Collection of grid job res. + * @param Type of the data item to cast to. See {@link org.apache.ignite.compute.ComputeJobResult#getData()} method. + * @return Collections of data items casted to type {@code T}. + * @see org.apache.ignite.compute.ComputeJobResult#getData() */ - public static double sumDouble(Iterable c) { - A.notNull(c, "c"); + public static Collection jobResults(@Nullable Collection res) { + if (isEmpty(res)) + return Collections.emptyList(); - double sum = 0; + assert res != null; - for (double t : c) { - sum += t; - } + Collection c = new ArrayList<>(res.size()); - return sum; + for (ComputeJobResult r : res) + c.add(r.getData()); + + return c; } /** - * Calculates sum of all elements. + * Convenient utility method that returns collection of node IDs for a given + * collection of grid nodes. *

- * + * Note that this method doesn't create a new collection but simply iterates + * over the input one. * - * @param c Collection of elements. - * @return Sum of all elements. + * @param nodes Collection of grid nodes. + * @return Collection of node IDs for given collection of grid nodes. */ - public static BigDecimal sumBigDecimal(Iterable c) { - A.notNull(c, "c"); - - BigDecimal sum = BigDecimal.ZERO; - - for (BigDecimal t : c) { - sum = sum.add(t); - } + public static Collection nodeIds(@Nullable Collection nodes) { + if (nodes == null || nodes.isEmpty()) + return Collections.emptyList(); - return sum; + return F.viewReadOnly(nodes, node2id()); } /** - * Calculates sum of all elements. + * Convenient utility method that returns collection of node ID8s for a given + * collection of grid nodes. ID8 is a shorter string representation of node ID, + * mainly the first 8 characters. *

- * + * Note that this method doesn't create a new collection but simply iterates + * over the input one. * - * @param c Collection of elements. - * @return Sum of all elements. + * @param nodes Collection of grid nodes. + * @return Collection of node IDs for given collection of grid nodes. */ - public static BigInteger sumBigInt(Iterable c) { - A.notNull(c, "c"); - - BigInteger sum = BigInteger.ZERO; - - for (BigInteger t : c) { - sum = sum.add(t); - } + public static Collection nodeId8s(@Nullable Collection nodes) { + if (nodes == null || nodes.isEmpty()) + return Collections.emptyList(); - return sum; + return F.viewReadOnly(nodes, NODE2ID8); } /** - * Calculates arithmetic mean. + * Convenient utility method that returns collection of node ID8s for a given + * collection of node IDs. ID8 is a shorter string representation of node ID, + * mainly the first 8 characters. *

- * + * Note that this method doesn't create a new collection but simply iterates + * over the input one. * - * @param c Input collection. - * @return Arithmetic mean of the input collection. + * @param ids Collection of nodeIds. + * @return Collection of node IDs for given collection of grid nodes. */ - public static double avg(Iterable c) { - A.notNull(c, "c"); - - double sum = 0; - - int i = 0; - - for (Number t : c) { - sum += t.doubleValue(); - - i++; - } + public static Collection id8s(@Nullable Collection ids) { + if (ids == null || ids.isEmpty()) + return Collections.emptyList(); - return sum / i; + return F.viewReadOnly(ids, ID2ID8); } /** - * Gets reducer closure that calculates arithmetic mean. - *

- * + * Creates absolute closure that does System.out.println(msg). * - * @return Reducer closure that calculated arithmetic mean. + * @param msg Message to print. + * @return Absolute closure that print message. */ - public static IgniteReducer avgReducer() { - return new R1() { - private double sum; - private int i; - - private final Object lock = new Object(); - - @Override public boolean collect(T e) { - if (e != null) - synchronized (lock) { - sum += e.doubleValue(); - i++; - } - - return true; - } - - @Override public Double reduce() { - synchronized (lock) { - return sum / i; - } + public static GridAbsClosure println(final String msg) { + return new CA() { + @Override public void apply() { + System.out.println(msg); } }; } /** - * Calculates quadratic mean. - *

- * + * Gets random value from given collection. * - * @param c Input collection. - * @return Quadratic mean of the input collection. + * @param c Input collection (no {@code null} and not emtpy). + * @param Type of the collection. + * @return Random value from the input collection. */ - public static double qavg(Iterable c) { + @SuppressWarnings("UnusedDeclaration") + public static T rand(Collection c) { A.notNull(c, "c"); - double sum = 0; + int n = ThreadLocalRandom8.current().nextInt(c.size()); int i = 0; - for (Number t : c) { - double d = t.doubleValue(); - - sum += d * d; - - i++; + for (T t : c) { + if (i++ == n) + return t; } - return Math.sqrt(sum / i); + throw new ConcurrentModificationException(); } /** - * Gets reducer closure that calculates quadratic mean. - *

- * + * Gets random value from given list. For random-access lists this + * operation is O(1), otherwise O(n). * - * @return Reducer closure that calculated quadratic mean. + * @param l Input collection. + * @param Type of the list elements. + * @return Random value from the input list. */ - public static IgniteReducer qavgReducer() { - return new R1() { - private double sum; - private int i; - - private final Object lock = new Object(); - - @Override public boolean collect(T e) { - if (e != null) { - double d = e.doubleValue(); - - synchronized (lock) { - sum += d * d; - - i++; - } - } - - return true; - } + public static T rand(List l) { + A.notNull(l, "l"); - @Override public Double reduce() { - synchronized (lock) { - return Math.sqrt(sum / i); - } - } - }; + return l.get(ThreadLocalRandom8.current().nextInt(l.size())); } /** - * Calculates geometric mean. - *

- * + * Gets random value from given array. This operation + * does not iterate through array elements and returns immediately. * * @param c Input collection. - * @return Geometric mean of the input collection. + * @param Type of the collection. + * @return Random value from the input collection. */ - public static double gavg(Iterable c) { + public static T rand(T... c) { A.notNull(c, "c"); - double sum = 0; - - int i = 0; - - for (Number t : c) { - sum *= t.doubleValue(); - - i++; - } - - return Math.pow(sum, 1f / i); + return c[ThreadLocalRandom8.current().nextInt(c.length)]; } /** - * Gets reducer closure that calculates geometric mean. - *

- * + * Concatenates an element to a collection. If {@code copy} flag is {@code true}, then + * a new collection will be created and the element and passed in collection will be + * copied into the new one. The returned collection will be modifiable. If {@code copy} + * flag is {@code false}, then a read-only view will be created over the element and given + * collections and no copying will happen. * - * @return Reducer closure that calculated geometric mean. + * @param cp Copy flag. + * @param t First element. + * @param c Second collection. + * @param Element type. + * @return Concatenated collection. */ - public static IgniteReducer gavgReducer() { - return new R1() { - private double sum; - private int i; + public static Collection concat(boolean cp, @Nullable final T t, @Nullable final Collection c) { + if (cp) { + if (isEmpty(c)) { + Collection l = new ArrayList<>(1); - private final Object lock = new Object(); + l.add(t); - @Override public boolean collect(T e) { - if (e != null) - synchronized (lock) { - sum *= e.doubleValue(); + return l; + } - i++; - } + assert c != null; - return true; - } + Collection ret = new ArrayList<>(c.size() + 1); - @Override public Double reduce() { - synchronized (lock) { - return Math.pow(sum, 1f / i); - } - } - }; - } + ret.add(t); + ret.addAll(c); - /** - * Calculates weighted mean. - *

- * - * - * @param c Collection of elements. - * @param w Collection of weights. - * @return Weighted mean of the input collection. - */ - public static double wavg(Collection c, Collection w) { - A.notNull(c, "c", w, "w"); - A.ensure(c.size() == w.size(), "c.size() == w.size()"); + return ret; + } + else { + if (isEmpty(c)) + return Collections.singletonList(t); - double sumC = 0; - double sumW = 0; + assert c != null; - Iterator iterC = c.iterator(); - Iterator iterW = w.iterator(); + return new GridSerializableCollection() { + @NotNull + @Override public Iterator iterator() { + return new GridSerializableIterator() { + private Iterator it; - while (iterC.hasNext()) { - assert iterW.hasNext(); + @Override public boolean hasNext() { + return it == null || it.hasNext(); + } - double dc = iterC.next().doubleValue(); - double dw = iterW.next().doubleValue(); + @Nullable @Override public T next() { + if (it == null) { + it = c.iterator(); - sumW += dw; - sumC += dw * dc; - } + return t; + } - return sumC / sumW; - } + return it.next(); + } - /** - * Calculates harmonic mean. - *

- * + @Override public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override public int size() { + return c.size() + 1; + } + + @Override public boolean equals(Object obj) { + return obj instanceof Collection && eqNotOrdered(this, (Collection)obj); + } + }; + } + } + + /** + * Concatenates 2 collections into one. If {@code copy} flag is {@code true}, then + * a new collection will be created and these collections will be copied into the + * new one. The returned collection will be modifiable. If {@code copy} flag is + * {@code false}, then a read-only view will be created over given collections + * and no copying will happen. * - * @param c Input collection. - * @return Harmonic mean of the input collection. + * @param cp Copy flag. + * @param c1 First collection. + * @param c2 Second collection. + * @param Element type. + * @return Concatenated {@code non-null} collection. */ - public static double havg(Iterable c) { - A.notNull(c, "c"); + public static Collection concat(boolean cp, @Nullable final Collection c1, + @Nullable final Collection c2) { + if (cp) { + if (isEmpty(c1) && isEmpty(c2)) + return new ArrayList<>(0); - double sum = 0; + if (isEmpty(c1)) + return new ArrayList<>(c2); - int i = 0; + if (isEmpty(c2)) + return new ArrayList<>(c1); - for (Number t : c) { + Collection c = new ArrayList<>(c1.size() + c2.size()); - sum += 1 / t.doubleValue(); + c.addAll(c1); + c.addAll(c2); - i++; + return c; } + else { + if (isEmpty(c1) && isEmpty(c2)) + return Collections.emptyList(); - return i / sum; - } - - /** - * Gets reducer closure that collects only a single value and returns it - * without any transformations. - * - * @return Reducer closure that collects and returns single value. - */ - public static IgniteReducer singleReducer() { - return new R1() { - private T obj; + if (isEmpty(c1) || isEmpty(c2)) { + Collection c = isEmpty(c1) ? c2 : c1; - @Override public boolean collect(T e) { - // No synchronization needed here. - obj = e; + assert c != null; - return false; + return c; } - @Override public T reduce() { - return obj; - } - }; + return new GridSerializableCollection() { + @NotNull + @Override public Iterator iterator() { + return new GridSerializableIterator() { + private Iterator it1 = c1.iterator(); + private Iterator it2 = c2.iterator(); + + @Override public boolean hasNext() { + if (it1 != null) + if (!it1.hasNext()) + it1 = null; + else + return true; + + return it2.hasNext(); + } + + @Override public T next() { + return it1 != null ? it1.next() : it2.next(); + } + + @Override public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + @Override public boolean contains(Object o) { + return c1.contains(o) || c2.contains(o); + } + + @Override public int size() { + return c1.size() + c2.size(); + } + + @Override public boolean equals(Object obj) { + return obj instanceof Collection && eqNotOrdered(this, (Collection)obj); + } + }; + } } /** - * Gets reducer which always returns {@code true} from {@link org.apache.ignite.lang.IgniteReducer#collect(Object)} - * method and passed in {@code element} from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. + * Concatenates an elements to an array. * - * @param elem Element to return from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. - * @param Reducer element type. - * @param Return element type. - * @return Passed in element. + * @param arr Array. + * @param obj One or more elements. + * @return Concatenated array. */ - public static IgniteReducer continuousReducer(final R elem) { - return new R1() { - @Override public boolean collect(T e) { - return true; - } + public static T[] concat(@Nullable T[] arr, T... obj) { + T[] newArr; - @Override public R reduce() { - return elem; - } - }; + if (arr == null || arr.length == 0) + newArr = obj; + else { + newArr = Arrays.copyOf(arr, arr.length + obj.length); + + System.arraycopy(obj, 0, newArr, arr.length, obj.length); + } + + return newArr; } /** - * Gets reducer which always returns {@code true} from {@link org.apache.ignite.lang.IgniteReducer#collect(Object)} - * method and passed in {@code element} from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. + * Concatenates multiple iterators as single one. * - * @param elem Element to return from {@link org.apache.ignite.lang.IgniteReducer#reduce()} method. - * @param Reducer element type. - * @return Passed in element. + * @param iters Iterators. + * @return Single iterator. */ - public static IgniteReducer identityReducer(final T elem) { - return new R1() { - @Override public boolean collect(T e) { - return true; - } + @SuppressWarnings("unchecked") + public static Iterator concat(Iterator ... iters) { + if (iters.length == 1) + return iters[0]; - @Override public T reduce() { - return elem; - } - }; + return concat(asList(iters).iterator()); } /** - * Gets reducer closure that calculates harmonic mean. - *

- * + * Concatenates multiple iterators as single one. * - * @return Reducer closure that calculated harmonic mean. + * @param iters Iterator over iterators. + * @return Single iterator. */ - public static IgniteReducer havgReducer() { - return new R1() { - private double sum; - private int i; + @SuppressWarnings("unchecked") + public static Iterator concat(final Iterator> iters) { + if (!iters.hasNext()) + return Collections.emptySet().iterator(); - private final Object lock = new Object(); + return new Iterator() { + private Iterator it = iters.next(); - @Override public boolean collect(T e) { - if (e != null) - synchronized (lock) { - sum += 1 / e.doubleValue(); + private Iterator last; - i++; - } + private T next; - return true; + { + advance(); } - @Override public Double reduce() { - synchronized (lock) { - return i / sum; - } - } - }; - } + private void advance() { + for (;;) { + if (it.hasNext()) { + next = it.next(); - /** - * Gets reducer closure that calculates sum of integer elements. - *

- * - * - * @return Reducer that calculates sum of integer elements. - */ - public static IgniteReducer sumIntReducer() { - return new R1() { - private AtomicInteger sum = new AtomicInteger(0); + assert next != null; - @Override public boolean collect(Integer e) { - if (e != null) - sum.addAndGet(e); + return; + } - return true; - } + if (!iters.hasNext()) + return; - @Override public Integer reduce() { - return sum.get(); + it = iters.next(); + } } - }; - } - - /** - * Gets reducer closure that calculates sum of long integer elements. - *

- * - * - * @return Reducer that calculates sum of long integer elements. - */ - public static IgniteReducer sumLongReducer() { - return new R1() { - private AtomicLong sum = new AtomicLong(0); - @Override public boolean collect(Long e) { - if (e != null) - sum.addAndGet(e); - - return true; + @Override public boolean hasNext() { + return next != null; } - @Override public Long reduce() { - return sum.get(); - } - }; - } + @Override public T next() { + T res = next; - /** - * Gets reducer closure that calculates sum of all elements. - *

- * - * - * @return Reducer that calculates sum of all elements. - */ - @SuppressWarnings("unchecked") - public static IgniteReducer sumDoubleReducer() { - return new R1() { - private double sum; + if (res == null) + throw new NoSuchElementException(); - private final Object lock = new Object(); + next = null; - @Override public boolean collect(Double e) { - if (e != null) - synchronized (lock) { - sum += e; - } + last = it; - return true; + advance(); + + return res; } - @Override public Double reduce() { - synchronized (lock) { - return sum; - } + @Override public void remove() { + if (last == null) + throw new IllegalStateException(); + + last.remove(); } }; } /** - * Creates a range list containing numbers in given range. + * Loses all elements in input collection that are contained in {@code filter} collection. * - * @param fromIncl Inclusive start of the range. - * @param toExcl Exclusive stop of the range. - * @return List containing numbers in range. + * @param c Input collection. + * @param cp If {@code true} method creates new collection not modifying input, + * otherwise does in-place modifications. + * @param filter Filter collection. If {@code filter} collection is empty or + * {@code null} - no elements are lost. + * @param Type of collections. + * @return Collection of remaining elements */ - public static List range(int fromIncl, int toExcl) { - A.ensure(fromIncl >= 0, "fromIncl >= 0"); - A.ensure(toExcl >= 0, "toExcl >= 0"); - A.ensure(toExcl >= fromIncl, "toExcl > fromIncl"); - - if (toExcl == fromIncl) - return Collections.emptyList(); - - List list = new ArrayList<>(toExcl - fromIncl); - - for (int i = fromIncl; i < toExcl; i++) - list.add(i); + public static Collection lose(Collection c, boolean cp, + @Nullable Collection filter) { + A.notNull(c, "c"); - return list; + return lose(c, cp, F0.in(filter)); } /** - * Gets reducer closure that calculates sum of all elements. - *

- * + * Loses all elements in input collection that are evaluated to {@code true} by + * all given predicates. * - * @return Reducer that calculates sum of all elements. + * @param c Input collection. + * @param cp If {@code true} method creates new collection without modifying the input one, + * otherwise does in-place modifications. + * @param p Predicates to filter by. If no predicates provided - no elements are lost. + * @param Type of collections. + * @return Collection of remaining elements. */ - @SuppressWarnings("unchecked") - public static IgniteReducer sumBigDecimalReducer() { - return new R1() { - private BigDecimal sum = BigDecimal.ZERO; + public static Collection lose(Collection c, boolean cp, @Nullable IgnitePredicate... p) { + A.notNull(c, "c"); - private final Object lock = new Object(); + Collection res; - @Override public boolean collect(BigDecimal e) { - if (e != null) - synchronized (lock) { - sum = sum.add(e); - } + if (!cp) { + res = c; - return true; - } + if (isEmpty(p)) + res.clear(); + else if (!isAlwaysFalse(p)) + for (Iterator iter = res.iterator(); iter.hasNext();) + if (isAll(iter.next(), p)) + iter.remove(); + } + else { + res = new LinkedList<>(); - @Override public BigDecimal reduce() { - synchronized (lock) { - return sum; - } - } - }; + if (!isEmpty(p) && !isAlwaysTrue(p)) + for (T t : c) + if (!isAll(t, p)) + res.add(t); + } + + return res; } /** - * Gets reducer closure that calculates sum of all elements. - *

- * + * Loses all entries in input map that are evaluated to {@code true} by all given predicates. * - * @return Reducer that calculates sum of all elements. + * @param m Map to filter. + * @param cp If {@code true} method creates new map not modifying input, otherwise does + * in-place modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original map + * will (or its copy) be returned. + * @param Type of the free variable for the predicate and type of map's keys. + * @param Type of the free variable for the predicate and type of map's values. + * @return Filtered map. */ - @SuppressWarnings("unchecked") - public static IgniteReducer sumBigIntegerReducer() { - return new R1() { - private BigInteger sum = BigInteger.ZERO; + @SuppressWarnings({"unchecked"}) + public static Map lose(Map m, boolean cp, + @Nullable IgnitePredicate>... p) { + A.notNull(m, "m"); - private final Object lock = new Object(); + Map res; - @Override public boolean collect(BigInteger e) { - if (e != null) - synchronized (lock) { - sum = sum.add(e); - } + if (!cp) { + res = m; - return true; - } + if (isEmpty(p)) + res.clear(); + else if (!isAlwaysFalse(p)) + for (Iterator> iter = m.entrySet().iterator(); iter.hasNext();) + if (isAll(iter.next(), p)) + iter.remove(); + } + else { + res = U.newHashMap(m.size()); - @Override public BigInteger reduce() { - synchronized (lock) { - return sum; - } - } - }; + if (!isEmpty(p) && !isAlwaysTrue(p)) + for (Map.Entry e : m.entrySet()) + if (!F.isAll(e, p)) + res.put(e.getKey(), e.getValue()); + } + + return res; } /** - * Gets reducer closure that concatenates strings using provided delimiter. + * Loses all entries in input map which keys are evaluated to {@code true} by all + * given predicates. * - * @param delim Delimiter (optional). - * @return Reducer that concatenates strings using provided delimeter. + * @param m Map to filter. + * @param cp If {@code true} method creates new map not modifying input, otherwise does + * in-place modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original + * map (or its copy) will be returned. + * @param Type of the free variable for the predicate and type of map's keys. + * @param Type of map's values. + * @return Filtered map. */ - public static IgniteReducer concatReducer(@Nullable final String delim) { - return new R1() { - private SB sb = new SB(); - - private boolean first = true; - - private final Object lock = new Object(); - - @Override public boolean collect(String s) { - synchronized (lock) { - if (!first && !isEmpty(delim)) - sb.a(delim); - - sb.a(s); - - first = false; - } - - return true; - } - - @Override public String reduce() { - synchronized (lock) { - return sb.toString(); - } + public static Map loseKeys( + Map m, + boolean cp, + @Nullable final IgnitePredicate... p + ) { + return lose(m, cp, new P1>() { + @Override public boolean apply(Map.Entry e) { + return isAll(e.getKey(), p); } - }; + }); } /** - * Concatenates strings using provided delimiter. + * Loses all entries in input map which values are evaluated to {@code true} by all + * given predicates. * - * @param c Input collection. - * @param delim Delimiter (optional). - * @return Concatenated string. + * @param m Map to filter. + * @param cp If {@code true} method creates new map not modifying input, otherwise does + * in-place modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original + * map (or its copy) will be returned. + * @param Type of the free variable for the predicate and type of map's keys. + * @param Type of map's values. + * @return Filtered map. */ - public static String concat(Iterable c, @Nullable String delim) { - A.notNull(c, "c"); - - return reduce(c, concatReducer(delim)); + public static Map loseValues(Map m, boolean cp, + @Nullable final IgnitePredicate... p) { + return lose(m, cp, new P1>() { + @Override public boolean apply(Map.Entry e) { + return isAll(e.getValue(), p); + } + }); } /** - * Gets collections of data items from grid job res casted to specified type. - *

- * Here's the typical example of how this method is used in {@code reduce()} method - * implementation (this example sums up all the values of {@code Integer} type): - *

-     * public Integer reduce(List<GridComputeJobResult> res) throws IgniteCheckedException {
-     *     return F.sum(F.<Integer>jobResults(res));
-     * }
-     * 
- *

- * Note that this method doesn't create a new collection but simply iterates over the input one. + * Loses all elements in input list that are contained in {@code filter} collection. * - * @param res Collection of grid job res. - * @param Type of the data item to cast to. See {@link org.apache.ignite.compute.ComputeJobResult#getData()} method. - * @return Collections of data items casted to type {@code T}. - * @see org.apache.ignite.compute.ComputeJobResult#getData() + * @param c Input list. + * @param cp If {@code true} method creates new list not modifying input, + * otherwise does in-place modifications. + * @param filter Filter collection. If {@code filter} collection is empty or + * {@code null} - no elements are lost. + * @param Type of list. + * @return List of remaining elements */ - public static Collection jobResults(@Nullable Collection res) { - if (isEmpty(res)) - return Collections.emptyList(); + public static List loseList(List c, boolean cp, @Nullable Collection filter) { + A.notNull(c, "c"); - assert res != null; + List res; - Collection c = new ArrayList<>(res.size()); + if (!cp) { + res = c; - for (ComputeJobResult r : res) - c.add(r.getData()); + if (filter != null) + res.removeAll(filter); + } + else { + res = new LinkedList<>(); - return c; + for (T t : c) { + if (filter == null || !filter.contains(t)) + res.add(t); + } + } + + return res; } /** - * Convenient utility method that returns collection of node IDs for a given - * collection of grid nodes. - *

- * Note that this method doesn't create a new collection but simply iterates - * over the input one. + * Loses all elements in input list for which any of the predicates evaluate to {@code true}. * - * @param nodes Collection of grid nodes. - * @return Collection of node IDs for given collection of grid nodes. + * @param c Input list. + * @param cp If {@code true} method creates new list not modifying input, + * otherwise does in-place modifications. + * @param p Looses all elements for which any of the predicates evaluate to {@code true}. + * @param Type of list. + * @return List of remaining elements */ - public static Collection nodeIds(@Nullable Collection nodes) { - if (nodes == null || nodes.isEmpty()) - return Collections.emptyList(); + public static List filterList(List c, boolean cp, @Nullable IgnitePredicate... p) { + A.notNull(c, "c"); - return F.viewReadOnly(nodes, node2id()); - } + List res; - /** - * Convenient utility method that returns collection of node ID8s for a given - * collection of grid nodes. ID8 is a shorter string representation of node ID, - * mainly the first 8 characters. - *

- * Note that this method doesn't create a new collection but simply iterates - * over the input one. - * - * @param nodes Collection of grid nodes. - * @return Collection of node IDs for given collection of grid nodes. - */ - public static Collection nodeId8s(@Nullable Collection nodes) { - if (nodes == null || nodes.isEmpty()) - return Collections.emptyList(); + if (!cp) { + res = c; - return F.viewReadOnly(nodes, node2id8()); - } + if (p != null) + for (Iterator it = c.iterator(); it.hasNext();) + if (isAny(it.next(), p)) + it.remove(); + } + else { + res = new ArrayList<>(c.size()); - /** - * Convenient utility method that returns collection of node ID8s for a given - * collection of node IDs. ID8 is a shorter string representation of node ID, - * mainly the first 8 characters. - *

- * Note that this method doesn't create a new collection but simply iterates - * over the input one. - * - * @param ids Collection of nodeIds. - * @return Collection of node IDs for given collection of grid nodes. - */ - public static Collection id8s(@Nullable Collection ids) { - if (ids == null || ids.isEmpty()) - return Collections.emptyList(); + for (T t : c) + if (!isAny(t, p)) + res.add(t); + } - return F.viewReadOnly(ids, id2id8()); + return res; } /** - * Convenient utility method that returns collection of node attributes for a given - * collection of grid nodes. - *

- * Note that this method doesn't create a new collection but simply iterates over the input one. + * Gets closure which converts node to node ID. * - * @param nodes Collection of grid nodes. - * @param attr Name of the attribute to return from each node. - * @param Type of the attribute. - * @return Collection of node attributes for given collection of grid nodes. + * @return Closure which converts node to node ID. */ - public static Collection nodeAttributes(Collection nodes, String attr) { - A.notNull(nodes, "nodes", attr, "attr"); - - Collection c = new ArrayList<>(nodes.size()); - - for (ClusterNode n : nodes) - c.add(n.attribute(attr)); - - return c; + public static IgniteClosure node2id() { + return NODE2ID; } /** - * Gets closure that calls {@code System.out.println()} on its bound variable. + * Creates grid node predicate evaluating on the given node ID. * - * @param Type of the bound variable. - * @return Closure that calls {@code System.out.println()} on its bound variable. + * @param nodeId Node ID for which returning predicate will evaluate to {@code true}. + * @return Grid node predicate evaluating on the given node ID. + * @see #idForNodeId(UUID) + * @see #nodeIds(Collection) */ - @SuppressWarnings("unchecked") - public static IgniteInClosure println() { - return (IgniteInClosure)PRINTLN; - } + public static IgnitePredicate nodeForNodeId(final UUID nodeId) { + A.notNull(nodeId, "nodeId"); - /** - * Creates absolute closure that does System.out.println(msg). - * - * @param msg Message to print. - * @return Absolute closure that print message. - */ - public static GridAbsClosure println(final String msg) { - return new CA() { - @Override public void apply() { - System.out.println(msg); + return new P1() { + @Override public boolean apply(ClusterNode e) { + return e.id().equals(nodeId); } }; } /** - * Creates absolute closure that does System.out.print(msg). + * Creates grid node predicate evaluating on the given node IDs. * - * @param msg Message to print. - * @return Absolute closure that print message. + * @param nodeIds Collection of node IDs. + * @return Grid node predicate evaluating on the given node IDs. + * @see #idForNodeId(UUID) + * @see #nodeIds(Collection) */ - public static GridAbsClosure print(final String msg) { - return new CA() { - @Override public void apply() { - System.out.print(msg); - } - }; - } + public static IgnitePredicate nodeForNodeIds(@Nullable final Collection + nodeIds) { + if (isEmpty(nodeIds)) + return alwaysFalse(); - /** - * Gets closure that prints out its bound variable. - * - * @param pre String value to print before each variable. - * @param post String value to print after each variable. - * @param Type of the bound variable. - * @return Closure that calls {@code System.out.print(pre); System.out.print(t); System.out.println(post)} - * on its bound variable. - */ - public static IgniteInClosure println(@Nullable final String pre, @Nullable final String post) { - return new CI1() { - @Override public void apply(T t) { - String sPre = pre == null ? "" : pre; - String sPost = post == null ? "" : post; + assert nodeIds != null; - System.out.println(sPre + t + sPost); + return new P1() { + @Override public boolean apply(ClusterNode e) { + return nodeIds.contains(e.id()); } }; } /** - * Gets closure that prints out its bound variable. + * Creates {@link UUID} predicate evaluating on the given node ID. * - * @param fmt Format string as for {@link PrintStream#printf(String, Object...)} method. - * @param Type of the bound variable. - * @return Closure that prints out its bound variable. + * @param nodeId Node ID for which returning predicate will evaluate to {@code true}. + * @return {@link UUID} predicate evaluating on the given node ID. + * @see #nodeForNodeId(UUID) + * @see #nodeIds(Collection) */ - public static IgniteInClosure printf(final String fmt) { - return new CI1() { - @Override public void apply(T t) { - System.out.printf(fmt, t); + public static IgnitePredicate idForNodeId(final UUID nodeId) { + A.notNull(nodeId, "nodeId"); + + return new P1() { + @Override public boolean apply(UUID id) { + return id.equals(nodeId); } }; } /** - * Gets closure that prints out its bound variable + * Creates predicates that evaluates to {@code true} for each node in given collection. + * Note that if collection is empty the result predicate will always evaluate to {@code false}. + * Implementation simply creates {@link GridNodePredicate} instance. * - * @return Closure that prints out its bound variable. + * @param nodes Collection of nodes. If none provided - result predicate will always + * return {@code false}. + * @return Predicates that evaluates to {@code true} for each node in given collection. */ - @SuppressWarnings("unchecked") - public static IgniteInClosure print() { - return (IgniteInClosure)PRINT; + public static IgnitePredicate nodeForNodes(ClusterNode... nodes) { + return new GridNodePredicate(nodes); } /** - * Gets closure that prints out its bound variable. + * Retains all elements in input collection that are contained in {@code filter}. * - * @param pre String value to print before each variable. - * @param post String value to print after each variable. - * @return Closure that prints out its bound variable. + * @param c Input collection. + * @param cp If {@code true} method creates collection not modifying input, otherwise does + * in-place modifications. + * @param filter Filter collection. If filter collection is {@code null} or empty - + * an empty collection will be returned. + * @param Type of collections. + * @return Collection of retain elements. */ - public static IgniteInClosure print(@Nullable final String pre, @Nullable final String post) { - return new CI1() { - @Override public void apply(T t) { - String sPre = pre == null ? "" : pre; - String sPost = post == null ? "" : post; + public static Collection retain(Collection c, boolean cp, + @Nullable Collection filter) { + A.notNull(c, "c"); - System.out.print(sPre + t + sPost); - } - }; + return retain(c, cp, F0.in(filter)); } /** - * Gets random value from given collection. + * Retains all elements in input collection that are evaluated to {@code true} + * by all given predicates. * - * @param c Input collection (no {@code null} and not emtpy). - * @param Type of the collection. - * @return Random value from the input collection. + * @param c Input collection. + * @param cp If {@code true} method creates collection not modifying input, otherwise does + * in-place modifications. + * @param p Predicates to filter by. If no predicates provides - all elements + * will be retained. + * @param Type of collections. + * @return Collection of retain elements. */ - @SuppressWarnings("UnusedDeclaration") - public static T rand(Collection c) { + public static Collection retain(Collection c, boolean cp, @Nullable IgnitePredicate... p) { A.notNull(c, "c"); - int n = ThreadLocalRandom8.current().nextInt(c.size()); - - int i = 0; - - for (T t : c) { - if (i++ == n) - return t; - } - - throw new ConcurrentModificationException(); + return lose(c, cp, not(p)); } /** - * Gets random value from given collection which may be modified concurrently. + * Retains only up to first {@code num} elements in the input collection. * * @param c Input collection. - * @param Type of the collection. - * @return Random value from the input collection. + * @param cp If {@code true} method creates collection not modifying input, otherwise does + * in-place modifications. + * @param num Maximum number of elements to retain (the actual number can be + * less if the input collection contains less elements). + * @param Type of the collections. + * @return Collection contains up to {@code num} first elements from the input collection. */ - @Nullable public static T randConcurrent(Collection c) { + public static Collection retain(Collection c, boolean cp, int num) { A.notNull(c, "c"); + A.ensure(num >= 0, "num >= 0"); - int size = c.size(); + Collection res; - if (size == 0) - return null; + if (!cp) { + res = c; - int n = ThreadLocalRandom8.current().nextInt(size); + if (num < res.size()) { + int i = 0; - int i = 0; + for (Iterator iter = res.iterator(); iter.hasNext();) { + iter.next(); - T res = null; + if (i++ >= num) + iter.remove(); + } + } + } + else { + res = new ArrayList<>(num); - for (T t : c) { - if (i++ == n) - return t; + Iterator iter = c.iterator(); - res = t; + for (int i = 0; i < num && iter.hasNext(); i++) + res.add(iter.next()); } return res; } /** - * Gets random value from given list. For random-access lists this - * operation is O(1), otherwise O(n). + * Curries given closure. * - * @param l Input collection. - * @param Type of the list elements. - * @return Random value from the input list. + * @param f Closure. + * @param e Parameter. + * @param Input type. + * @param Output type. + * @return Curried closure. */ - public static T rand(List l) { - A.notNull(l, "l"); - - return l.get(ThreadLocalRandom8.current().nextInt(l.size())); + public static IgniteOutClosure curry(final IgniteClosure f, final T e) { + return new IgniteOutClosure() { + @Override public R apply() { + return f.apply(e); + } + }; } /** - * Gets random value from given array. This operation - * does not iterate through array elements and returns immediately. + * Curries given closure. * - * @param c Input collection. - * @param Type of the collection. - * @return Random value from the input collection. + * @param f Closure. + * @param e Parameter. + * @param Input type. + * @return Curried closure. */ - public static T rand(T... c) { - A.notNull(c, "c"); - - return c[ThreadLocalRandom8.current().nextInt(c.length)]; + public static GridAbsClosure curry(final IgniteInClosure f, final T e) { + return new GridAbsClosure() { + @Override public void apply() { + f.apply(e); + } + }; } /** - * Concatenates an element to a collection. If {@code copy} flag is {@code true}, then - * a new collection will be created and the element and passed in collection will be - * copied into the new one. The returned collection will be modifiable. If {@code copy} - * flag is {@code false}, then a read-only view will be created over the element and given - * collections and no copying will happen. + * Converts array to {@link List}. Note that resulting list cannot + * be altered in size, as it it based on the passed in array - + * only current elements can be changed. + *

+ * Note that unlike {@link Arrays#asList(Object[])}, this method is + * {@code null}-safe. If {@code null} is passed in, then empty list + * will be returned. * - * @param cp Copy flag. - * @param t First element. - * @param c Second collection. - * @param Element type. - * @return Concatenated collection. + * @param vals Array of values + * @param Array type. + * @return {@link List} instance for array. */ - public static Collection concat(boolean cp, @Nullable final T t, @Nullable final Collection c) { - if (cp) { - if (isEmpty(c)) { - Collection l = new ArrayList<>(1); + public static List asList(@Nullable T... vals) { + return isEmpty(vals) ? Collections.emptyList() : Arrays.asList(vals); + } - l.add(t); + /** + * Creates new empty iterator. + * + * @param Type of the iterator. + * @return Newly created empty iterator. + */ + public static GridIterator emptyIterator() { + return new GridEmptyIterator<>(); + } - return l; + /** + * Flattens collection-of-collections and returns collection over the + * elements of the inner collections. This method doesn't create any + * new collections or copies any elements. + *

+ * Note that due to non-copying nature of implementation, the + * {@link Collection#size() size()} method of resulting collection will have to + * iterate over all elements to produce size. Method {@link Collection#isEmpty() isEmpty()}, + * however, is constant time and is much more preferable to use instead + * of {@code 'size()'} method when checking if list is not empty. + * + * @param c Input collection of collections. + * @param Type of the inner collections. + * @return Iterable over the elements of the inner collections. + */ + public static Collection flatCollections(@Nullable final Collection> c) { + if (F.isEmpty(c)) + return Collections.emptyList(); + + return new GridSerializableCollection() { + @NotNull + @Override public Iterator iterator() { + return flat((Iterable>)c); } - assert c != null; + @Override public int size() { + return F.size(iterator()); + } - Collection ret = new ArrayList<>(c.size() + 1); + @Override public boolean isEmpty() { + return !iterator().hasNext(); + } + }; + } - ret.add(t); - ret.addAll(c); + /** + * Flattens iterable-of-iterables and returns iterable over the + * elements of the inner collections. This method doesn't create any + * new collections or copies any elements. + * + * @param c Input collection of collections. + * @param Type of the inner collections. + * @return Iterable over the elements of the inner collections. + */ + public static GridIterator flat(@Nullable final Iterable> c) { + return isEmpty(c) ? GridFunc.emptyIterator() : new GridIteratorAdapter() { + /** */ + private Iterator> a = c.iterator(); - return ret; - } - else { - if (isEmpty(c)) - return Collections.singletonList(t); + /** */ + private Iterator b; - assert c != null; + /** */ + private boolean moved = true; - return new GridSerializableCollection() { - @NotNull - @Override public Iterator iterator() { - return new GridSerializableIterator() { - private Iterator it; + /** */ + private boolean more; - @Override public boolean hasNext() { - return it == null || it.hasNext(); - } + @Override public boolean hasNextX() { + if (!moved) + return more; - @Nullable @Override public T next() { - if (it == null) { - it = c.iterator(); + moved = false; - return t; - } + if (b != null && b.hasNext()) + return more = true; - return it.next(); - } + while (a.hasNext()) { + b = a.next().iterator(); - @Override public void remove() { - throw new UnsupportedOperationException(); - } - }; + if (b.hasNext()) + return more = true; } - @Override public int size() { - return c.size() + 1; - } + return more = false; + } - @Override public boolean equals(Object obj) { - return obj instanceof Collection && eqNotOrdered(this, (Collection)obj); + @Override public T nextX() { + if (hasNext()) { + moved = true; + + return b.next(); } - }; - } + + throw new NoSuchElementException(); + } + + @Override public void removeX() { + assert b != null; + + b.remove(); + } + }; } /** - * Concatenates 2 collections into one. If {@code copy} flag is {@code true}, then - * a new collection will be created and these collections will be copied into the - * new one. The returned collection will be modifiable. If {@code copy} flag is - * {@code false}, then a read-only view will be created over given collections - * and no copying will happen. + * Flattens iterable-of-iterators and returns iterator over the + * elements of the inner collections. This method doesn't create any + * new collections or copies any elements. * - * @param cp Copy flag. - * @param c1 First collection. - * @param c2 Second collection. - * @param Element type. - * @return Concatenated {@code non-null} collection. + * @param c Input iterable of iterators. + * @return Iterator over the elements of given iterators. */ - public static Collection concat(boolean cp, @Nullable final Collection c1, - @Nullable final Collection c2) { - if (cp) { - if (isEmpty(c1) && isEmpty(c2)) - return new ArrayList<>(0); + public static Iterator flatIterators(@Nullable final Iterable> c) { + return isEmpty(c) ? GridFunc.emptyIterator() : new GridIteratorAdapter() { + /** */ + private Iterator> a = c.iterator(); - if (isEmpty(c1)) - return new ArrayList<>(c2); + /** */ + private Iterator b; - if (isEmpty(c2)) - return new ArrayList<>(c1); + /** */ + private boolean moved = true; - assert c1 != null && c2 != null; + /** */ + private boolean more; - Collection c = new ArrayList<>(c1.size() + c2.size()); + @Override public boolean hasNextX() { + if (!moved) + return more; - c.addAll(c1); - c.addAll(c2); + moved = false; - return c; - } - else { - if (isEmpty(c1) && isEmpty(c2)) - return Collections.emptyList(); + if (b != null && b.hasNext()) + return more = true; - if (isEmpty(c1) || isEmpty(c2)) { - Collection c = isEmpty(c1) ? c2 : c1; + while (a.hasNext()) { + b = a.next(); - assert c != null; + if (b.hasNext()) + return more = true; + } - return c; + return more = false; } - assert c1 != null && c2 != null; - - return new GridSerializableCollection() { - @NotNull - @Override public Iterator iterator() { - return new GridSerializableIterator() { - private Iterator it1 = c1.iterator(); - private Iterator it2 = c2.iterator(); - - @Override public boolean hasNext() { - if (it1 != null) - if (!it1.hasNext()) - it1 = null; - else - return true; - - return it2.hasNext(); - } - - @Override public T next() { - return it1 != null ? it1.next() : it2.next(); - } + @Override public T nextX() { + if (hasNext()) { + moved = true; - @Override public void remove() { - throw new UnsupportedOperationException(); - } - }; + return b.next(); } - @Override public boolean contains(Object o) { - return c1.contains(o) || c2.contains(o); - } + throw new NoSuchElementException(); + } - @Override public int size() { - return c1.size() + c2.size(); - } + @Override public void removeX() { + assert b != null; - @Override public boolean equals(Object obj) { - return obj instanceof Collection && eqNotOrdered(this, (Collection)obj); - } - }; - } + b.remove(); + } + }; } /** - * Concatenates an elements to an array. + * Converts given runnable to an absolute closure. * - * @param arr Array. - * @param obj One or more elements. - * @return Concatenated array. + * @param r Runnable to convert to closure. If {@code null} - no-op closure is returned. + * @return Closure that wraps given runnable. Note that wrapping closure always returns {@code null}. */ - public static T[] concat(@Nullable T[] arr, T... obj) { - T[] newArr; - - if (arr == null || arr.length == 0) - newArr = obj; - else { - newArr = Arrays.copyOf(arr, arr.length + obj.length); - - System.arraycopy(obj, 0, newArr, arr.length, obj.length); - } - - return newArr; - } + public static GridAbsClosure as(@Nullable final Runnable r) { + return new CA() { + @Override public void apply() { + if (r != null) + r.run(); + } + }; + } /** - * Concatenates multiple iterators as single one. + * Gets size of the given collection with provided optional predicates. * - * @param iters Iterators. - * @return Single iterator. + * @param c Collection to size. + * @param p Optional predicates that filters out elements from count. + * @param Type of the iterator. + * @return Number of elements in the collection for which all given predicates + * evaluates to {@code true}. If no predicates is provided - all elements are counted. */ - @SuppressWarnings("unchecked") - public static Iterator concat(Iterator ... iters) { - if (iters.length == 1) - return iters[0]; - - return concat(asList(iters).iterator()); + public static int size(@Nullable Collection c, @Nullable IgnitePredicate... p) { + return c == null || c.isEmpty() ? 0 : isEmpty(p) || isAlwaysTrue(p) ? c.size() : size(c.iterator(), p); } /** - * Concatenates multiple iterators as single one. + * Gets size of the given iterator with provided optional predicates. Iterator + * will be traversed to get the count. * - * @param iters Iterator over iterators. - * @return Single iterator. + * @param it Iterator to size. + * @param p Optional predicates that filters out elements from count. + * @param Type of the iterator. + * @return Number of elements in the iterator for which all given predicates + * evaluates to {@code true}. If no predicates is provided - all elements are counted. */ - @SuppressWarnings("unchecked") - public static Iterator concat(final Iterator> iters) { - if (!iters.hasNext()) - return Collections.emptySet().iterator(); - - return new Iterator() { - privat