6447ea51d2
This takes advantange of the latest features in go-cid, peer.ID and go-multiaddr and makes the Go types serializable by default. This means we no longer need to copy between Pin <-> PinSerial, or ID <-> IDSerial etc. We can now efficiently binary-encode these types using short field keys and without parsing/stringifying (in many cases it just a cast). We still get the same json output as before (with minor modifications for Cids). This should greatly improve Cluster performance and memory usage when dealing with large collections of items. License: MIT Signed-off-by: Hector Sanjuan <hector@protocol.ai>
76 lines
1.6 KiB
Go
76 lines
1.6 KiB
Go
// Package util is a utility package used by the allocator
|
|
// implementations. This package provides the SortNumeric function, which may be
|
|
// used by an allocator to sort peers by their metric values (ascending or
|
|
// descending).
|
|
package util
|
|
|
|
import (
|
|
"sort"
|
|
"strconv"
|
|
|
|
"github.com/ipfs/ipfs-cluster/api"
|
|
|
|
peer "github.com/libp2p/go-libp2p-peer"
|
|
)
|
|
|
|
// SortNumeric returns a list of peers sorted by their metric values. If reverse
|
|
// is false (true), peers will be sorted from smallest to largest (largest to
|
|
// smallest) metric
|
|
func SortNumeric(candidates map[peer.ID]*api.Metric, reverse bool) []peer.ID {
|
|
vMap := make(map[peer.ID]uint64)
|
|
peers := make([]peer.ID, 0, len(candidates))
|
|
for k, v := range candidates {
|
|
if v.Discard() {
|
|
continue
|
|
}
|
|
val, err := strconv.ParseUint(v.Value, 10, 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
peers = append(peers, k)
|
|
vMap[k] = val
|
|
}
|
|
|
|
sorter := &metricSorter{
|
|
m: vMap,
|
|
peers: peers,
|
|
reverse: reverse,
|
|
}
|
|
sort.Sort(sorter)
|
|
return sorter.peers
|
|
}
|
|
|
|
// metricSorter implements the sort.Sort interface
|
|
type metricSorter struct {
|
|
peers []peer.ID
|
|
m map[peer.ID]uint64
|
|
reverse bool
|
|
}
|
|
|
|
// Len returns the number of metrics
|
|
func (s metricSorter) Len() int {
|
|
return len(s.peers)
|
|
}
|
|
|
|
// Swap Swaps the elements in positions i and j
|
|
func (s metricSorter) Swap(i, j int) {
|
|
temp := s.peers[i]
|
|
s.peers[i] = s.peers[j]
|
|
s.peers[j] = temp
|
|
}
|
|
|
|
// Less reports if the element in position i is Less than the element in j
|
|
// (important to override this)
|
|
func (s metricSorter) Less(i, j int) bool {
|
|
peeri := s.peers[i]
|
|
peerj := s.peers[j]
|
|
|
|
x := s.m[peeri]
|
|
y := s.m[peerj]
|
|
|
|
if s.reverse {
|
|
return x > y
|
|
}
|
|
return x < y
|
|
}
|