Skip to content

Commit 8ebc675

Browse files
authored
perf: add rax_tree_up() to iterate the routes tree (#136)
1 parent ee3e37b commit 8ebc675

File tree

6 files changed

+101
-2
lines changed

6 files changed

+101
-2
lines changed

benchmark/match-prefix.lua

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ for i = 1, route_count do
88
end
99

1010
local rx = radix.new(routes)
11-
11+
ngx.say("case 1: route matched ")
1212
ngx.update_time()
1313
local start_time = ngx.now()
1414

@@ -25,3 +25,21 @@ ngx.say("route count: ", route_count)
2525
ngx.say("match times: ", match_times)
2626
ngx.say("time used : ", used_time, " sec")
2727
ngx.say("QPS : ", math.floor(match_times / used_time))
28+
29+
ngx.say("=================")
30+
ngx.say("case 2: route not matched ")
31+
ngx.update_time()
32+
start_time = ngx.now()
33+
34+
path = "/" .. ngx.md5(route_count + 1) .. "/a"
35+
for _ = 1, match_times do
36+
res = rx:match(path)
37+
end
38+
39+
ngx.update_time()
40+
local used_time = ngx.now() - start_time
41+
ngx.say("matched res: ", res)
42+
ngx.say("route count: ", route_count)
43+
ngx.say("match times: ", match_times)
44+
ngx.say("time used : ", used_time, " sec")
45+
ngx.say("QPS : ", math.floor(match_times / used_time))

lib/resty/radixtree.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ ffi_cdef[[
118118
void *radix_tree_search(void *t, void *it, const unsigned char *buf,
119119
size_t len);
120120
int radix_tree_prev(void *it, const unsigned char *buf, size_t len);
121+
int radix_tree_up(void *it, const unsigned char *buf, size_t len);
121122
int radix_tree_stop(void *it);
122123
123124
void *radix_tree_new_it(void *t);
@@ -847,7 +848,7 @@ local function match_route(self, path, opts, args)
847848
end
848849

849850
while true do
850-
local idx = radix.radix_tree_prev(it, path, #path)
851+
local idx = radix.radix_tree_up(it, path, #path)
851852
if idx <= 0 then
852853
break
853854
end

src/easy_rax.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,30 @@ radix_tree_prev(void *it, const unsigned char *buf, size_t len)
166166
}
167167

168168

169+
int
170+
radix_tree_up(void *it, const unsigned char *buf, size_t len)
171+
{
172+
raxIterator *iter = it;
173+
int res;
174+
175+
while (1) {
176+
res = raxUp(iter);
177+
if (!res) {
178+
return -1;
179+
}
180+
181+
if (iter->key_len > len ||
182+
memcmp(buf, iter->key, iter->key_len) != 0) {
183+
continue;
184+
}
185+
186+
break;
187+
}
188+
189+
return (int)iter->data;
190+
}
191+
192+
169193
int
170194
radix_tree_stop(void *it)
171195
{

src/easy_rax.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void *radix_tree_find(void *t, const unsigned char *buf, size_t len);
5757
void *radix_tree_search(void *t, void *it, const unsigned char *buf, size_t len);
5858
int radix_tree_prev(void *it, const unsigned char *buf, size_t len);
5959
int radix_tree_next(void *it, const unsigned char *buf, size_t len);
60+
int radix_tree_up(void *it, const unsigned char *buf, size_t len);
6061
int radix_tree_stop(void *it);
6162

6263
void *radix_tree_new_it(void *t);

src/rax.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,48 @@ int raxIteratorPrevStep(raxIterator *it, int noup) {
15011501
}
15021502
}
15031503

1504+
1505+
int raxIteratorUpStep(raxIterator *it) {
1506+
if (it->flags & RAX_ITER_EOF) {
1507+
return 1;
1508+
} else if (it->flags & RAX_ITER_JUST_SEEKED) {
1509+
it->flags &= ~RAX_ITER_JUST_SEEKED;
1510+
return 1;
1511+
}
1512+
1513+
/* Save key len, stack items and the node where we are currently
1514+
* so that on iterator EOF we can restore the current key and state. */
1515+
size_t orig_key_len = it->key_len;
1516+
size_t orig_stack_items = it->stack.items;
1517+
raxNode *orig_node = it->node;
1518+
1519+
while(1) {
1520+
/* Already on head? Can't go up, iteration finished. */
1521+
if (it->node == it->rt->head) {
1522+
it->flags |= RAX_ITER_EOF;
1523+
it->stack.items = orig_stack_items;
1524+
it->key_len = orig_key_len;
1525+
it->node = orig_node;
1526+
return 1;
1527+
}
1528+
1529+
it->node = raxStackPop(&it->stack);
1530+
1531+
/* Adjust the current key to represent the node we are
1532+
* at. */
1533+
int todel = it->node->iscompr ? it->node->size : 1;
1534+
raxIteratorDelChars(it,todel);
1535+
1536+
/* Return the key: this could be the key we found scanning a new
1537+
* subtree, or if we did not find a new subtree to explore here,
1538+
* before giving up with this node, check if it's a key itself. */
1539+
if (it->node->iskey) {
1540+
it->data = raxGetData(it->node);
1541+
return 1;
1542+
}
1543+
}
1544+
}
1545+
15041546
/* Seek an iterator at the specified element.
15051547
* Return 0 if the seek failed for syntax error or out of memory. Otherwise
15061548
* 1 is returned. When 0 is returned for out of memory, errno is set to
@@ -1718,6 +1760,18 @@ int raxPrev(raxIterator *it) {
17181760
return 1;
17191761
}
17201762

1763+
int raxUp(raxIterator *it) {
1764+
if (!raxIteratorUpStep(it)) {
1765+
errno = ENOMEM;
1766+
return 0;
1767+
}
1768+
if (it->flags & RAX_ITER_EOF) {
1769+
errno = 0;
1770+
return 0;
1771+
}
1772+
return 1;
1773+
}
1774+
17211775
/* Compare the key currently pointed by the iterator to the specified
17221776
* key according to the specified operator. Returns 1 if the comparison is
17231777
* true, otherwise 0 is returned. */

src/rax.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ void raxStart(raxIterator *it, rax *rt);
200200
int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len);
201201
int raxNext(raxIterator *it);
202202
int raxPrev(raxIterator *it);
203+
int raxUp(raxIterator *it);
203204
int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key_len);
204205
void raxStop(raxIterator *it);
205206
int raxEOF(raxIterator *it);

0 commit comments

Comments
 (0)