Merge branch '2960-keepstore-streaming'
[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         }
37         // Only useful for testing, a set of one service root, etc.
38         return Md5String(hash + uuid)
39 }
40
41 func (rs RootSorter) GetSortedRoots() []string {
42         sorted := make([]string, len(rs.order))
43         for i := range rs.order {
44                 sorted[i] = rs.root[rs.order[i]]
45         }
46         return sorted
47 }
48
49 // Less is really More here: the heaviest root will be at the front of the list.
50 func (rs RootSorter) Less(i, j int) bool {
51         return rs.weight[rs.order[j]] < rs.weight[rs.order[i]]
52 }
53
54 func (rs RootSorter) Len() int {
55         return len(rs.order)
56 }
57
58 func (rs RootSorter) Swap(i, j int) {
59         sort.IntSlice(rs.order).Swap(i, j)
60 }