Merge branch 'master' into 5349-timestamp-error-for-running-pipeline
[arvados.git] / sdk / go / keepclient / root_sorter.go
1 package keepclient
2
3 import (
4         "sort"
5 )
6
7 type RootSorter struct {
8         root         []string
9         weight       []string
10         order        []int
11 }
12
13 func NewRootSorter(serviceRoots map[string]string, hash string) (*RootSorter) {
14         rs := new(RootSorter)
15         rs.root = make([]string, len(serviceRoots))
16         rs.weight = make([]string, len(serviceRoots))
17         rs.order = make([]int, len(serviceRoots))
18         i := 0
19         for uuid, root := range serviceRoots {
20                 rs.root[i] = root
21                 rs.weight[i] = rs.getWeight(hash, uuid)
22                 rs.order[i] = i
23                 i++
24         }
25         sort.Sort(rs)
26         return rs
27 }
28
29 func (rs RootSorter) getWeight(hash string, uuid string) (string) {
30         if len(uuid) == 27 {
31                 return Md5String(hash + uuid[12:])
32         } else {
33                 // Only useful for testing, a set of one service root, etc.
34                 return Md5String(hash + uuid)
35         }
36 }
37
38 func (rs RootSorter) GetSortedRoots() ([]string) {
39         sorted := make([]string, len(rs.order))
40         for i := range rs.order {
41                 sorted[i] = rs.root[rs.order[i]]
42         }
43         return sorted
44 }
45
46 // Less is really More here: the heaviest root will be at the front of the list.
47 func (rs RootSorter) Less(i, j int) bool {
48         return rs.weight[rs.order[j]] < rs.weight[rs.order[i]]
49 }
50
51 func (rs RootSorter) Len() int {
52         return len(rs.order)
53 }
54
55 func (rs RootSorter) Swap(i, j int) {
56         sort.IntSlice(rs.order).Swap(i, j)
57 }