/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ignite.internal.util.lang; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.UUID; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.tostring.GridToStringInclude; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgnitePredicate; import org.jetbrains.annotations.Nullable; /** * Convenient node predicate as a separate class. It allows to avoid "dragging" enclosing * class's state when predicates are created as anonymous classes in stateful enclosing context. * This class is also optimized for evaluation of large number of nodes. */ public class GridNodePredicate implements IgnitePredicate<ClusterNode>, Iterable<UUID> { /** */ private static final long serialVersionUID = 0L; /** */ @GridToStringInclude private final Set<UUID> ids; /** */ @GridToStringExclude private int hash = Integer.MIN_VALUE; /** * Creates node predicate that evaluates to {@code true} for all * provided node IDs. Implementation will not make a defensive copy. * * @param ids Optional node IDs. If none provided - predicate will always return {@code false}. */ public GridNodePredicate(Set<UUID> ids) { assert ids != null; this.ids = ids; } /** * Creates node predicate that evaluates to {@code true} for all * provided node IDs. Implementation will make a defensive copy. * * @param ids Optional node IDs. If none provided - predicate will always return {@code false}. */ public GridNodePredicate(@Nullable Collection<UUID> ids) { this.ids = F.isEmpty(ids) ? Collections.<UUID>emptySet() : ids.size() == 1 ? Collections.singleton(F.first(ids)) : new HashSet<>(ids); } /** * Creates node predicate that evaluates to {@code true} for all * provided node IDs. Implementation will make a defensive copy. * * @param ids Optional node IDs. If none provided - predicate will always return {@code false}. */ public GridNodePredicate(@Nullable UUID... ids) { if (F.isEmpty(ids)) this.ids = Collections.emptySet(); else if (ids.length == 1) this.ids = Collections.singleton(ids[0]); else { this.ids = U.newHashSet(ids.length); Collections.addAll(this.ids, ids); } } /** * Creates node predicate that evaluates to {@code true} for all * provided nodes. Implementation will make a defensive copy. * * @param nodes Optional grid nodes. If none provided - predicate * will always return {@code false}. */ public GridNodePredicate(@Nullable ClusterNode... nodes) { if (F.isEmpty(nodes)) ids = Collections.emptySet(); else if (nodes.length == 1) { ClusterNode node = nodes[0]; ids = node != null ? Collections.singleton(node.id()) : Collections.<UUID>emptySet(); } else { ids = U.newHashSet(nodes.length); for (ClusterNode n : nodes) { if (n != null) ids.add(n.id()); } } } /** * Gets set of node IDs this predicate is based on. Note that for performance * reasons this methods return the internal set that <b>should not</b> be * modified by the caller. * * @return Set of node IDs this predicate is based on. */ public Set<UUID> nodeIds(){ return ids; } /** {@inheritDoc} */ @Override public Iterator<UUID> iterator() { return ids.iterator(); } /** {@inheritDoc} */ @Override public boolean apply(ClusterNode n) { assert n != null; return ids.contains(n.id()); } /** {@inheritDoc} */ @Override public int hashCode() { // Allow for multiple hash calculations to avoid // synchronization cost. Note that array of IDs don't change. if (hash == Integer.MIN_VALUE) hash = ids.hashCode(); return hash; } /** {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof GridNodePredicate)) return false; GridNodePredicate it = (GridNodePredicate)o; return ids.equals(it.ids); } /** {@inheritDoc} */ @Override public String toString() { return S.toString(GridNodePredicate.class, this); } }