89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package app
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
func reconcileTransportAllocations(items []TransportClient, forceRebalance bool) ([]TransportClient, bool) {
|
|
if len(items) == 0 {
|
|
return items, false
|
|
}
|
|
changed := false
|
|
|
|
sort.Slice(items, func(i, j int) bool { return items[i].ID < items[j].ID })
|
|
|
|
usedMarks := map[uint64]struct{}{}
|
|
usedPrefs := map[int]struct{}{}
|
|
missingMark := make([]int, 0)
|
|
missingPref := make([]int, 0)
|
|
needRebalance := forceRebalance
|
|
|
|
for i := range items {
|
|
if m, ok := parseTransportMarkHex(items[i].MarkHex); ok {
|
|
if _, exists := usedMarks[m]; exists {
|
|
needRebalance = true
|
|
} else {
|
|
usedMarks[m] = struct{}{}
|
|
}
|
|
} else if strings.TrimSpace(items[i].MarkHex) == "" {
|
|
missingMark = append(missingMark, i)
|
|
} else {
|
|
needRebalance = true
|
|
}
|
|
|
|
if p, ok := parseTransportPref(items[i].PriorityBase); ok {
|
|
if _, exists := usedPrefs[p]; exists {
|
|
needRebalance = true
|
|
} else {
|
|
usedPrefs[p] = struct{}{}
|
|
}
|
|
} else if items[i].PriorityBase == 0 {
|
|
missingPref = append(missingPref, i)
|
|
} else {
|
|
needRebalance = true
|
|
}
|
|
}
|
|
|
|
if needRebalance {
|
|
usedMarks = map[uint64]struct{}{}
|
|
usedPrefs = map[int]struct{}{}
|
|
for i := range items {
|
|
m := nextTransportMark(usedMarks)
|
|
p := nextTransportPref(usedPrefs)
|
|
usedMarks[m] = struct{}{}
|
|
usedPrefs[p] = struct{}{}
|
|
|
|
markHex := formatTransportMarkHex(m)
|
|
if items[i].MarkHex != markHex {
|
|
items[i].MarkHex = markHex
|
|
changed = true
|
|
}
|
|
if items[i].PriorityBase != p {
|
|
items[i].PriorityBase = p
|
|
changed = true
|
|
}
|
|
}
|
|
return items, changed
|
|
}
|
|
|
|
for _, idx := range missingMark {
|
|
m := nextTransportMark(usedMarks)
|
|
usedMarks[m] = struct{}{}
|
|
markHex := formatTransportMarkHex(m)
|
|
if items[idx].MarkHex != markHex {
|
|
items[idx].MarkHex = markHex
|
|
changed = true
|
|
}
|
|
}
|
|
for _, idx := range missingPref {
|
|
p := nextTransportPref(usedPrefs)
|
|
usedPrefs[p] = struct{}{}
|
|
if items[idx].PriorityBase != p {
|
|
items[idx].PriorityBase = p
|
|
changed = true
|
|
}
|
|
}
|
|
return items, changed
|
|
}
|