public Map < String , Collection < String > > getServerClusterMap ( Collection < String > iClusterNames , final String iLocalNode , final boolean optimizeForLocalOnly ) { if ( iClusterNames == null || iClusterNames . isEmpty ( ) ) iClusterNames = DEFAULT_CLUSTER_NAME ; final Map < String , Collection < String > > servers = new HashMap < String , Collection < String > > ( iClusterNames . size ( ) ) ; // TRY TO SEE IF IT CAN BE EXECUTED ON LOCAL NODE ONLY boolean canUseLocalNode = true ; for ( String p : iClusterNames ) { final List < String > serverList = getClusterConfiguration ( p ) . field ( SERVERS ) ; if ( serverList != null && ! serverList . contains ( iLocalNode ) ) { canUseLocalNode = false ; break ; } } if ( optimizeForLocalOnly && canUseLocalNode ) { // USE LOCAL NODE ONLY (MUCH FASTER) servers . put ( iLocalNode , iClusterNames ) ; return servers ; } // GROUP BY SERVER WITH THE NUMBER OF CLUSTERS final Map < String , Collection < String > > serverMap = new HashMap < String , Collection < String > > ( ) ; for ( String p : iClusterNames ) { final List < String > serverList = getClusterConfiguration ( p ) . field ( SERVERS ) ; for ( String s : serverList ) { if ( NEW_NODE_TAG . equalsIgnoreCase ( s ) ) continue ; Collection < String > clustersInServer = serverMap . get ( s ) ; if ( clustersInServer == null ) { clustersInServer = new HashSet < String > ( ) ; serverMap . put ( s , clustersInServer ) ; } clustersInServer . add ( p ) ; } } if ( serverMap . size ( ) == 1 ) // RETURN THE ONLY SERVER INVOLVED return serverMap ; if ( ! optimizeForLocalOnly ) return serverMap ; // ORDER BY NUMBER OF CLUSTERS final List < String > orderedServers = new ArrayList < String > ( serverMap . keySet ( ) ) ; Collections . sort ( orderedServers , new Comparator < String > ( ) { @ Override public int compare ( final String o1 , final String o2 ) { return ( ( Integer ) serverMap . get ( o2 ) . size ( ) ) . compareTo ( ( Integer ) serverMap . get ( o1 ) . size ( ) ) ; } } ) ; // BROWSER ORDERED SERVER MAP PUTTING THE MINIMUM SERVER TO COVER ALL THE CLUSTERS final Set < String > remainingClusters = new HashSet < String > ( iClusterNames ) ; // KEEPS THE REMAINING CLUSTER TO ADD IN FINAL // RESULT final Set < String > includedClusters = new HashSet < String > ( iClusterNames . size ( ) ) ; // KEEPS THE COLLECTION OF ALREADY INCLUDED // CLUSTERS for ( String s : orderedServers ) { final Collection < String > clusters = serverMap . get ( s ) ; if ( ! servers . isEmpty ( ) ) { // FILTER CLUSTER LIST AVOIDING TO REPEAT CLUSTERS ALREADY INCLUDED ON PREVIOUS NODES clusters . removeAll ( includedClusters ) ; } servers . put ( s , clusters ) ; remainingClusters . removeAll ( clusters ) ; includedClusters . addAll ( clusters ) ; if ( remainingClusters . isEmpty ( ) ) // FOUND ALL CLUSTERS break ; } return servers ; }
Returns the list of servers that can manage a list of clusters . The algorithm makes its best to involve the less servers as it can .