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