package cassandra.routing; import cassandra.cql.AbstractStatement; import java.net.InetAddress; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList; public class RoundRobinPolicy implements RoutingPolicy { private final List<InetAddress> activeEndpoints; private volatile int counter; public RoundRobinPolicy() { this(new CopyOnWriteArrayList<InetAddress>()); } public RoundRobinPolicy(List<InetAddress> activeEndpoints) { if (activeEndpoints == null) { throw new NullPointerException("activeEndpoints"); } this.activeEndpoints = activeEndpoints; counter = new Random().nextInt(997); } @Override public boolean isLocal(InetAddress endpoint) { return true; } @Override public Iterator<InetAddress> activeEndpoints(AbstractStatement<?> statement) { return new Iterator<InetAddress>() { private int start = counter++; private int remaining = activeEndpoints.size(); @Override public boolean hasNext() { return remaining > 0; } @Override public InetAddress next() { if (!hasNext()) { return null; } remaining--; int index = start++ % activeEndpoints.size(); if (index < 0) { index += activeEndpoints.size(); } return activeEndpoints.get(index); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public void addEndpoint(InetAddress endpoint) { if (!activeEndpoints.contains(endpoint)) { activeEndpoints.add(endpoint); } } @Override public void removeEndpoint(InetAddress endpoint) { activeEndpoints.remove(endpoint); } }