Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Synopsis
init_by_lua_block {
local resty_chash = require "resty.chash"
local resty_roundrobin = require "resty.roundrobin"
local resty_swrr = require "resty.swrr"

local server_list = {
["127.0.0.1:1985"] = 2,
Expand All @@ -76,6 +77,9 @@ Synopsis

local rr_up = resty_roundrobin:new(server_list)
package.loaded.my_rr_up = rr_up

local swrr_up = resty_swrr:new(server_list)
package.loaded.my_swrr_up = swrr_up
}

upstream backend_chash {
Expand Down Expand Up @@ -108,6 +112,20 @@ Synopsis
}
}

upstream backend_swrr {
server 0.0.0.1;
balancer_by_lua_block {
local b = require "ngx.balancer"

local swrr_up = package.loaded.my_swrr_up

-- Note that SWRR picks the first server randomly
local server = swrr_up:find()

assert(b.set_current_peer(server))
}
}

server {
location /chash {
proxy_pass http://backend_chash;
Expand All @@ -116,6 +134,10 @@ Synopsis
location /roundrobin {
proxy_pass http://backend_rr;
}

location /swrr {
proxy_pass http://backend_swrr;
}
}
```

Expand All @@ -124,7 +146,7 @@ Synopsis
Methods
=======

Both `resty.chash` and `resty.roundrobin` have the same apis.
Both `resty.chash`, `resty.roundrobin` and `resty.swrr` have the same apis.

[Back to TOC](#table-of-contents)

Expand Down
32 changes: 27 additions & 5 deletions chash.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define u_char unsigned char
#endif

#define CHASH_OK 0
#define CHASH_ERR -1

#define crc32_final(crc) \
crc ^= 0xffffffff
Expand Down Expand Up @@ -144,7 +146,7 @@ chash_point_init(chash_point_t *arr, uint32_t base_hash, uint32_t start,
}


void
int
chash_point_sort(chash_point_t arr[], uint32_t n)
{
chash_point_t *points;
Expand All @@ -163,6 +165,9 @@ chash_point_sort(chash_point_t arr[], uint32_t n)
step = pow(2, 32) / m;

points = (chash_point_t *) calloc(m, sizeof(chash_point_t));
if (points == NULL) {
return CHASH_ERR;
}

for (i = 0; i < n; i++) {
node = &arr[i];
Expand Down Expand Up @@ -246,10 +251,12 @@ chash_point_sort(chash_point_t arr[], uint32_t n)
}

free(points);

return CHASH_OK;
}


void
int
chash_point_add(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id,
chash_point_t *new_points)
Expand All @@ -258,9 +265,16 @@ chash_point_add(chash_point_t *old_points, uint32_t old_length,
chash_point_t *tmp_points;

tmp_points = (chash_point_t *) calloc(num, sizeof(chash_point_t));
if (tmp_points == NULL) {
return CHASH_ERR;
}

chash_point_init_crc(tmp_points, 0, base_hash, from, num, id);
chash_point_sort(tmp_points, num);

if (chash_point_sort(tmp_points, num) != CHASH_OK) {
free(tmp_points);
return CHASH_ERR;
}

j = num - 1;
k = old_length + num - 1;
Expand All @@ -283,10 +297,12 @@ chash_point_add(chash_point_t *old_points, uint32_t old_length,
}

free(tmp_points);

return CHASH_OK;
}


void
int
chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id)
{
Expand All @@ -296,7 +312,11 @@ chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
tmp_points = (chash_point_t *) calloc(num, sizeof(chash_point_t));

chash_point_init_crc(tmp_points, 0, base_hash, from, num, id);
chash_point_sort(tmp_points, num);

if (chash_point_sort(tmp_points, num) != CHASH_OK) {
free(tmp_points);
return CHASH_ERR;
}

for (i = 0, j = 0, k = 0; i < old_length; i++) {
if (j < num
Expand All @@ -315,6 +335,8 @@ chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
}

free(tmp_points);

return CHASH_OK;
}


Expand Down
6 changes: 3 additions & 3 deletions chash.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ typedef struct {
*/
void chash_point_init(chash_point_t *points, uint32_t base_hash,
uint32_t start, uint32_t num, uint32_t id) LCH_EXPORT;
void chash_point_sort(chash_point_t *points, uint32_t npoints) LCH_EXPORT;
int chash_point_sort(chash_point_t *points, uint32_t npoints) LCH_EXPORT;

void chash_point_add(chash_point_t *old_points, uint32_t old_length,
int chash_point_add(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id,
chash_point_t *new_points) LCH_EXPORT;
void chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
int chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id) LCH_EXPORT;
void chash_point_delete(chash_point_t *old_points, uint32_t old_length,
uint32_t id) LCH_EXPORT;
Expand Down
44 changes: 31 additions & 13 deletions lib/resty/chash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ local pairs = pairs
local tostring = tostring
local tonumber = tonumber
local bxor = bit.bxor
local error = error


local CHASH_OK = 0


ffi.cdef[[
Expand All @@ -31,12 +35,12 @@ typedef struct {

void chash_point_init(chash_point_t *points, uint32_t base_hash, uint32_t start,
uint32_t num, uint32_t id);
void chash_point_sort(chash_point_t *points, uint32_t size);
int chash_point_sort(chash_point_t *points, uint32_t size);

void chash_point_add(chash_point_t *old_points, uint32_t old_length,
int chash_point_add(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id,
chash_point_t *new_points);
void chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
int chash_point_reduce(chash_point_t *old_points, uint32_t old_length,
uint32_t base_hash, uint32_t from, uint32_t num, uint32_t id);
void chash_point_delete(chash_point_t *old_points, uint32_t old_length,
uint32_t id);
Expand Down Expand Up @@ -117,7 +121,9 @@ local function _precompute(nodes)
start = start + num
end

clib.chash_point_sort(points, npoints)
if clib.chash_point_sort(points, npoints) ~= CHASH_OK then
error("no memory")
end

return ids, points, npoints, newnodes
end
Expand Down Expand Up @@ -194,14 +200,21 @@ local function _incr(self, id, weight)
local new_npoints = self.npoints + weight * CONSISTENT_POINTS
if self.size < new_npoints then
new_points = ffi_new(chash_point_t, new_npoints)
self.size = new_npoints
end

local base_hash = bxor(crc32(tostring(id)), 0xffffffff)
clib.chash_point_add(self.points, self.npoints, base_hash,
old_weight * CONSISTENT_POINTS,
weight * CONSISTENT_POINTS,
index, new_points)
local rc = clib.chash_point_add(self.points, self.npoints, base_hash,
old_weight * CONSISTENT_POINTS,
weight * CONSISTENT_POINTS,
index, new_points)

if rc ~= CHASH_OK then
error("no memory")
end

if self.size < new_npoints then
self.size = new_npoints
end

self.points = new_points
self.npoints = new_npoints
Expand Down Expand Up @@ -230,10 +243,15 @@ local function _decr(self, id, weight)
end

local base_hash = bxor(crc32(tostring(id)), 0xffffffff)
clib.chash_point_reduce(self.points, self.npoints, base_hash,
(old_weight - weight) * CONSISTENT_POINTS,
CONSISTENT_POINTS * weight,
index)
local from = (old_weight - weight) * CONSISTENT_POINTS
local num = CONSISTENT_POINTS * weight

local rc = clib.chash_point_reduce(self.points, self.npoints, base_hash,
from, num, index)

if rc ~= CHASH_OK then
error("no memory")
end

nodes[id] = old_weight - weight
self.npoints = self.npoints - CONSISTENT_POINTS * weight
Expand Down
1 change: 1 addition & 0 deletions lib/resty/roundrobin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local next = next
local tonumber = tonumber
local setmetatable = setmetatable
local math_random = math.random
local error = error

local utils = require "resty.balancer.utils"

Expand Down
Loading