String serviceName = service.getServiceName();
String clusterName = service.getClusterName();
ClusterProperties cluster = getClusterProperties(serviceName, clusterName);
LoadBalancerStateItem<UriProperties> uriItem = getUriItem(serviceName, clusterName, cluster);
UriProperties uris = uriItem.getProperty();
List<LoadBalancerState.SchemeStrategyPair> orderedStrategies =
_state.getStrategiesForService(serviceName, service.getPrioritizedSchemes());
List<K> unmappedKeys = new ArrayList<K>();
if (! orderedStrategies.isEmpty())
{
//DANGER we assume that the first strategy in the list has to support partitioning. If not then,
//this function may fail. The reason why we don't check whether the strategy support partitioning
//is because the downstream code will check it for us and the user will be notified about
//this problem. Plus it doesn't make sense for a user to have partitioning but didn't specify a
//strategy that supports partitioning
final LoadBalancerState.SchemeStrategyPair pair = orderedStrategies.get(0);
final PartitionAccessor accessor = getPartitionAccessor(serviceName, clusterName);
//get the partitionId -> keys mapping
Map<Integer, Set<K>> partitionSet = new TreeMap<Integer, Set<K>>();
for (final K key : keys)
{
int partitionId;
try
{
partitionId = accessor.getPartitionId(key.toString());
}
catch (PartitionAccessException e)
{
unmappedKeys.add(key);
continue;
}
Set<K> set = partitionSet.get(partitionId);
if (set == null)
{
set = new HashSet<K>();
partitionSet.put(partitionId, set);
}
set.add(key);
}
Collection<Integer> partitionWithoutEnoughHost = new HashSet<Integer>();
int hash = hashProvider.nextHash();
//get the partitionId -> host URIs list
Map<Integer, List<URI>> hostList = new HashMap<Integer, List<URI>>();
for (Integer partitionId : partitionSet.keySet())
{
Set<URI> possibleUris = uris.getUriBySchemeAndPartition(pair.getScheme(), partitionId);
List<TrackerClient> trackerClients = getPotentialClients(serviceName, service, possibleUris);
int size = trackerClients.size() <= limitHostPerPartition ? trackerClients.size() : limitHostPerPartition;
List<URI> rankedUri = new ArrayList<URI>(size);
Ring<URI> ring = pair.getStrategy().getRing(uriItem.getVersion(), partitionId, trackerClients);