From 9a26b96cf2dfb78cbd2c7c553cad363d320b1695 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 21 May 2019 16:58:44 +0100 Subject: [PATCH] [Feature] Add maps cache and type refinement --- lualib/lua_maps.lua | 69 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/lualib/lua_maps.lua b/lualib/lua_maps.lua index a21a60f4f..7cbd9ae0d 100644 --- a/lualib/lua_maps.lua +++ b/lualib/lua_maps.lua @@ -19,8 +19,62 @@ See the License for the specific language governing permissions and limitations under the License. ]]-- +local rspamd_logger = require "rspamd_logger" + local exports = {} +local maps_cache = {} + +local function map_hash_key(data, mtype) + local hash = require "rspamd_cryptobox_hash" + local st = hash.create_specific('xxh64') + st:update(data) + st:update(mtype) + + return st:hex() +end + +local function starts(where,st) + return string.sub(where,1,string.len(st))==st +end + +local function cut_prefix(where,st) + return string.sub(where,#st + 1) +end + +local function maybe_adjust_type(data,mtype) + local function check_prefix(prefix, t) + if starts(data, prefix) then + data = cut_prefix(data, prefix) + mtype = t + + return true + end + + return false + end + + local known_types = { + {'regexp;', 'regexp'}, + {'re;', 'regexp'}, + {'glob;', 'glob'}, + {'radix;', 'radix'}, + {'ipnet;', 'radix'}, + {'set;', 'set'}, + {'hash;', 'hash'}, + {'plain;', 'hash'} + } + + for _,t in ipairs(known_types) do + if check_prefix(t[1], t[2]) then + return data,mtype + end + end + + -- No change + return data,mtype +end + --[[[ -- @function lua_maps.map_add_from_ucl(opt, mtype, description) -- Creates a map from static data @@ -56,6 +110,14 @@ local function rspamd_map_add_from_ucl(opt, mtype, description) end if type(opt) == 'string' then + opt,mtype = maybe_adjust_type(opt, mtype) + local k = map_hash_key(opt, mtype) + if maps_cache[k] then + rspamd_logger.infox(rspamd_config, 'reuse url for %s(%s)', + opt, mtype) + + return maps_cache[k] + end -- We have a single string, so we treat it as a map local map = rspamd_config:add_map{ type = mtype, @@ -65,11 +127,14 @@ local function rspamd_map_add_from_ucl(opt, mtype, description) if map then ret.__data = map + ret.hash = k setmetatable(ret, ret_mt) + maps_cache[k] = ret return ret end elseif type(opt) == 'table' then -- it might be plain map or map of plain elements + -- no caching in this case (yet) if opt[1] then if mtype == 'radix' then @@ -201,10 +266,6 @@ exports.map_add_from_ucl = rspamd_map_add_from_ucl local function rspamd_maybe_check_map(key, what) local fun = require "fun" - local function starts(where,st) - return string.sub(where,1,string.len(st))==st - end - if type(what) == "table" then return fun.any(function(elt) return rspamd_maybe_check_map(key, elt) end, what) end -- 2.39.5