do
local ffi = require('ffi');
ffi.cdef[[
unsigned long shift(char *s);
unsigned long bitwise(char *s);
]]
local ibit = ffi.load('ibit');
local function str2point(str)
md5 = ngx.md5(str);
--point = tonumber(ffi.string(xbit.bitwise(ffi.cast("char *", tostring(md5)))));
point = tonumber(ibit.bitwise(ffi.cast("char *", tostring(md5))));
return point;
end
-- sps = aring
-- sp = point
local function search(sp, sps, pstart, pend, n)
n = n + 1;
local mid, mod = math.modf((pstart + pend) / 2);
if n > 20 then
ngx.log(ngx.ERR, 'the point ' .. sp .. ' cycle index exceed 20');
ngx.exit(509);
end
if sps[mid] >= sp and sps[mid - 1] < sp then
return sps[mid];
elseif sps[mid + 1] >= sp and sps[mid] < sp then
return sps[mid + 1];
elseif sps[mid] > sp then
pend = mid;
return search(sp, sps, pstart, pend, n);
elseif sps[mid] < sp then
pstart = mid;
return search(sp, sps, pstart, pend, n);
end
end
-- fps = points
-- frs = rings
-- fnode = node name
local function findhost(fp, fps, ffls, fsgls, fls, frs, fnode)
local fflag = ffls.get(fnode);
if fflag == 's' then
--ngx.say('single
');
return fsgls.get(fnode);
elseif fflag == 'h' then
local ps = fps.get(fnode);
local fend = table.getn(ps);
if fp <= ps[1] or ps[fend] < fp then
return frs.get(fnode).get(ps[1]);
else
tp = search(fp, ps, 1, fend, 0);
if tp ~= nil then
return frs.get(fnode).get(tp);
else
ngx.log(ngx.ERR, 'search ring error ' .. fp .. '
');
end
end
elseif fflag == 'l' then
floops = fls.get(fnode);
total = table.getn(floops);
math.randomseed(os.time());
rp = math.random(1, total);
return floops[rp];
end
end
ring = {
bitwise = bitwise,
str2point = str2point,
findhost = findhost,
}
end