// Path: core/src/main/java/com/bazaarvoice/ostrich/LoadBalanceAlgorithm.java
// public interface LoadBalanceAlgorithm {
//     /**
//      * Selects an end point to use based on a load balancing algorithm.  If no end point can be chosen, then
//      * <code>null</code> is returned.
//      *
//      * @param endPoints The end points to choose from.
//      * @param statistics Usage statistics about the end points in case the load balancing algorithm needs some
//      *                   knowledge of the service pool's state.
//      * @return Which end point to use or <code>null</code> if one couldn't be chosen.
//      */
//     ServiceEndPoint choose(Iterable<ServiceEndPoint> endPoints, ServicePoolStatistics statistics);
// }
// 
// Path: core/src/main/java/com/bazaarvoice/ostrich/loadbalance/RandomAlgorithm.java
// public class RandomAlgorithm implements LoadBalanceAlgorithm {
//     private final Random _rnd = new Random();
// 
//     @Override
//     public ServiceEndPoint choose(Iterable<ServiceEndPoint> endPoints, ServicePoolStatistics statistics) {
//         Preconditions.checkNotNull(endPoints);
// 
//         Iterator<ServiceEndPoint> iter = endPoints.iterator();
//         if (!iter.hasNext()) {
//             return null;
//         }
// 
//         List<ServiceEndPoint> list = Lists.newArrayList(iter);
//         if (list.size() == 1) {
//             return list.get(0);
//         }
//         return list.get(_rnd.nextInt(list.size()));
//     }
// }


import com.bazaarvoice.ostrich.HostDiscovery;
import com.bazaarvoice.ostrich.HostDiscoverySource;
import com.bazaarvoice.ostrich.LoadBalanceAlgorithm;
import com.bazaarvoice.ostrich.RetryPolicy;
import com.bazaarvoice.ostrich.ServiceFactory;
import com.bazaarvoice.ostrich.healthcheck.ExponentialBackoffHealthCheckRetryDelay;
import com.bazaarvoice.ostrich.healthcheck.HealthCheckRetryDelay;
import com.bazaarvoice.ostrich.loadbalance.RandomAlgorithm;
import com.bazaarvoice.ostrich.partition.IdentityPartitionFilter;
import com.bazaarvoice.ostrich.partition.PartitionFilter;
import com.bazaarvoice.ostrich.partition.PartitionKey;
import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.base.Ticker;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
package com.bazaarvoice.ostrich.pool;




public class ServicePoolBuilder<S> {
    private static final int DEFAULT_NUM_HEALTH_CHECK_THREADS = 1;
    private static final HealthCheckRetryDelay DEFAULT_HEALTH_CHECK_RETRY_POLICY = new ExponentialBackoffHealthCheckRetryDelay(100, 10_000, TimeUnit.MILLISECONDS);

    private final Class<S> _serviceType;
    private final List<HostDiscoverySource> _hostDiscoverySources = Lists.newArrayList();
    private boolean _closeHostDiscovery;
    private ServiceFactory<S> _serviceFactory;
    private String _serviceName;
    private ScheduledExecutorService _healthCheckExecutor;
    private ServiceCachingPolicy _cachingPolicy;
    private PartitionFilter _partitionFilter = new IdentityPartitionFilter();
    private PartitionContextSupplier _partitionContextSupplier = new EmptyPartitionContextSupplier();
// Path: core/src/main/java/com/bazaarvoice/ostrich/LoadBalanceAlgorithm.java
// public interface LoadBalanceAlgorithm {
//     /**
//      * Selects an end point to use based on a load balancing algorithm.  If no end point can be chosen, then
//      * <code>null</code> is returned.
//      *
//      * @param endPoints The end points to choose from.
//      * @param statistics Usage statistics about the end points in case the load balancing algorithm needs some
//      *                   knowledge of the service pool's state.
//      * @return Which end point to use or <code>null</code> if one couldn't be chosen.
//      */
//     ServiceEndPoint choose(Iterable<ServiceEndPoint> endPoints, ServicePoolStatistics statistics);
// }
// 
// Path: core/src/main/java/com/bazaarvoice/ostrich/loadbalance/RandomAlgorithm.java
// public class RandomAlgorithm implements LoadBalanceAlgorithm {
//     private final Random _rnd = new Random();
// 
//     @Override
//     public ServiceEndPoint choose(Iterable<ServiceEndPoint> endPoints, ServicePoolStatistics statistics) {
//         Preconditions.checkNotNull(endPoints);
// 
//         Iterator<ServiceEndPoint> iter = endPoints.iterator();
//         if (!iter.hasNext()) {
//             return null;
//         }
// 
//         List<ServiceEndPoint> list = Lists.newArrayList(iter);
//         if (list.size() == 1) {
//             return list.get(0);
//         }
//         return list.get(_rnd.nextInt(list.size()));
//     }
// }


// Path: core/src/main/java/com/bazaarvoice/ostrich/pool/ServicePoolBuilder.java
import com.bazaarvoice.ostrich.HostDiscovery;
import com.bazaarvoice.ostrich.HostDiscoverySource;
import com.bazaarvoice.ostrich.LoadBalanceAlgorithm;
import com.bazaarvoice.ostrich.RetryPolicy;
import com.bazaarvoice.ostrich.ServiceFactory;
import com.bazaarvoice.ostrich.healthcheck.ExponentialBackoffHealthCheckRetryDelay;
import com.bazaarvoice.ostrich.healthcheck.HealthCheckRetryDelay;
import com.bazaarvoice.ostrich.loadbalance.RandomAlgorithm;
import com.bazaarvoice.ostrich.partition.IdentityPartitionFilter;
import com.bazaarvoice.ostrich.partition.PartitionFilter;
import com.bazaarvoice.ostrich.partition.PartitionKey;
import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.base.Ticker;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;

package com.bazaarvoice.ostrich.pool;




public class ServicePoolBuilder<S> {
    private static final int DEFAULT_NUM_HEALTH_CHECK_THREADS = 1;
    private static final HealthCheckRetryDelay DEFAULT_HEALTH_CHECK_RETRY_POLICY = new ExponentialBackoffHealthCheckRetryDelay(100, 10_000, TimeUnit.MILLISECONDS);

    private final Class<S> _serviceType;
    private final List<HostDiscoverySource> _hostDiscoverySources = Lists.newArrayList();
    private boolean _closeHostDiscovery;
    private ServiceFactory<S> _serviceFactory;
    private String _serviceName;
    private ScheduledExecutorService _healthCheckExecutor;
    private ServiceCachingPolicy _cachingPolicy;
    private PartitionFilter _partitionFilter = new IdentityPartitionFilter();
    private PartitionContextSupplier _partitionContextSupplier = new EmptyPartitionContextSupplier();
    private LoadBalanceAlgorithm _loadBalanceAlgorithm = new RandomAlgorithm();