forked from memcached/memcached
-
Notifications
You must be signed in to change notification settings - Fork 1
/
proxy_jump_hash.c
51 lines (39 loc) · 1.39 KB
/
proxy_jump_hash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#include "proxy.h"
typedef struct {
struct proxy_hash_caller phc; // passed back to proxy API
unsigned int buckets;
} mcplib_jump_hash_t;
static uint32_t mcplib_dist_jump_hash_get_server(uint64_t hash, void *ctx) {
mcplib_jump_hash_t *jh = ctx;
int64_t b = -1, j = 0;
while (j < jh->buckets) {
b = j;
hash = hash * 2862933555777941757ULL + 1;
j = (b + 1) * ((double)(1LL << 31) / (double)((hash >> 33) + 1));
}
return b;
}
// stack = [pool, option]
static int mcplib_dist_jump_hash_new(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_Unsigned buckets = lua_rawlen(L, 1);
mcplib_jump_hash_t *jh = lua_newuserdatauv(L, sizeof(mcplib_jump_hash_t), 0);
// don't need to loop through the table at all, just need its length.
// could optimize startup time by adding hints to the module for how to
// format pool (ie; just a total count or the full table)
jh->buckets = buckets;
jh->phc.ctx = jh;
jh->phc.selector_func = mcplib_dist_jump_hash_get_server;
lua_pushlightuserdata(L, &jh->phc);
// - return [UD, lightuserdata]
return 2;
}
int mcplib_open_dist_jump_hash(lua_State *L) {
const struct luaL_Reg jump_f[] = {
{"new", mcplib_dist_jump_hash_new},
{NULL, NULL},
};
luaL_newlib(L, jump_f);
return 1;
}