示例#1
0
文件: network.go 项目: BobbWu/degdb
// MinimumCoveringPeers returns a set of peers that minimizes overlap. This is similar to the Set Covering Problem and is NP-hard.
// This is a greedy algorithm. While the keyspace is not entirely covered, scan through all peers and pick the peer that will add the most to the set while still having the start in the selected set.
// TODO(wiz): Make this more optimal.
// TODO(wiz): achieve n-redundancy
func (s *Server) MinimumCoveringPeers() []*Conn {
	usedPeers := make(map[string]bool)
	var peers []*Conn
	var keyspace *protocol.Keyspace
	for i := 0; i < len(s.Peers) && !keyspace.Maxed(); i++ {
		var bestPeer *Conn
		var increase uint64
		// By definition, ranging through peer map will go in random order.
	Peers:
		for id, conn := range s.Peers {
			if conn == nil || conn.Peer == nil || usedPeers[id] {
				continue
			}
			peer := conn.Peer
			if keyspace == nil {
				peers = append(peers, conn)
				keyspace = peer.Keyspace
				break Peers
			}
			incr := keySpaceIncrease(keyspace, peer.Keyspace)
			if incr > increase {
				increase = incr
				bestPeer = conn
			}
		}
		if bestPeer != nil {
			peers = append(peers, bestPeer)
			keyspace = keyspace.Union(bestPeer.Peer.Keyspace)
			usedPeers[bestPeer.Peer.Id] = true
			// break?
		}
	}
	return peers
}
示例#2
0
文件: network.go 项目: BobbWu/degdb
// keySpaceIncrease calculates the increase in keyspace if b was to be unioned.
func keySpaceIncrease(a, b *protocol.Keyspace) uint64 {
	unionMag := a.Union(b).Mag()
	aMag := a.Mag()
	if unionMag > aMag {
		return unionMag - aMag
	}
	return 0
}