Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into parameters-vars
Browse files Browse the repository at this point in the history
  • Loading branch information
boekkooi-lengoo committed Jan 23, 2024
2 parents 22f0010 + 2e8f493 commit d5ed57b
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 2 deletions.
20 changes: 19 additions & 1 deletion benchmark/match-prefix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ for i = 1, route_count do
end

local rx = radix.new(routes)

ngx.say("case 1: route matched ")
ngx.update_time()
local start_time = ngx.now()

Expand All @@ -25,3 +25,21 @@ ngx.say("route count: ", route_count)
ngx.say("match times: ", match_times)
ngx.say("time used : ", used_time, " sec")
ngx.say("QPS : ", math.floor(match_times / used_time))

ngx.say("=================")
ngx.say("case 2: route not matched ")
ngx.update_time()
start_time = ngx.now()

path = "/" .. ngx.md5(route_count + 1) .. "/a"
for _ = 1, match_times do
res = rx:match(path)
end

ngx.update_time()
local used_time = ngx.now() - start_time
ngx.say("matched res: ", res)
ngx.say("route count: ", route_count)
ngx.say("match times: ", match_times)
ngx.say("time used : ", used_time, " sec")
ngx.say("QPS : ", math.floor(match_times / used_time))
13 changes: 12 additions & 1 deletion lib/resty/radixtree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ ffi_cdef[[
void *radix_tree_search(void *t, void *it, const unsigned char *buf,
size_t len);
int radix_tree_prev(void *it, const unsigned char *buf, size_t len);
int radix_tree_up(void *it, const unsigned char *buf, size_t len);
int radix_tree_stop(void *it);
void *radix_tree_new_it(void *t);
Expand Down Expand Up @@ -214,6 +215,9 @@ local mt = { __index = _M, __gc = gc_free }


local function sort_route(route_a, route_b)
if route_a.priority == route_b.priority then
return #route_a.path_org > #route_b.path_org
end
return (route_a.priority or 0) > (route_b.priority or 0)
end

Expand Down Expand Up @@ -743,6 +747,13 @@ local function match_route_opts(route, path, opts, args)
if host then
local len = #hosts
for i = 1, len, 2 do
if str_find(hosts[i+1], ":", 1, true) then
if opts.vars.http_host then
host = opts.vars.http_host
end
else
host = opts.host
end
if match_host(hosts[i], hosts[i + 1], host) then
if opts_matched_exists then
if hosts[i] then
Expand Down Expand Up @@ -871,7 +882,7 @@ local function match_route(self, path, opts, args)
end

while true do
local idx = radix.radix_tree_prev(it, path, #path)
local idx = radix.radix_tree_up(it, path, #path)
if idx <= 0 then
break
end
Expand Down
38 changes: 38 additions & 0 deletions rockspec/lua-resty-radixtree-2.9.1-0.rockspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package = "lua-resty-radixtree"
version = "2.9.1-0"
source = {
url = "git://github.com/api7/lua-resty-radixtree",
branch = "v2.9.1",
}

description = {
summary = "Adaptive Radix Trees implemented in Lua for Nginx + Lua",
homepage = "https://github.com/api7/lua-resty-radixtree",
license = "Apache License 2.0",
}

dependencies = {
"lua-resty-ipmatcher",
"lua-resty-expr = 1.3.0",
}


build = {
type = "make",
build_variables = {
CFLAGS="$(CFLAGS) -std=c99 -g -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast",
LIBFLAG="$(LIBFLAG)",
LUA_LIBDIR="$(LUA_LIBDIR)",
LUA_BINDIR="$(LUA_BINDIR)",
LUA_INCDIR="$(LUA_INCDIR)",
LUA="$(LUA)",
},
install_variables = {
INST_PREFIX="$(PREFIX)",
INST_BINDIR="$(BINDIR)",
INST_LIBDIR="$(LIBDIR)",
INST_LUADIR="$(LUADIR)",
INST_CONFDIR="$(CONFDIR)",
},
}

24 changes: 24 additions & 0 deletions src/easy_rax.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,30 @@ radix_tree_prev(void *it, const unsigned char *buf, size_t len)
}


int
radix_tree_up(void *it, const unsigned char *buf, size_t len)
{
raxIterator *iter = it;
int res;

while (1) {
res = raxUp(iter);
if (!res) {
return -1;
}

if (iter->key_len > len ||
memcmp(buf, iter->key, iter->key_len) != 0) {
continue;
}

break;
}

return (int)iter->data;
}


int
radix_tree_stop(void *it)
{
Expand Down
1 change: 1 addition & 0 deletions src/easy_rax.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void *radix_tree_find(void *t, const unsigned char *buf, size_t len);
void *radix_tree_search(void *t, void *it, const unsigned char *buf, size_t len);
int radix_tree_prev(void *it, const unsigned char *buf, size_t len);
int radix_tree_next(void *it, const unsigned char *buf, size_t len);
int radix_tree_up(void *it, const unsigned char *buf, size_t len);
int radix_tree_stop(void *it);

void *radix_tree_new_it(void *t);
Expand Down
54 changes: 54 additions & 0 deletions src/rax.c
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,48 @@ int raxIteratorPrevStep(raxIterator *it, int noup) {
}
}


int raxIteratorUpStep(raxIterator *it) {
if (it->flags & RAX_ITER_EOF) {
return 1;
} else if (it->flags & RAX_ITER_JUST_SEEKED) {
it->flags &= ~RAX_ITER_JUST_SEEKED;
return 1;
}

/* Save key len, stack items and the node where we are currently
* so that on iterator EOF we can restore the current key and state. */
size_t orig_key_len = it->key_len;
size_t orig_stack_items = it->stack.items;
raxNode *orig_node = it->node;

while(1) {
/* Already on head? Can't go up, iteration finished. */
if (it->node == it->rt->head) {
it->flags |= RAX_ITER_EOF;
it->stack.items = orig_stack_items;
it->key_len = orig_key_len;
it->node = orig_node;
return 1;
}

it->node = raxStackPop(&it->stack);

/* Adjust the current key to represent the node we are
* at. */
int todel = it->node->iscompr ? it->node->size : 1;
raxIteratorDelChars(it,todel);

/* Return the key: this could be the key we found scanning a new
* subtree, or if we did not find a new subtree to explore here,
* before giving up with this node, check if it's a key itself. */
if (it->node->iskey) {
it->data = raxGetData(it->node);
return 1;
}
}
}

/* Seek an iterator at the specified element.
* Return 0 if the seek failed for syntax error or out of memory. Otherwise
* 1 is returned. When 0 is returned for out of memory, errno is set to
Expand Down Expand Up @@ -1718,6 +1760,18 @@ int raxPrev(raxIterator *it) {
return 1;
}

int raxUp(raxIterator *it) {
if (!raxIteratorUpStep(it)) {
errno = ENOMEM;
return 0;
}
if (it->flags & RAX_ITER_EOF) {
errno = 0;
return 0;
}
return 1;
}

/* Compare the key currently pointed by the iterator to the specified
* key according to the specified operator. Returns 1 if the comparison is
* true, otherwise 0 is returned. */
Expand Down
1 change: 1 addition & 0 deletions src/rax.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ void raxStart(raxIterator *it, rax *rt);
int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len);
int raxNext(raxIterator *it);
int raxPrev(raxIterator *it);
int raxUp(raxIterator *it);
int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key_len);
void raxStop(raxIterator *it);
int raxEOF(raxIterator *it);
Expand Down
139 changes: 139 additions & 0 deletions t/add.t
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,142 @@ GET /t?name=json&weight=20
--- response_body
metadata add route succeed.
--- error_code: 200



=== TEST 2: test host and port
--- config
location /t {
content_by_lua_block {
local opts = {vars = {http_host = "127.0.0.1:9080"}, host = "127.0.0.1"}
local radix = require("resty.radixtree")
local rx = radix.new({
{
paths = {"/aa*"},
hosts = {"127.0.0.1:9080"},
handler = function (ctx)
ngx.say("pass")
end
}
})
ngx.say(rx:dispatch("/aa", opts))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
pass
true
=== TEST 3: test domain and port
--- config
location /t {
content_by_lua_block {
local opts = {vars = {http_host = "www.foo.com:9080"}, host = "www.foo.com"}
local radix = require("resty.radixtree")
local rx = radix.new({
{
paths = {"/aa*"},
hosts = "www.foo.com:9080",
handler = function (ctx)
ngx.say("pass")
end
}
})
ngx.say(rx:dispatch("/aa", opts))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
pass
true
=== TEST 4: match failed
--- config
location /t {
content_by_lua_block {
local opts = {vars = {http_host = "127.0.0.1"}, host = "127.0.0.1"}
local radix = require("resty.radixtree")
local rx = radix.new({
{
paths = {"/aa*"},
hosts = "127.0.0.1:9080",
handler = function (ctx)
ngx.say("pass")
end
}
})
ngx.say(rx:dispatch("/aa", opts))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
nil
=== TEST 5: match success
--- config
location /t {
content_by_lua_block {
local opts = {vars = {http_host = "127.0.0.1:9080"}, host = "127.0.0.1"}
local radix = require("resty.radixtree")
local rx = radix.new({
{
paths = {"/aa*"},
hosts = "127.0.0.1",
handler = function (ctx)
ngx.say("pass")
end
}
})
ngx.say(rx:dispatch("/aa", opts))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
pass
true
=== TEST 6: match many host
--- config
location /t {
content_by_lua_block {
local opts = {vars = {http_host = "127.0.0.1:9980"}, host = "127.0.0.1"}
local radix = require("resty.radixtree")
local rx = radix.new({
{
paths = {"/aa*"},
hosts = {"www.foo.com:9080", "127.0.0.1:9991", "www.bar.com:9200", "127.0.0.1"},
handler = function (ctx)
ngx.say("pass")
end
}
})
ngx.say(rx:dispatch("/aa", opts))
}
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
pass
true
Loading

0 comments on commit d5ed57b

Please sign in to comment.