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