kingluo commented on code in PR #9692:
URL: https://github.com/apache/apisix/pull/9692#discussion_r1236476468


##########
apisix/http/router/radixtree_host_uri.lua:
##########
@@ -27,20 +27,28 @@ local loadstring = loadstring
 local pairs = pairs
 local cached_router_version
 local cached_service_version
-local host_router
-local only_uri_router
+local base        = require("resty.core.base")
+local clear_tab   = base.clear_tab
 
 
 local _M = {version = 0.1}
 
 
-local function push_host_router(route, host_routes, only_uri_routes)
+local function tab_cpy(t1, t2)

Review Comment:
   remove useless function: tab_cpy



##########
apisix/http/router/radixtree_host_uri.lua:
##########
@@ -53,113 +61,256 @@ local function push_host_router(route, host_routes, 
only_uri_routes)
         filter_fun = filter_fun()
     end
 
-    local hosts = route.value.hosts
-    if not hosts then
-        if route.value.host then
-            hosts = {route.value.host}
-        elseif route.value.service_id then
-            local service = service_fetch(route.value.service_id)
-            if not service then
-                core.log.error("failed to fetch service configuration by ",
-                                "id: ", route.value.service_id)
-                -- we keep the behavior that missing service won't affect the 
route matching
-            else
-                hosts = service.value.hosts
+    local radixtree_route, pre_radixtree_route = {}, {}
+    local hosts
+    if route and route.value then
+        hosts = route.value.hosts
+        if not hosts then
+            if route.value.host then
+                hosts = {route.value.host}
+            elseif route.value.service_id then
+                local service = service_fetch(route.value.service_id)
+                if not service then
+                    core.log.error("failed to fetch service configuration by ",
+                                    "id: ", route.value.service_id)
+                    -- we keep the behavior that missing service won't affect 
the route matching
+                else
+                    hosts = service.value.hosts
+                end
+            end
+        end
+
+        radixtree_route = {
+            id = route.value.id,
+            paths = route.value.uris or route.value.uri,
+            methods = route.value.methods,
+            priority = route.value.priority,
+            remote_addrs = route.value.remote_addrs
+                        or route.value.remote_addr,
+            vars = route.value.vars,
+            filter_fun = filter_fun,
+            handler = function (api_ctx, match_opts)
+                api_ctx.matched_params = nil
+                api_ctx.matched_route = route
+                api_ctx.curr_req_matched = match_opts.matched
+                api_ctx.real_curr_req_matched_path = match_opts.matched._path
+            end
+        }
+
+        if rdx_rt ~= nil then
+            for k, v in pairs(radixtree_route) do
+                rdx_rt[k] = v
             end
         end
     end
 
-    local radixtree_route = {
-        paths = route.value.uris or route.value.uri,
-        methods = route.value.methods,
-        priority = route.value.priority,
-        remote_addrs = route.value.remote_addrs
-                       or route.value.remote_addr,
-        vars = route.value.vars,
-        filter_fun = filter_fun,
-        handler = function (api_ctx, match_opts)
-            api_ctx.matched_params = nil
-            api_ctx.matched_route = route
-            api_ctx.curr_req_matched = match_opts.matched
-            api_ctx.real_curr_req_matched_path = match_opts.matched._path
-        end
-    }
-
-    if hosts == nil then
+    if hosts == nil and all_hosts == nil then
         core.table.insert(only_uri_routes, radixtree_route)
         return
     end
 
-    for i, host in ipairs(hosts) do
-        local host_rev = host:reverse()
-        if not host_routes[host_rev] then
-            host_routes[host_rev] = {radixtree_route}
+    local pre_hosts
+    if pre_route and pre_route.value then
+        pre_hosts = pre_route.value.hosts
+        if not pre_hosts then
+            if pre_route.value.host then
+                pre_hosts = {pre_route.value.host}
+            elseif pre_route.value.service_id then
+                local service = service_fetch(pre_route.value.service_id)
+                if not service then
+                    core.log.error("failed to fetch service configuration by ",
+                                    "id: ", pre_route.value.service_id)
+                    -- we keep the behavior that missing service won't affect 
the route matching
+                else
+                    pre_hosts = service.value.hosts
+                end
+            end
+        end
+
+        pre_radixtree_route = {
+            id = pre_route.value.id,
+            paths = pre_route.value.uris or pre_route.value.uri,
+            methods = pre_route.value.methods,
+            priority = pre_route.value.priority,
+            remote_addrs = pre_route.value.remote_addrs
+                           or pre_route.value.remote_addr,
+            vars = pre_route.value.vars,
+            filter_fun = filter_fun,
+            handler = function (api_ctx, match_opts)
+                api_ctx.matched_params = nil
+                api_ctx.matched_route = pre_route
+                api_ctx.curr_req_matched = match_opts.matched
+                api_ctx.real_curr_req_matched_path = match_opts.matched._path
+            end
+        }
+
+        if pre_rdx_rt ~= nil then
+            for k, v in pairs(pre_radixtree_route) do
+                pre_rdx_rt[k] = v
+            end
+        end
+    end
+
+    if all_hosts ~= nil then
+        all_hosts["host"] = hosts
+        all_hosts["pre_host"] = pre_hosts
+    end
+
+    local pre_t = {}
+    if pre_hosts then
+        for i, h in ipairs(pre_hosts) do
+            local rev_h = h:reverse()
+            pre_t[rev_h] = 1
+        end
+    end
+
+    local t = {}
+    if hosts then
+        for i, h in ipairs(hosts) do
+            local rev_h = h:reverse()
+            t[rev_h] = 1
+        end
+    end
+
+    local comm = {}
+    for k, v in pairs(pre_t) do
+        if t[k] ~= nil then
+            tab_insert(comm, k)
+            pre_t[k] = nil
+            t[k] = nil
+        end
+    end
+
+    for _, j in ipairs(comm) do
+        local routes = host_routes[j]
+        if routes == nil then
+            core.log.error("no routes array for reverse host in the map.", j)
+            return
+        end
+
+        local found = false
+        for i, r in ipairs(routes) do
+            if r.id == radixtree_route.id then
+                routes[i] = radixtree_route
+                found = true
+                if op then
+                    table.insert(op["upd"], j)
+                end
+                break
+            end
+        end
+
+        if not found then
+            core.log.error("cannot find the route in common host's table.", j, 
radixtree_route.id)
+            return
+        end
+    end
+
+    for k, v in pairs(pre_t) do
+        local routes = host_routes[k]
+        if routes == nil then
+            core.log.error("no routes array for reverse host in the map.", k)
+            return
+        end
+
+        local found = false
+        for i, r in ipairs(routes) do
+            if r.id == pre_radixtree_route.id then
+                table.remove(routes, i)
+                found = true
+                break
+            end
+        end
+
+        if not found then
+            core.log.error("cannot find the route in previous host's table.", 
k, pre_radixtree_route.id)
+            return
+        end
+
+        if #routes == 0 then
+            host_routes[k] = nil
+            if op then
+                table.insert(op["del"], k)
+            end
+        else
+            if op then
+                table.insert(op["upd"], k)
+            end
+        end
+    end
+
+    for k, v in pairs(t) do
+        local routes = host_routes[k]
+        if routes == nil then
+            host_routes[k] = {radixtree_route}
+            if op then
+                table.insert(op["add"], k)
+            end
         else
-            tab_insert(host_routes[host_rev], radixtree_route)
+            table.insert(routes, radixtree_route)
+            if op then
+                table.insert(op["upd"], k)
+            end
         end
     end
 end
 
 
-local function create_radixtree_router(routes)
+function _M.create_radixtree_router(routes)
     local host_routes = {}
     local only_uri_routes = {}
-    host_router = nil
     routes = routes or {}
 
     for _, route in ipairs(routes) do
         local status = core.table.try_read_attr(route, "value", "status")
         -- check the status
         if not status or status == 1 then
-            push_host_router(route, host_routes, only_uri_routes)
-        end
-    end
+            _M.push_host_router(route, host_routes, only_uri_routes)
+        end 

Review Comment:
   redundant spaces



##########
apisix/http/router/radixtree_host_uri.lua:
##########
@@ -53,113 +61,256 @@ local function push_host_router(route, host_routes, 
only_uri_routes)
         filter_fun = filter_fun()
     end
 
-    local hosts = route.value.hosts
-    if not hosts then
-        if route.value.host then
-            hosts = {route.value.host}
-        elseif route.value.service_id then
-            local service = service_fetch(route.value.service_id)
-            if not service then
-                core.log.error("failed to fetch service configuration by ",
-                                "id: ", route.value.service_id)
-                -- we keep the behavior that missing service won't affect the 
route matching
-            else
-                hosts = service.value.hosts
+    local radixtree_route, pre_radixtree_route = {}, {}
+    local hosts
+    if route and route.value then
+        hosts = route.value.hosts
+        if not hosts then
+            if route.value.host then
+                hosts = {route.value.host}
+            elseif route.value.service_id then
+                local service = service_fetch(route.value.service_id)
+                if not service then
+                    core.log.error("failed to fetch service configuration by ",
+                                    "id: ", route.value.service_id)
+                    -- we keep the behavior that missing service won't affect 
the route matching
+                else
+                    hosts = service.value.hosts
+                end
+            end
+        end
+
+        radixtree_route = {
+            id = route.value.id,
+            paths = route.value.uris or route.value.uri,
+            methods = route.value.methods,
+            priority = route.value.priority,
+            remote_addrs = route.value.remote_addrs
+                        or route.value.remote_addr,
+            vars = route.value.vars,
+            filter_fun = filter_fun,
+            handler = function (api_ctx, match_opts)
+                api_ctx.matched_params = nil
+                api_ctx.matched_route = route
+                api_ctx.curr_req_matched = match_opts.matched
+                api_ctx.real_curr_req_matched_path = match_opts.matched._path
+            end
+        }
+
+        if rdx_rt ~= nil then
+            for k, v in pairs(radixtree_route) do
+                rdx_rt[k] = v
             end
         end
     end
 
-    local radixtree_route = {
-        paths = route.value.uris or route.value.uri,
-        methods = route.value.methods,
-        priority = route.value.priority,
-        remote_addrs = route.value.remote_addrs
-                       or route.value.remote_addr,
-        vars = route.value.vars,
-        filter_fun = filter_fun,
-        handler = function (api_ctx, match_opts)
-            api_ctx.matched_params = nil
-            api_ctx.matched_route = route
-            api_ctx.curr_req_matched = match_opts.matched
-            api_ctx.real_curr_req_matched_path = match_opts.matched._path
-        end
-    }
-
-    if hosts == nil then
+    if hosts == nil and all_hosts == nil then
         core.table.insert(only_uri_routes, radixtree_route)
         return
     end
 
-    for i, host in ipairs(hosts) do
-        local host_rev = host:reverse()
-        if not host_routes[host_rev] then
-            host_routes[host_rev] = {radixtree_route}
+    local pre_hosts
+    if pre_route and pre_route.value then
+        pre_hosts = pre_route.value.hosts
+        if not pre_hosts then
+            if pre_route.value.host then
+                pre_hosts = {pre_route.value.host}
+            elseif pre_route.value.service_id then
+                local service = service_fetch(pre_route.value.service_id)
+                if not service then
+                    core.log.error("failed to fetch service configuration by ",
+                                    "id: ", pre_route.value.service_id)
+                    -- we keep the behavior that missing service won't affect 
the route matching
+                else
+                    pre_hosts = service.value.hosts
+                end
+            end
+        end
+
+        pre_radixtree_route = {
+            id = pre_route.value.id,
+            paths = pre_route.value.uris or pre_route.value.uri,
+            methods = pre_route.value.methods,
+            priority = pre_route.value.priority,
+            remote_addrs = pre_route.value.remote_addrs
+                           or pre_route.value.remote_addr,
+            vars = pre_route.value.vars,
+            filter_fun = filter_fun,
+            handler = function (api_ctx, match_opts)
+                api_ctx.matched_params = nil
+                api_ctx.matched_route = pre_route
+                api_ctx.curr_req_matched = match_opts.matched
+                api_ctx.real_curr_req_matched_path = match_opts.matched._path
+            end
+        }
+
+        if pre_rdx_rt ~= nil then
+            for k, v in pairs(pre_radixtree_route) do
+                pre_rdx_rt[k] = v
+            end
+        end
+    end
+
+    if all_hosts ~= nil then
+        all_hosts["host"] = hosts
+        all_hosts["pre_host"] = pre_hosts
+    end
+
+    local pre_t = {}
+    if pre_hosts then
+        for i, h in ipairs(pre_hosts) do
+            local rev_h = h:reverse()
+            pre_t[rev_h] = 1
+        end
+    end
+
+    local t = {}
+    if hosts then
+        for i, h in ipairs(hosts) do
+            local rev_h = h:reverse()
+            t[rev_h] = 1
+        end
+    end
+
+    local comm = {}
+    for k, v in pairs(pre_t) do
+        if t[k] ~= nil then
+            tab_insert(comm, k)
+            pre_t[k] = nil
+            t[k] = nil
+        end
+    end
+
+    for _, j in ipairs(comm) do
+        local routes = host_routes[j]
+        if routes == nil then
+            core.log.error("no routes array for reverse host in the map.", j)
+            return
+        end
+
+        local found = false
+        for i, r in ipairs(routes) do
+            if r.id == radixtree_route.id then
+                routes[i] = radixtree_route
+                found = true
+                if op then
+                    table.insert(op["upd"], j)
+                end
+                break
+            end
+        end
+
+        if not found then
+            core.log.error("cannot find the route in common host's table.", j, 
radixtree_route.id)
+            return
+        end
+    end
+
+    for k, v in pairs(pre_t) do
+        local routes = host_routes[k]
+        if routes == nil then
+            core.log.error("no routes array for reverse host in the map.", k)
+            return
+        end
+
+        local found = false
+        for i, r in ipairs(routes) do
+            if r.id == pre_radixtree_route.id then
+                table.remove(routes, i)
+                found = true
+                break
+            end
+        end
+
+        if not found then
+            core.log.error("cannot find the route in previous host's table.", 
k, pre_radixtree_route.id)
+            return
+        end
+
+        if #routes == 0 then
+            host_routes[k] = nil
+            if op then
+                table.insert(op["del"], k)
+            end
+        else
+            if op then
+                table.insert(op["upd"], k)
+            end
+        end
+    end
+
+    for k, v in pairs(t) do
+        local routes = host_routes[k]
+        if routes == nil then
+            host_routes[k] = {radixtree_route}
+            if op then
+                table.insert(op["add"], k)
+            end
         else
-            tab_insert(host_routes[host_rev], radixtree_route)
+            table.insert(routes, radixtree_route)
+            if op then
+                table.insert(op["upd"], k)
+            end
         end
     end
 end
 
 
-local function create_radixtree_router(routes)
+function _M.create_radixtree_router(routes)
     local host_routes = {}
     local only_uri_routes = {}
-    host_router = nil
     routes = routes or {}
 
     for _, route in ipairs(routes) do
         local status = core.table.try_read_attr(route, "value", "status")
         -- check the status
         if not status or status == 1 then
-            push_host_router(route, host_routes, only_uri_routes)
-        end
-    end
+            _M.push_host_router(route, host_routes, only_uri_routes)
+        end 

Review Comment:
   redundant spaces



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to