public static Cluster swapGreedyRandomPartitions ( final Cluster nextCandidateCluster , final List < Integer > nodeIds , final int greedySwapMaxPartitionsPerNode , final int greedySwapMaxPartitionsPerZone , List < StoreDefinition > storeDefs ) { System . out . println ( "GreedyRandom : nodeIds:" + nodeIds ) ; Cluster returnCluster = Cluster . cloneCluster ( nextCandidateCluster ) ; double currentUtility = new PartitionBalance ( returnCluster , storeDefs ) . getUtility ( ) ; int nodeIdA = - 1 ; int nodeIdB = - 1 ; int partitionIdA = - 1 ; int partitionIdB = - 1 ; for ( int nodeIdAPrime : nodeIds ) { System . out . println ( "GreedyRandom : processing nodeId:" + nodeIdAPrime ) ; List < Integer > partitionIdsAPrime = new ArrayList < Integer > ( ) ; partitionIdsAPrime . addAll ( returnCluster . getNodeById ( nodeIdAPrime ) . getPartitionIds ( ) ) ; Collections . shuffle ( partitionIdsAPrime ) ; int maxPartitionsInAPrime = Math . min ( greedySwapMaxPartitionsPerNode , partitionIdsAPrime . size ( ) ) ; for ( int offsetAPrime = 0 ; offsetAPrime < maxPartitionsInAPrime ; offsetAPrime ++ ) { Integer partitionIdAPrime = partitionIdsAPrime . get ( offsetAPrime ) ; List < Pair < Integer , Integer > > partitionIdsZone = new ArrayList < Pair < Integer , Integer > > ( ) ; for ( int nodeIdBPrime : nodeIds ) { if ( nodeIdBPrime == nodeIdAPrime ) continue ; for ( Integer partitionIdBPrime : returnCluster . getNodeById ( nodeIdBPrime ) . getPartitionIds ( ) ) { partitionIdsZone . add ( new Pair < Integer , Integer > ( nodeIdBPrime , partitionIdBPrime ) ) ; } } Collections . shuffle ( partitionIdsZone ) ; int maxPartitionsInZone = Math . min ( greedySwapMaxPartitionsPerZone , partitionIdsZone . size ( ) ) ; for ( int offsetZone = 0 ; offsetZone < maxPartitionsInZone ; offsetZone ++ ) { Integer nodeIdBPrime = partitionIdsZone . get ( offsetZone ) . getFirst ( ) ; Integer partitionIdBPrime = partitionIdsZone . get ( offsetZone ) . getSecond ( ) ; Cluster swapResult = swapPartitions ( returnCluster , nodeIdAPrime , partitionIdAPrime , nodeIdBPrime , partitionIdBPrime ) ; double swapUtility = new PartitionBalance ( swapResult , storeDefs ) . getUtility ( ) ; if ( swapUtility < currentUtility ) { currentUtility = swapUtility ; System . out . println ( " -> " + currentUtility ) ; nodeIdA = nodeIdAPrime ; partitionIdA = partitionIdAPrime ; nodeIdB = nodeIdBPrime ; partitionIdB = partitionIdBPrime ; } } } } if ( nodeIdA == - 1 ) { return returnCluster ; } return swapPartitions ( returnCluster , nodeIdA , partitionIdA , nodeIdB , partitionIdB ) ; }
For each node in specified zones tries swapping some minimum number of random partitions per node with some minimum number of random partitions from other specified nodes . Chooses the best swap in each iteration . Large values of the greedSwapMaxPartitions ... arguments make this method equivalent to comparing every possible swap . This may get very expensive .