Skip to content

Instantly share code, notes, and snippets.

@rangercyh
Last active September 1, 2022 07:49
Show Gist options
  • Save rangercyh/9f2c2704804af3104babd0afc28b2cc2 to your computer and use it in GitHub Desktop.
Save rangercyh/9f2c2704804af3104babd0afc28b2cc2 to your computer and use it in GitHub Desktop.
smooth weighted round-robin balancing
local mt = {}
mt.__index = mt
function mt:get()
local max = 0
local c = 0
local cur = self.cur
for i = 1, self.num do
cur[i] = (cur[i] or 0) + self.wl[i]
if cur[i] > max then
max = cur[i]
c = i
end
end
cur[c] = cur[c] - self.sum
return c
end
function mt:add(w)
assert(w > 0, "weight must > 0")
self.num = self.num + 1
self.sum = self.sum + w
table.insert(self.wl, w)
self.cur = {}
return self.num
end
function mt:del(idx)
if idx > 0 and idx <= self.num then
self.num = self.num - 1
self.sum = self.sum - table.remove(self.wl, idx)
self.cur = {}
return true
end
end
local M = {}
function M.new(num, weighted_list)
assert(num > 0, "num must > 0" .. num)
local sum = 0
local wl = {}
if not(weighted_list) then
sum = num
for i = 1, num do
wl[i] = 1
end
else
local w = 1
for i = 1, num do
w = weighted_list[i] or 1
assert(w > 0, "weight must > 0")
wl[i] = w
sum = sum + w
end
end
return setmetatable({
num = num,
wl = wl,
sum = sum,
cur = {},
}, mt)
end
--[[test
local t = M.new(3, {10,5,1})
for i = 1, 30 do
print(t:get())
end
print('---', t:add(10))
for i = 1, 30 do
print(t:get())
end
print(t:del(1))
for i = 1, 30 do
print(t:get())
end
]]
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment