Skip to content

Instantly share code, notes, and snippets.

@rShetty
Created February 27, 2018 14:41
Show Gist options
  • Save rShetty/ffdc5810c97db6fa5a2961f744af6e21 to your computer and use it in GitHub Desktop.
Save rShetty/ffdc5810c97db6fa5a2961f744af6e21 to your computer and use it in GitHub Desktop.
Weighted Distribution across servers
package main
import (
"container/heap"
"fmt"
)
type Server struct {
name string
priority int
index int
}
type PriorityQueue []*Server
func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
return pq[i].priority > pq[j].priority
}
func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}
func (pq *PriorityQueue) Push(x interface{}) {
n := len(*pq)
server := x.(*Server)
server.index = n
*pq = append(*pq, server)
}
func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
server := old[n-1]
server.index = -1
*pq = old[0 : n-1]
return server
}
func (pq *PriorityQueue) update(server *Server, name string, priority int) {
server.name = name
server.priority = priority
heap.Fix(pq, server.index)
}
func main() {
servers := map[string]int{
"svc1": 5,
"svc2": 2,
"svc3": 7,
}
pq := make(PriorityQueue, len(servers))
i := 0
totalWeight := 0
for name, priority := range servers {
pq[i] = &Server{
name: name,
priority: priority,
index: i,
}
i++
totalWeight += priority
}
heap.Init(&pq)
for i := 0; i < totalWeight; i++ {
server := heap.Pop(&pq).(*Server)
serverPriority := server.priority - 1
newServer := &Server{
name: server.name,
priority: serverPriority,
index: server.index,
}
heap.Push(&pq, newServer)
fmt.Printf("Server selected: %s\n", server.name)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment