package org.radargun.config;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Definition of one cluster
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class Cluster implements Serializable, Comparable<Cluster> {
private static final AtomicInteger INDEX_GENERATOR = new AtomicInteger(0);
public static final String DEFAULT_GROUP = "default";
private List<Group> groups = new ArrayList<Group>();
private final int index;
public Cluster() {
index = INDEX_GENERATOR.getAndIncrement();
}
public void addGroup(String name, int size) {
if (!groups.isEmpty() && DEFAULT_GROUP.equals(groups.get(0).name)) {
throw new IllegalStateException("The cluster already contains default group (its size has been set).");
}
groups.add(new Group(name, size));
}
public void setSize(int size) {
if (groups.isEmpty()) {
groups.add(new Group(DEFAULT_GROUP, size));
} else {
Group group = groups.get(0);
if (DEFAULT_GROUP.equals(group.name)) {
throw new IllegalStateException("Size for default group already set to " + group.size);
} else {
throw new IllegalStateException("Cluster already contains some non-default groups: " + groups);
}
}
}
public int getSize() {
int totalSize = 0;
for (Group group : groups) {
totalSize += group.size;
}
return totalSize;
}
public Group getGroup(int slaveIndex) {
if (slaveIndex != -1) {
int index = slaveIndex;
for (Group g : groups) {
if (index < g.size) {
return g;
}
index -= g.size;
}
}
throw new IllegalStateException("Slave index is " + slaveIndex + ", cluster is " + toString());
}
public int getIndexInGroup(int slaveIndex) {
if (slaveIndex != -1) {
int index = slaveIndex;
for (Group g : groups) {
if (index < g.size) {
return index;
}
index -= g.size;
}
}
throw new IllegalStateException("Slave index is " + slaveIndex + ", cluster is " + toString());
}
public boolean groupExists(String groupName) {
boolean result = false;
for (Group group : groups) {
if (group.name.equals(groupName)) {
result = true;
break;
}
}
return result;
}
public int getClusterIndex() {
return index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Cluster[");
for (int i = 0; i < groups.size(); ++i) {
sb.append(groups.get(i).name).append('=').append(groups.get(i).size);
if (i != groups.size() - 1) {
sb.append(", ");
}
}
return sb.append("]").toString();
}
public List<Group> getGroups() {
return Collections.unmodifiableList(groups);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Cluster cluster = (Cluster) o;
if (!groups.equals(cluster.groups)) return false;
return true;
}
@Override
public int hashCode() {
return groups.hashCode();
}
@Override
public int compareTo(Cluster c) {
int compare = Integer.compare(getSize(), c.getSize());
if (compare != 0) return compare;
compare = Integer.compare(groups.size(), c.groups.size());
if (compare != 0) return compare;
for (int i = 0; i < groups.size(); ++i) {
compare = Integer.compare(groups.get(i).size, c.groups.get(i).size);
if (compare != 0) return compare;
}
return 0;
}
public Set<Integer> getSlaves(String group) {
int index = 0;
for (Group g : groups) {
if (g.name.equals(group)) {
Set<Integer> slaves = new HashSet<>(g.size);
for (int i = 0; i < g.size; ++i) {
slaves.add(index + i);
}
return slaves;
}
index += g.size;
}
return Collections.EMPTY_SET;
}
public class Group implements Serializable {
public final String name;
public final int size;
public Group(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Group group = (Group) o;
if (size != group.size) return false;
if (!name.equals(group.name)) return false;
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + size;
return result;
}
}
}