package uk.ac.rhul.cs.cl1.growth; import java.util.Arrays; import uk.ac.rhul.cs.cl1.MutableNodeSet; import uk.ac.rhul.cs.utils.StringUtils; /** * An action that can be taken while growing a cluster according to some rules. * * The possible actions are: * * - add some new nodes to the cluster * - remove some nodes from the cluster * - declare the cluster as the final solution * * @author ntamas * */ public class ClusterGrowthAction { public enum Type { ADD, REMOVE, TERMINATE; } /** * The type of the action to be taken */ protected Type type = null; /** * Optional set of nodes associated with the action */ protected int[] nodes = null; /** * Locally cached instance of a ClusterGrowthAction storing Type.TERMINATE */ private static ClusterGrowthAction cachedTerminateAction = new ClusterGrowthAction(Type.TERMINATE); /** * Creates an instance corresponding to the given action type */ protected ClusterGrowthAction(Type type) { this.type = type; } /** * Creates an instance representing the addition of a single node * @param index the node to be added */ public static ClusterGrowthAction addition(int index) { ClusterGrowthAction result = new ClusterGrowthAction(Type.ADD); result.nodes = new int[1]; result.nodes[0] = index; return result; } /** * Creates an instance representing the addition of several nodes * @param array indices of the nodes to be added */ public static ClusterGrowthAction addition(int[] array) { ClusterGrowthAction result = new ClusterGrowthAction(Type.ADD); result.nodes = Arrays.copyOf(array, array.length); return result; } /** * Creates an instance representing the removal of a single node * @param index the node to be added */ public static ClusterGrowthAction removal(int index) { ClusterGrowthAction result = new ClusterGrowthAction(Type.REMOVE); result.nodes = new int[1]; result.nodes[0] = index; return result; } /** * Creates an instance representing the removal of several nodes * @param array indices of the nodes to be removed */ public static ClusterGrowthAction removal(int[] array) { ClusterGrowthAction result = new ClusterGrowthAction(Type.REMOVE); result.nodes = Arrays.copyOf(array, array.length); return result; } /** * Creates an instance representing the termination of the growth process */ public static ClusterGrowthAction terminate() { return cachedTerminateAction; } /** * Returns the type of this action */ public Type getType() { return this.type; } /** * Executes the action on the given mutable node set * @param nodeSet the nodeset to modify */ public void executeOn(MutableNodeSet nodeSet) { if (this.type == Type.ADD) { for (int node: this.nodes) nodeSet.add(node); return; } if (this.type == Type.REMOVE) { for (int node: this.nodes) nodeSet.remove(node); return; } } /** * Creates a simple human-readable string representation of this action */ public String toString() { StringBuilder sb = new StringBuilder(); Integer[] nodes; if (this.nodes == null) { nodes = new Integer[0]; } else { nodes = new Integer[this.nodes.length]; for (int i = 0; i < this.nodes.length; i++) nodes[i] = this.nodes[i]; } sb.append(this.getType().toString()); sb.append(" {"); sb.append(StringUtils.join(Arrays.asList(nodes).iterator(), ", ")); sb.append("}"); return sb.toString(); } }