provision/docker/scheduler.go
func (s *segregatedScheduler) minMaxNodes(nodes []cluster.Node, appName, process string) (string, string, error) {
	nodesList := make(node.NodeList, len(nodes))
	for i := range nodes {
		nodesList[i] = &clusterNodeWrapper{Node: &nodes[i], prov: s.provisioner}
	}
	metaFreqList, _, err := nodesList.SplitMetadata()
	if err != nil {
		log.Debugf("[scheduler] ignoring metadata diff when selecting node: %s", err)
	}
	hostGroupMap := map[string]int{}
	for i, m := range metaFreqList {
		for _, n := range m.Nodes {
			hostGroupMap[net.URLToHost(n.Address())] = i
		}
	}
	hosts, hostsMap := s.nodesToHosts(nodes)
	hostCountMap, err := s.aggregateContainersByHost(hosts)
	if err != nil {
		return "", "", err
	}
	appCountMap, err := s.aggregateContainersByHostAppProcess(hosts, appName, process)
	if err != nil {
		return "", "", err
	}
	priorityEntries := []map[string]int{appGroupCount(hostGroupMap, appCountMap), appCountMap, hostCountMap}
	var minHost, maxHost string
	var minScore uint64 = math.MaxUint64
	var maxScore uint64 = 0
	for _, host := range hosts {
		var score uint64
		for i, e := range priorityEntries {
			score += uint64(e[host]) << uint((len(priorityEntries)-i-1)*(64/len(priorityEntries)))
		}
		if score < minScore {
			minScore = score
			minHost = host
		}
		if score >= maxScore {
			maxScore = score
			maxHost = host
		}
	}
	return hostsMap[minHost], hostsMap[maxHost], nil
}
func (s *segregatedScheduler) minMaxNodes(nodes []cluster.Node, appName, process string) (string, string, error) {
	nodesList := make(node.NodeList, len(nodes))
	for i := range nodes {
		nodesList[i] = &clusterNodeWrapper{Node: &nodes[i], prov: s.provisioner}
	}
	metaFreqList, _, err := nodesList.SplitMetadata()
	if err != nil {
		log.Debugf("[scheduler] ignoring metadata diff when selecting node: %s", err)
	}
	hostGroupMap := map[string]int{}
	for i, m := range metaFreqList {
		for _, n := range m.Nodes {
			hostGroupMap[net.URLToHost(n.Address())] = i
		}
	}
	hosts, hostsMap := s.nodesToHosts(nodes)
	hostCountMap, err := s.aggregateContainersByHost(hosts)
	if err != nil {
		return "", "", err
	}
	appCountMap, err := s.aggregateContainersByHostAppProcess(hosts, appName, process)
	if err != nil {
		return "", "", err
	}
	priorityEntries := []map[string]int{appGroupCount(hostGroupMap, appCountMap), appCountMap, hostCountMap}
	var minHost, maxHost string
	var minScore uint64 = math.MaxUint64
	var maxScore uint64 = 0
	for _, host := range hosts {
		var score uint64
		for i, e := range priorityEntries {
			score += uint64(e[host]) << uint((len(priorityEntries)-i-1)*(64/len(priorityEntries)))
		}
		if score < minScore {
			minScore = score
			minHost = host
		}
		if score >= maxScore {
			maxScore = score
			maxHost = host
		}
	}
	return hostsMap[minHost], hostsMap[maxHost], nil
}
// Find the host with the minimum (good to add a new container) and maximum
// (good to remove a container) value for the pair [(number of containers for
// app-process), (number of containers in host)]