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<Boolean> IDENTITY_PRED = new P1<Boolean>() { - @Override public boolean apply(Boolean e) { - return e; - } - }; - - /** */ private static final IgnitePredicate<Object> ALWAYS_TRUE = new P1<Object>() { @Override public boolean apply(Object e) { return true; @@ -128,34 +116,6 @@ public class GridFunc { }; /** */ - public static final IgnitePredicate<String> EMPTY_STRING = new P1<String>() { - @Override public boolean apply(String s) { - return isEmpty(s); - } - }; - - /** */ - public static final IgnitePredicate<String> NOT_EMPTY_STRING = new P1<String>() { - @Override public boolean apply(String s) { - return !isEmpty(s); - } - }; - - /** */ - public static final IgnitePredicate EMPTY_COLLECTION = new P1<Collection>() { - @Override public boolean apply(Collection c) { - return isEmpty(c); - } - }; - - /** */ - public static final IgnitePredicate NOT_EMPTY_COLLECTION = new P1<Collection>() { - @Override public boolean apply(Collection c) { - return !isEmpty(c); - } - }; - - /** */ private static final IgniteCallable<?> LIST_FACTORY = new IgniteCallable<List>() { @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<Runnable, GridAbsClosure> R2C = new C1<Runnable, GridAbsClosure>() { - @Override public GridAbsClosure apply(Runnable r) { - return as(r); - } - - @Override public String toString() { - return "Runnable to absolute closure transformer."; - } - }; - - /** */ - private static final IgniteClosure<ClusterGroup, IgnitePredicate<ClusterNode>> P2P = - new C1<ClusterGroup, IgnitePredicate<ClusterNode>>() { - @Override public IgnitePredicate<ClusterNode> apply(ClusterGroup e) { - return e.predicate(); - } - - @Override public String toString() { - return "Projection to its predicate transformer closure."; - } - }; - - /** */ - private static final IgniteClosure<Object, Class<?>> CLAZZ = new C1<Object, Class<?>>() { - @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<ClusterNode, UUID> NODE2ID = new IgniteClosure<ClusterNode, UUID>() { @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 <T> Predicate type. - * @return Breaker predicate. - */ - public static <T> IgnitePredicate<T> breaker(final boolean firstVal) { - return new IgnitePredicate<T>() { - 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<ClusterGroup, IgnitePredicate<ClusterNode>> 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 <T> IgniteOutClosure<T> nill() { - return (IgniteOutClosure<T>)NILL; - } - - /** - * Creates closure that will reflectively call a method with the given name on - * closure's argument and return result of that call. - * <p> - * 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 <R> Type of closure return value. - * @param <T> 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 <T> Type of the collection. + * @return De-duped collection. */ - public static <T, R> IgniteClosure<T, R> cInvoke(final String mtdName, final Object... args) { - A.notNull(mtdName, "mtdName"); - - return new C1<T, R>() { - private Method mtd; + public static <T> Collection<T> dedup(Collection<? extends T> 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<T> 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. * <p> - * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteClosure} which is {@link C1}. + * <img src="{@docRoot}/img/sum.png"> * - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param <T> 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 <T> IgniteInClosure<T> ciInvoke(final String mtdName, final Object... args) { - A.notNull(mtdName, "mtdName"); - - return new CI1<T>() { - private Method mtd; + public static int sumInt(Iterable<Integer> 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. - * <p> - * 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 <R> 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 <T> Reducer element type. + * @return Passed in element. */ - public static <R> IgniteOutClosure<R> coInvoke(final Object o, final String mtdName, final Object... args) { - A.notNull(o, "o", mtdName, "mtdName"); - - return new CO<R>() { - 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 <T> IgniteReducer<T, T> identityReducer(final T elem) { + return new R1<T, T>() { + @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. * <p> - * Method reflects the typedef for {@link GridAbsClosure} which is {@link CA}. + * <img src="{@docRoot}/img/sum.png"> * - * @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<Integer, Integer> sumIntReducer() { + return new R1<Integer, Integer>() { + 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. * <p> - * Method reflects the typedef for {@link org.apache.ignite.lang.IgniteOutClosure} which is {@link CO}. + * <img src="{@docRoot}/img/sum.png"> * - * @param cls Class to call a static method on. - * @param mtdName Method name. - * @param args Optional set of arguments for the method call. - * @param <R> 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 <R> IgniteOutClosure<R> coInvoke(final Class<?> cls, final String mtdName, - @Nullable final Object... args) { - A.notNull(cls, "cls", mtdName, "mtdName"); - - return new CO<R>() { - /** */ - private Method mtd; + public static IgniteReducer<Long, Long> sumLongReducer() { + return new R1<Long, Long>() { + 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. - * <p> - * 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<Integer> 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<Integer> 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<String, String> concatReducer(@Nullable final String delim) { + return new R1<String, String>() { + 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<Object, Class<?>> clazz() { - return CLAZZ; - } - - /** - * Creates new collection by removing duplicates from the given collection. - * - * @param c Collection to remove duplicates from. - * @param <T> Type of the collection. - * @return De-duped collection. + * @param c Input collection. + * @param delim Delimiter (optional). + * @return Concatenated string. */ - public static <T> Collection<T> dedup(Collection<? extends T> c) { + public static String concat(Iterable<String> c, @Nullable String delim) { A.notNull(c, "c"); - Collection<T> 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. * <p> - * <img src="{@docRoot}/img/sum.png"> - * - * @param c Collection of elements. - * @return Sum of all elements. - */ - public static int sumInt(Iterable<Integer> 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): + * <pre name="code" class="java"> + * public Integer reduce(List<GridComputeJobResult> res) throws IgniteCheckedException { + * return F.sum(F.<Integer>jobResults(res)); + * } + * </pre> * <p> - * <img src="{@docRoot}/img/sum.png"> + * 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 <T> 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<Double> c) { - A.notNull(c, "c"); + public static <T> Collection<T> jobResults(@Nullable Collection<? extends ComputeJobResult> res) { + if (isEmpty(res)) + return Collections.emptyList(); - double sum = 0; + assert res != null; - for (double t : c) { - sum += t; - } + Collection<T> c = new ArrayList<>(res.size()); - return sum; + for (ComputeJobResult r : res) + c.add(r.<T>getData()); + + return c; } /** - * Calculates sum of all elements. + * Convenient utility method that returns collection of node IDs for a given + * collection of grid nodes. * <p> - * <img src="{@docRoot}/img/sum.png"> + * 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<BigDecimal> c) { - A.notNull(c, "c"); - - BigDecimal sum = BigDecimal.ZERO; - - for (BigDecimal t : c) { - sum = sum.add(t); - } + public static Collection<UUID> nodeIds(@Nullable Collection<? extends ClusterNode> 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. * <p> - * <img src="{@docRoot}/img/sum.png"> + * 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<BigInteger> c) { - A.notNull(c, "c"); - - BigInteger sum = BigInteger.ZERO; - - for (BigInteger t : c) { - sum = sum.add(t); - } + public static Collection<String> nodeId8s(@Nullable Collection<? extends ClusterNode> 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. * <p> - * <img src="{@docRoot}/img/avg.png"> + * 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<? extends Number> c) { - A.notNull(c, "c"); - - double sum = 0; - - int i = 0; - - for (Number t : c) { - sum += t.doubleValue(); - - i++; - } + public static Collection<String> id8s(@Nullable Collection<UUID> ids) { + if (ids == null || ids.isEmpty()) + return Collections.emptyList(); - return sum / i; + return F.viewReadOnly(ids, ID2ID8); } /** - * Gets reducer closure that calculates arithmetic mean. - * <p> - * <img src="{@docRoot}/img/avg.png"> + * Creates absolute closure that does <tt>System.out.println(msg)</tt>. * - * @return Reducer closure that calculated arithmetic mean. + * @param msg Message to print. + * @return Absolute closure that print message. */ - public static <T extends Number> IgniteReducer<T, Double> avgReducer() { - return new R1<T, Double>() { - 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. - * <p> - * <img src="{@docRoot}/img/qavg.png"> + * 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 <T> Type of the collection. + * @return Random value from the input collection. */ - public static double qavg(Iterable<? extends Number> c) { + @SuppressWarnings("UnusedDeclaration") + public static <T> T rand(Collection<? extends T> 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. - * <p> - * <img src="{@docRoot}/img/qavg.png"> + * 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 <T> Type of the list elements. + * @return Random value from the input list. */ - public static <T extends Number> IgniteReducer<T, Double> qavgReducer() { - return new R1<T, Double>() { - 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> T rand(List<T> 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. - * <p> - * <img src="{@docRoot}/img/gavg.png"> + * 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 <T> Type of the collection. + * @return Random value from the input collection. */ - public static double gavg(Iterable<? extends Number> c) { + public static <T> 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. - * <p> - * <img src="{@docRoot}/img/gavg.png"> + * 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 <T> Element type. + * @return Concatenated collection. */ - public static <T extends Number> IgniteReducer<T, Double> gavgReducer() { - return new R1<T, Double>() { - private double sum; - private int i; + public static <T> Collection<T> concat(boolean cp, @Nullable final T t, @Nullable final Collection<T> c) { + if (cp) { + if (isEmpty(c)) { + Collection<T> 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<T> 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. - * <p> - * <img src="{@docRoot}/img/wavg.png"> - * - * @param c Collection of elements. - * @param w Collection of weights. - * @return Weighted mean of the input collection. - */ - public static double wavg(Collection<? extends Number> c, Collection<? extends Number> 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<? extends Number> iterC = c.iterator(); - Iterator<? extends Number> iterW = w.iterator(); + return new GridSerializableCollection<T>() { + @NotNull + @Override public Iterator<T> iterator() { + return new GridSerializableIterator<T>() { + private Iterator<T> 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. - * <p> - * <img src="{@docRoot}/img/havg.png"> + @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 <T> Element type. + * @return Concatenated {@code non-null} collection. */ - public static double havg(Iterable<? extends Number> c) { - A.notNull(c, "c"); + public static <T> Collection<T> concat(boolean cp, @Nullable final Collection<T> c1, + @Nullable final Collection<T> 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<T> 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 <T> IgniteReducer<T, T> singleReducer() { - return new R1<T, T>() { - private T obj; + if (isEmpty(c1) || isEmpty(c2)) { + Collection<T> 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<T>() { + @NotNull + @Override public Iterator<T> iterator() { + return new GridSerializableIterator<T>() { + private Iterator<T> it1 = c1.iterator(); + private Iterator<T> 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 <T> Reducer element type. - * @param <R> Return element type. - * @return Passed in element. + * @param arr Array. + * @param obj One or more elements. + * @return Concatenated array. */ - public static <T, R> IgniteReducer<T, R> continuousReducer(final R elem) { - return new R1<T, R>() { - @Override public boolean collect(T e) { - return true; - } + public static <T> 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 <T> Reducer element type. - * @return Passed in element. + * @param iters Iterators. + * @return Single iterator. */ - public static <T> IgniteReducer<T, T> identityReducer(final T elem) { - return new R1<T, T>() { - @Override public boolean collect(T e) { - return true; - } + @SuppressWarnings("unchecked") + public static <T> Iterator<T> concat(Iterator<T> ... 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. - * <p> - * <img src="{@docRoot}/img/havg.png"> + * Concatenates multiple iterators as single one. * - * @return Reducer closure that calculated harmonic mean. + * @param iters Iterator over iterators. + * @return Single iterator. */ - public static <T extends Number> IgniteReducer<T, Double> havgReducer() { - return new R1<T, Double>() { - private double sum; - private int i; + @SuppressWarnings("unchecked") + public static <T> Iterator<T> concat(final Iterator<Iterator<T>> iters) { + if (!iters.hasNext()) + return Collections.<T>emptySet().iterator(); - private final Object lock = new Object(); + return new Iterator<T>() { + private Iterator<T> it = iters.next(); - @Override public boolean collect(T e) { - if (e != null) - synchronized (lock) { - sum += 1 / e.doubleValue(); + private Iterator<T> 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. - * <p> - * <img src="{@docRoot}/img/sum.png"> - * - * @return Reducer that calculates sum of integer elements. - */ - public static IgniteReducer<Integer, Integer> sumIntReducer() { - return new R1<Integer, Integer>() { - 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. - * <p> - * <img src="{@docRoot}/img/sum.png"> - * - * @return Reducer that calculates sum of long integer elements. - */ - public static IgniteReducer<Long, Long> sumLongReducer() { - return new R1<Long, Long>() { - 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. - * <p> - * <img src="{@docRoot}/img/sum.png"> - * - * @return Reducer that calculates sum of all elements. - */ - @SuppressWarnings("unchecked") - public static IgniteReducer<Double, Double> sumDoubleReducer() { - return new R1<Double, Double>() { - 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 <tt>in-place</tt> modifications. + * @param filter Filter collection. If {@code filter} collection is empty or + * {@code null} - no elements are lost. + * @param <T> Type of collections. + * @return Collection of remaining elements */ - public static List<Integer> 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<Integer> list = new ArrayList<>(toExcl - fromIncl); - - for (int i = fromIncl; i < toExcl; i++) - list.add(i); + public static <T0, T extends T0> Collection<T> lose(Collection<T> c, boolean cp, + @Nullable Collection<T0> filter) { + A.notNull(c, "c"); - return list; + return lose(c, cp, F0.in(filter)); } /** - * Gets reducer closure that calculates sum of all elements. - * <p> - * <img src="{@docRoot}/img/sum.png"> + * 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 <tt>in-place</tt> modifications. + * @param p Predicates to filter by. If no predicates provided - no elements are lost. + * @param <T> Type of collections. + * @return Collection of remaining elements. */ - @SuppressWarnings("unchecked") - public static IgniteReducer<BigDecimal, BigDecimal> sumBigDecimalReducer() { - return new R1<BigDecimal, BigDecimal>() { - private BigDecimal sum = BigDecimal.ZERO; + public static <T> Collection<T> lose(Collection<T> c, boolean cp, @Nullable IgnitePredicate<? super T>... p) { + A.notNull(c, "c"); - private final Object lock = new Object(); + Collection<T> 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<T> 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. - * <p> - * <img src="{@docRoot}/img/sum.png"> + * 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 + * <tt>in-place</tt> modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original map + * will (or its copy) be returned. + * @param <K> Type of the free variable for the predicate and type of map's keys. + * @param <V> Type of the free variable for the predicate and type of map's values. + * @return Filtered map. */ - @SuppressWarnings("unchecked") - public static IgniteReducer<BigInteger, BigInteger> sumBigIntegerReducer() { - return new R1<BigInteger, BigInteger>() { - private BigInteger sum = BigInteger.ZERO; + @SuppressWarnings({"unchecked"}) + public static <K, V> Map<K, V> lose(Map<K, V> m, boolean cp, + @Nullable IgnitePredicate<? super Map.Entry<K, V>>... p) { + A.notNull(m, "m"); - private final Object lock = new Object(); + Map<K, V> 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<Map.Entry<K, V>> 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<K, V> 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 + * <tt>in-place</tt> modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original + * map (or its copy) will be returned. + * @param <K> Type of the free variable for the predicate and type of map's keys. + * @param <V> Type of map's values. + * @return Filtered map. */ - public static IgniteReducer<String, String> concatReducer(@Nullable final String delim) { - return new R1<String, String>() { - 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 <K, V> Map<K, V> loseKeys( + Map<K, V> m, + boolean cp, + @Nullable final IgnitePredicate<? super K>... p + ) { + return lose(m, cp, new P1<Map.Entry<K, V>>() { + @Override public boolean apply(Map.Entry<K, V> 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 + * <tt>in-place</tt> modifications. + * @param p Optional set of predicates to use for filtration. If none provided - original + * map (or its copy) will be returned. + * @param <K> Type of the free variable for the predicate and type of map's keys. + * @param <V> Type of map's values. + * @return Filtered map. */ - public static String concat(Iterable<String> c, @Nullable String delim) { - A.notNull(c, "c"); - - return reduce(c, concatReducer(delim)); + public static <K, V> Map<K, V> loseValues(Map<K, V> m, boolean cp, + @Nullable final IgnitePredicate<? super V>... p) { + return lose(m, cp, new P1<Map.Entry<K, V>>() { + @Override public boolean apply(Map.Entry<K, V> e) { + return isAll(e.getValue(), p); + } + }); } /** - * Gets collections of data items from grid job res casted to specified type. - * <p> - * 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): - * <pre name="code" class="java"> - * public Integer reduce(List<GridComputeJobResult> res) throws IgniteCheckedException { - * return F.sum(F.<Integer>jobResults(res)); - * } - * </pre> - * <p> - * 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 <T> 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 <tt>in-place</tt> modifications. + * @param filter Filter collection. If {@code filter} collection is empty or + * {@code null} - no elements are lost. + * @param <T> Type of list. + * @return List of remaining elements */ - public static <T> Collection<T> jobResults(@Nullable Collection<? extends ComputeJobResult> res) { - if (isEmpty(res)) - return Collections.emptyList(); + public static <T> List<T> loseList(List<T> c, boolean cp, @Nullable Collection<? super T> filter) { + A.notNull(c, "c"); - assert res != null; + List<T> res; - Collection<T> c = new ArrayList<>(res.size()); + if (!cp) { + res = c; - for (ComputeJobResult r : res) - c.add(r.<T>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. - * <p> - * 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 <tt>in-place</tt> modifications. + * @param p Looses all elements for which any of the predicates evaluate to {@code true}. + * @param <T> Type of list. + * @return List of remaining elements */ - public static Collection<UUID> nodeIds(@Nullable Collection<? extends ClusterNode> nodes) { - if (nodes == null || nodes.isEmpty()) - return Collections.emptyList(); + public static <T> List<T> filterList(List<T> c, boolean cp, @Nullable IgnitePredicate<T>... p) { + A.notNull(c, "c"); - return F.viewReadOnly(nodes, node2id()); - } + List<T> 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. - * <p> - * 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<String> nodeId8s(@Nullable Collection<? extends ClusterNode> nodes) { - if (nodes == null || nodes.isEmpty()) - return Collections.emptyList(); + if (!cp) { + res = c; - return F.viewReadOnly(nodes, node2id8()); - } + if (p != null) + for (Iterator<T> 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. - * <p> - * 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<String> id8s(@Nullable Collection<UUID> 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. - * <p> - * 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 <T> 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 <T> Collection<T> nodeAttributes(Collection<? extends ClusterNode> nodes, String attr) { - A.notNull(nodes, "nodes", attr, "attr"); - - Collection<T> c = new ArrayList<>(nodes.size()); - - for (ClusterNode n : nodes) - c.add(n.<T>attribute(attr)); - - return c; + public static IgniteClosure<ClusterNode, UUID> 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 <T> 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 <T> IgniteInClosure<T> println() { - return (IgniteInClosure<T>)PRINTLN; - } + public static <T extends ClusterNode> IgnitePredicate<T> nodeForNodeId(final UUID nodeId) { + A.notNull(nodeId, "nodeId"); - /** - * Creates absolute closure that does <tt>System.out.println(msg)</tt>. - * - * @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<T>() { + @Override public boolean apply(ClusterNode e) { + return e.id().equals(nodeId); } }; } /** - * Creates absolute closure that does <tt>System.out.print(msg)</tt>. + * 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 <T extends ClusterNode> IgnitePredicate<T> nodeForNodeIds(@Nullable final Collection<UUID> + 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 <T> 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 <T> IgniteInClosure<T> println(@Nullable final String pre, @Nullable final String post) { - return new CI1<T>() { - @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<T>() { + @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 <T> 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 <T> IgniteInClosure<T> printf(final String fmt) { - return new CI1<T>() { - @Override public void apply(T t) { - System.out.printf(fmt, t); + public static IgnitePredicate<UUID> idForNodeId(final UUID nodeId) { + A.notNull(nodeId, "nodeId"); + + return new P1<UUID>() { + @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 <T> IgniteInClosure<T> print() { - return (IgniteInClosure<T>)PRINT; + public static IgnitePredicate<ClusterNode> 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 + * <tt>in-place</tt> modifications. + * @param filter Filter collection. If filter collection is {@code null} or empty - + * an empty collection will be returned. + * @param <T> Type of collections. + * @return Collection of retain elements. */ - public static <T> IgniteInClosure<T> print(@Nullable final String pre, @Nullable final String post) { - return new CI1<T>() { - @Override public void apply(T t) { - String sPre = pre == null ? "" : pre; - String sPost = post == null ? "" : post; + public static <T0, T extends T0> Collection<T> retain(Collection<T> c, boolean cp, + @Nullable Collection<? extends T0> 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 <T> 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 + * <tt>in-place</tt> modifications. + * @param p Predicates to filter by. If no predicates provides - all elements + * will be retained. + * @param <T> Type of collections. + * @return Collection of retain elements. */ - @SuppressWarnings("UnusedDeclaration") - public static <T> T rand(Collection<? extends T> c) { + public static <T> Collection<T> retain(Collection<T> c, boolean cp, @Nullable IgnitePredicate<? super T>... 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 <T> Type of the collection. - * @return Random value from the input collection. + * @param cp If {@code true} method creates collection not modifying input, otherwise does + * <tt>in-place</tt> modifications. + * @param num Maximum number of elements to retain (the actual number can be + * less if the input collection contains less elements). + * @param <T> Type of the collections. + * @return Collection contains up to {@code num} first elements from the input collection. */ - @Nullable public static <T> T randConcurrent(Collection<? extends T> c) { + public static <T> Collection<T> retain(Collection<T> c, boolean cp, int num) { A.notNull(c, "c"); + A.ensure(num >= 0, "num >= 0"); - int size = c.size(); + Collection<T> 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<T> 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<? extends T> 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 <T> Type of the list elements. - * @return Random value from the input list. + * @param f Closure. + * @param e Parameter. + * @param <T> Input type. + * @param <R> Output type. + * @return Curried closure. */ - public static <T> T rand(List<T> l) { - A.notNull(l, "l"); - - return l.get(ThreadLocalRandom8.current().nextInt(l.size())); + public static <T, R> IgniteOutClosure<R> curry(final IgniteClosure<? super T, R> f, final T e) { + return new IgniteOutClosure<R>() { + @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 <T> Type of the collection. - * @return Random value from the input collection. + * @param f Closure. + * @param e Parameter. + * @param <T> Input type. + * @return Curried closure. */ - public static <T> T rand(T... c) { - A.notNull(c, "c"); - - return c[ThreadLocalRandom8.current().nextInt(c.length)]; + public static <T> GridAbsClosure curry(final IgniteInClosure<? super T> 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. + * <p> + * 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 <T> Element type. - * @return Concatenated collection. + * @param vals Array of values + * @param <T> Array type. + * @return {@link List} instance for array. */ - public static <T> Collection<T> concat(boolean cp, @Nullable final T t, @Nullable final Collection<T> c) { - if (cp) { - if (isEmpty(c)) { - Collection<T> l = new ArrayList<>(1); + public static <T> List<T> asList(@Nullable T... vals) { + return isEmpty(vals) ? Collections.<T>emptyList() : Arrays.asList(vals); + } - l.add(t); + /** + * Creates new empty iterator. + * + * @param <T> Type of the iterator. + * @return Newly created empty iterator. + */ + public static <T> GridIterator<T> 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. + * <p> + * 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 <T> Type of the inner collections. + * @return Iterable over the elements of the inner collections. + */ + public static <T> Collection<T> flatCollections(@Nullable final Collection<? extends Collection<T>> c) { + if (F.isEmpty(c)) + return Collections.emptyList(); + + return new GridSerializableCollection<T>() { + @NotNull + @Override public Iterator<T> iterator() { + return flat((Iterable<? extends Iterable<T>>)c); } - assert c != null; + @Override public int size() { + return F.size(iterator()); + } - Collection<T> 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 <T> Type of the inner collections. + * @return Iterable over the elements of the inner collections. + */ + public static <T> GridIterator<T> flat(@Nullable final Iterable<? extends Iterable<T>> c) { + return isEmpty(c) ? GridFunc.<T>emptyIterator() : new GridIteratorAdapter<T>() { + /** */ + private Iterator<? extends Iterable<T>> a = c.iterator(); - return ret; - } - else { - if (isEmpty(c)) - return Collections.singletonList(t); + /** */ + private Iterator<T> b; - assert c != null; + /** */ + private boolean moved = true; - return new GridSerializableCollection<T>() { - @NotNull - @Override public Iterator<T> iterator() { - return new GridSerializableIterator<T>() { - private Iterator<T> 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 <T> Element type. - * @return Concatenated {@code non-null} collection. + * @param c Input iterable of iterators. + * @return Iterator over the elements of given iterators. */ - public static <T> Collection<T> concat(boolean cp, @Nullable final Collection<T> c1, - @Nullable final Collection<T> c2) { - if (cp) { - if (isEmpty(c1) && isEmpty(c2)) - return new ArrayList<>(0); + public static <T> Iterator<T> flatIterators(@Nullable final Iterable<Iterator<T>> c) { + return isEmpty(c) ? GridFunc.<T>emptyIterator() : new GridIteratorAdapter<T>() { + /** */ + private Iterator<? extends Iterator<T>> a = c.iterator(); - if (isEmpty(c1)) - return new ArrayList<>(c2); + /** */ + private Iterator<T> b; - if (isEmpty(c2)) - return new ArrayList<>(c1); + /** */ + private boolean moved = true; - assert c1 != null && c2 != null; + /** */ + private boolean more; - Collection<T> 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<T> 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<T>() { - @NotNull - @Override public Iterator<T> iterator() { - return new GridSerializableIterator<T>() { - private Iterator<T> it1 = c1.iterator(); - private Iterator<T> 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> 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 <T> 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 <T> Iterator<T> concat(Iterator<T> ... iters) { - if (iters.length == 1) - return iters[0]; - - return concat(asList(iters).iterator()); + public static <T> int size(@Nullable Collection<? extends T> c, @Nullable IgnitePredicate<? super T>... 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 <T> 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 <T> Iterator<T> concat(final Iterator<Iterator<T>> iters) { - if (!iters.hasNext()) - return Collections.<T>emptySet().iterator(); - - return new Iterator<T>() { - privat
<TRUNCATED>