BalancingNodePlacementStrategy implements NodePlacementStrategy { @Override public List<Location> locationsForAdditions(Multimap<Location, Entity> currentMembers, Collection<? extends Location> locs, int numToAdd) { if (locs.isEmpty() && numToAdd > 0) { throw new IllegalArgumentException("No locations supplied, when requesting locations for "+numToAdd+" nodes"); } List<Location> result = Lists.newArrayList(); Map<Location, Integer> locSizes = toMutableLocationSizes(currentMembers, locs); for (int i = 0; i < numToAdd; i++) { Location leastPopulatedLoc = null; int leastPopulatedLocSize = 0; for (Location loc : locs) { int locSize = locSizes.get(loc); if (leastPopulatedLoc == null || locSize < leastPopulatedLocSize) { leastPopulatedLoc = loc; leastPopulatedLocSize = locSize; } } assert leastPopulatedLoc != null : "leastPopulatedLoc=null; locs="+locs+"; currentMembers="+currentMembers; result.add(leastPopulatedLoc); locSizes.put(leastPopulatedLoc, locSizes.get(leastPopulatedLoc)+1); } return result; }  @Override List<Location> locationsForAdditions(Multimap<Location, Entity> currentMembers, Collection<? extends Location> locs, int numToAdd); @Override List<Entity> entitiesToRemove(Multimap<Location, Entity> currentMembers, int numToRemove); @Override String toString();  }
@Test public void testAddsBalancedWhenEmpty() throws Exception { LinkedHashMultimap<Location, Entity> currentMembers = LinkedHashMultimap.<Location,Entity>create(); List<Location> result = placementStrategy.locationsForAdditions(currentMembers, ImmutableList.of(loc1, loc2), 4); Asserts.assertEqualsIgnoringOrder(result, ImmutableList.of(loc1, loc1, loc2, loc2)); }
@Test public void testAddsToBalanceWhenPopulated() throws Exception { LinkedHashMultimap<Location, Entity> currentMembers = LinkedHashMultimap.<Location,Entity>create(); currentMembers.put(loc1, entity1); currentMembers.put(loc1, entity2); List<Location> result = placementStrategy.locationsForAdditions(currentMembers, ImmutableList.of(loc1, loc2), 4); Asserts.assertEqualsIgnoringOrder(result, ImmutableList.of(loc1, loc2, loc2, loc2)); }
@Test public void testAddWillIgnoredDisallowedLocation() throws Exception { LinkedHashMultimap<Location, Entity> currentMembers = LinkedHashMultimap.<Location,Entity>create(); currentMembers.put(loc1, entity1); currentMembers.put(loc2, entity2); List<Location> result = placementStrategy.locationsForAdditions(currentMembers, ImmutableList.of(loc1), 2); Asserts.assertEqualsIgnoringOrder(result, ImmutableList.of(loc1, loc1)); }