Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
vm-001 committed Dec 16, 2023
1 parent d39d311 commit 1c13ab1
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 98 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ build:
test: build
luajit spec/utils_spec.lua

test2: build
TEST_NGINX_LOG_LEVEL=info \
prove -I../test-nginx/lib -I. -r -s t/

bench: build
resty -I=./lib -I=./deps/share/lua/5.1 benchmark/match-parameter.lua

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ local x = router:match("/a/b/c")

Java style

https://blog.csdn.net/JokerLJG/article/details/127751174

- /api/users/{id}
- /api/*

Expand All @@ -28,3 +30,8 @@ go httprouter
- /api/users/:id
- /api/people/:id/profile


TODO 处理路由冲突

- /user/:name/info
- /user/:id/info
29 changes: 29 additions & 0 deletions benchmark/match-parameter-with-matched.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local radix = require("router-tree")
local route_count = 1000 * 100
local match_times = 1000 * 1000 * 10

local routes = {}
for i = 1, route_count do
routes[i] = {paths = {"/user" .. i .. "/:name"}, metadata = i}
end

local opts = {matched = {}}
local rx = radix.new(routes)

ngx.update_time()
local start_time = ngx.now()

local res
local path = "/user1/gordon"
for _ = 1, match_times do
res = rx:match(path, opts)
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))
ngx.say("each time : ", used_time * 1000 * 1000 / match_times, " ns")
5 changes: 5 additions & 0 deletions spec/trie_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,10 @@ local function test2()
print(root:get("/user4/doge"))
end

-- test params
local function test3()

end

--test1()
test2()
10 changes: 10 additions & 0 deletions spec/utils_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,14 @@ describe("utils", function()
assert.is_false(utils.starts_with("/abc", "/abcd"))
assert.is_false(utils.starts_with("/abc", "/d"))
end)

it("lcp", function()
assert.equal(0, utils.lcp("/abc", ""))
assert.equal(1, utils.lcp("/abc", "/"))
assert.equal(2, utils.lcp("/abc", "/a"))
assert.equal(4, utils.lcp("/abc", "/abc"))
assert.equal(4, utils.lcp("/abc", "/abcd"))
assert.equal(0, utils.lcp("", "/abcd"))
assert.equal(0, utils.lcp("a", "c"))
end)
end)
21 changes: 12 additions & 9 deletions src/resty/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ local sub = string.sub

local BYTE_SLASH = byte("/")
local BYTE_COLON = byte(":")
local BYTE_ASTERISK = byte("*")

local _M = {}
local mt = {__index = _M}
local Parser = {}
local mt = {__index = Parser }

local debug = false

Expand All @@ -15,26 +16,28 @@ local STATES = {
colon = 2,
}

function _M.new(path)
function Parser.new(path)
local self = {
path = path,
anchor = 1,
pos = 1,
len = string.len(path),
state = 0,
path_n = string.len(path),
state = STATES.none,
}
return setmetatable(self, mt)
end

-- /info/:user/project/:sub
function _M.next(self)
-- /info/:user/project/:sub -> ["/info/", ":user", "/project/", ":sub"]
-- /users/:id/xxx.*

function Parser.next(self)
local c

if self.state == STATES.finish then
return nil, nil
end

while self.pos <= self.len do
while self.pos <= self.path_n do
c = byte(self.path, self.pos)
if debug then
print("pos: " .. self.pos .. "(" .. string.char(c) .. ")")
Expand Down Expand Up @@ -71,4 +74,4 @@ function _M.next(self)
return sub(self.path, self.anchor, self.pos)
end

return _M
return Parser
27 changes: 18 additions & 9 deletions src/resty/router.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
local trie = require "router-tree.trie"
local utils = require "router-tree.utils"


local ipairs = ipairs
local has_wildcard = utils.has_wildcard
local clear_table = utils.clear_table


local EMPTY = {}

Expand All @@ -14,7 +15,7 @@ local function add_route(self, path, route)
local wildcard = has_wildcard(path)
if wildcard then
-- wildcard
self.tree:add(path, route) -- TODO
self.tree:add(path, route)
else
-- static
if not self.static[path] then
Expand All @@ -26,8 +27,8 @@ local function add_route(self, path, route)
end

function Router.new(routes, options)
options = options or {}
routes = routes or {}
options = options or EMPTY
routes = routes or EMPTY

if type(routes) ~= "table" then
return nil, "invalid argument: routes"
Expand All @@ -41,7 +42,7 @@ function Router.new(routes, options)

for _, route in ipairs(routes) do
local route_t = {
handler = route.handler
handler = route.handler or route.metadata
}
for _, path in ipairs(route.paths) do
add_route(self, path, route_t)
Expand All @@ -51,8 +52,12 @@ function Router.new(routes, options)
return setmetatable(self, mt)
end

function Router:match(path, opts)
--opts = opts or EMPTY
-- path: 请求路径
-- ctx(请求的参数):
-- method:
--
function Router:match(path, ctx)
ctx = ctx or EMPTY
-- dirty Implementation
local routes = self.static[path]
if routes then
Expand All @@ -63,10 +68,14 @@ function Router:match(path, opts)
return routes[1].handler
end

local route = self.tree:get(path)
local route = self.tree:get(path, ctx)
if route then
return route.handler
return route.handler or route.metadata
end
if ctx and ctx.matched then
clear_table(ctx.matched)
end
return nil
end


Expand Down
25 changes: 23 additions & 2 deletions src/resty/sample.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,33 @@ local function test4()

assert(nil == rx:match("/info/123/pubc"))
assert("doge1" == rx:match("/info/123/public"))
assert("doge2" == rx:match("/info/123/project/456"))
local ctx = { matched = {} }
assert("doge2" == rx:match("/info/123/project/456", ctx))
print(inspect(ctx))
end

local function test_example()
local mobdebug = require "mobdebug"
mobdebug.start("localhost", 28172)
local radix = require("router-tree")
local rx = radix.new({
{
paths = {"/name/:name/id/:id"},
metadata = "metadata /name",
},
})
local ctx = { matched = {} }
print(rx:match("/name/json/id/1", ctx))
print(inspect(ctx))
end



--test1()
--test2()

--test3()

test4()
--test4()

test_example()
Loading

0 comments on commit 1c13ab1

Please sign in to comment.