package me.prettyprint.cassandra.connection;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.google.common.collect.Iterables;

import me.prettyprint.cassandra.service.CassandraHost;

/**
 * Implements a RoundRobin balancing policy based off the contents
 * of the active {@link HClientPool}. If a pool is shutdown by another 
 * thread in the midst of the selection process, we return the pool
 * at position 0
 *
 * @author zznate
 */
public class RoundRobinBalancingPolicy implements LoadBalancingPolicy {

  private static final long serialVersionUID = 1107204068032227079L;
  private AtomicInteger counter;
  
  public RoundRobinBalancingPolicy() {
    counter = new AtomicInteger();
  }
  
  @Override
  public HClientPool getPool(Collection<HClientPool> pools,
      Set<CassandraHost> excludeHosts) {
    HClientPool pool = getPoolSafely(pools);    
    if ( excludeHosts != null && excludeHosts.size() > 0 ) {
      while ( excludeHosts.contains(pool.getCassandraHost()) ) {
        pool = getPoolSafely(pools);
        if ( excludeHosts.size() >= pools.size() )
          break;
      }
    }    
    return pool;
  }
  
  private HClientPool getPoolSafely(Collection<HClientPool> pools) {
    try {
      return Iterables.get(pools, getAndIncrement(pools.size()));
    } catch (IndexOutOfBoundsException e) {
      return pools.iterator().next();
    }       
  }
    
  private int getAndIncrement(int size) {
    counter.compareAndSet(16384, 0);
    return counter.getAndIncrement() % size;    
  }

  @Override
  public HClientPool createConnection(CassandraHost host) {
  	return new ConcurrentHClientPool(host);
  }
}

@@ -670,29 +670,19 @@
 private 
-AtomicInteger
+int
  counter
@@ -743,27 +743,9 @@
 r = 
-new AtomicInteger()
+0
 ;%0A  
@@ -1483,59 +1483,277 @@
     
+int 
 counter
-.compareAndSet(16384,
+ToReturn;%0A    %0A    // There should not be that much of contention here as%0A    // the %22if%22 statement plus the increment is executed real fast.%0A    synchronized (this) %7B%0A      if (counter %3E= 16384) %7B%0A        counter =
  0
-)
 ;%0A    
-r
+  %7D%0A      counterToR
 eturn
+ =
  counter
 .get
@@ -1752,34 +1752,53 @@
 nter
-.getAndIncrement()
+++;%0A    %7D%0A%0A    return counterToReturn
  %25 size;
     
@@ -1793,20 +1793,16 @@
  %25 size;
-    
 %0A  %7D%0A%0A  

Fix issue #224