This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 5fd95ce  perf(grpc transcode): find proto in O(1) way (#5331)
5fd95ce is described below

commit 5fd95ce608973607e72f8be601bc418fe8aad2a8
Author: Bisakh <[email protected]>
AuthorDate: Wed Oct 27 07:39:39 2021 +0530

    perf(grpc transcode): find proto in O(1) way (#5331)
---
 apisix/plugins/grpc-transcode/proto.lua | 33 ++++++++++++++++++++++------
 apisix/plugins/grpc-transcode/util.lua  | 39 ++++++++++++++-------------------
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/apisix/plugins/grpc-transcode/proto.lua 
b/apisix/plugins/grpc-transcode/proto.lua
index ec515c7..33d84eb 100644
--- a/apisix/plugins/grpc-transcode/proto.lua
+++ b/apisix/plugins/grpc-transcode/proto.lua
@@ -18,6 +18,7 @@ local core        = require("apisix.core")
 local config_util = require("apisix.core.config_util")
 local protoc      = require("protoc")
 local pcall       = pcall
+local ipairs      = ipairs
 local protos
 
 
@@ -25,6 +26,7 @@ local lrucache_proto = core.lrucache.new({
     ttl = 300, count = 100
 })
 
+local proto_fake_file = "filename for loaded"
 
 local function compile_proto(content)
     local _p  = protoc.new()
@@ -33,7 +35,7 @@ local function compile_proto(content)
     -- name to keep the code below unchanged, or we can create our own load 
function with returning
     -- the loaded DescriptorProto table additionally, see more details in
     -- https://github.com/apache/apisix/pull/4368
-    local ok, res = pcall(_p.load, _p, content, "filename for loaded")
+    local ok, res = pcall(_p.load, _p, content, proto_fake_file)
     if not ok then
         return nil, res
     end
@@ -46,6 +48,12 @@ local function compile_proto(content)
 end
 
 
+local _M = {
+    version = 0.1,
+    compile_proto = compile_proto,
+    proto_fake_file = proto_fake_file
+}
+
 local function create_proto_obj(proto_id)
     if protos.values == nil then
         return nil
@@ -63,14 +71,25 @@ local function create_proto_obj(proto_id)
         return nil, "failed to find proto by id: " .. proto_id
     end
 
-    return compile_proto(content)
-end
+    local compiled, err = compile_proto(content)
 
+    if not compiled then
+        return nil, err
+    end
 
-local _M = {
-    version = 0.1,
-    compile_proto = compile_proto,
-}
+    local index = {}
+    for _, s in ipairs(compiled[proto_fake_file].service or {}) do
+        local method_index = {}
+        for _, m in ipairs(s.method) do
+            method_index[m.name] = m
+        end
+
+        index[compiled[proto_fake_file].package .. '.' .. s.name] = 
method_index
+    end
+
+    compiled[proto_fake_file].index = index
+    return compiled
+end
 
 
 function _M.fetch(proto_id)
diff --git a/apisix/plugins/grpc-transcode/util.lua 
b/apisix/plugins/grpc-transcode/util.lua
index 102e50d..8fbe962 100644
--- a/apisix/plugins/grpc-transcode/util.lua
+++ b/apisix/plugins/grpc-transcode/util.lua
@@ -14,37 +14,30 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
-local core     = require("apisix.core")
-local json     = core.json
-local pb       = require("pb")
-local ngx      = ngx
-local pairs    = pairs
-local ipairs   = ipairs
-local string   = string
-local tonumber = tonumber
-local type     = type
+local core              = require("apisix.core")
+local proto_fake_file   = 
require("apisix.plugins.grpc-transcode.proto").proto_fake_file
+local json              = core.json
+local pb                = require("pb")
+local ngx               = ngx
+local string            = string
+local tonumber          = tonumber
+local type              = type
 
 
 local _M = {version = 0.1}
 
 
 function _M.find_method(protos, service, method)
-    for k, loaded in pairs(protos) do
-        if type(loaded) == 'table' then
-            local package = loaded.package
-            for _, s in ipairs(loaded.service or {}) do
-                if package .. "." .. s.name == service then
-                    for _, m in ipairs(s.method) do
-                        if m.name == method then
-                            return m
-                        end
-                    end
-                end
-            end
-        end
+    local loaded = protos[proto_fake_file]
+    if not loaded or type(loaded) ~= "table" then
+        return nil
+    end
+
+    if not loaded.index[service] or type(loaded.index[service]) ~= "table" then
+        return nil
     end
 
-    return nil
+    return loaded.index[service][method]
 end
 
 

Reply via email to