local function gen_cache_learn_functor(redis_params, learn_script_id, conf)
local packed_conf = ucl.to_format(conf, 'msgpack')
return function(task, cache_id, is_spam)
+ local is_per_user = task:get_mempool():has_variable('stat_user')
local function learn_redis_cb(err, data)
lua_util.debugm(N, task, 'learn_cache redis cb: %s, %s', err, data)
end
lua_redis.exec_redis_script(learn_script_id,
{ task = task, is_write = true, key = cache_id },
learn_redis_cb,
- { cache_id, is_spam and "1" or "0", packed_conf })
+ { cache_id, is_spam and "1" or "0", packed_conf, is_per_user and "1" or "0" })
end
end
-- Lua script to perform cache checking for bayes classification
-- This script accepts the following parameters:
-- key1 - cache id
--- key3 - is spam
+-- key3 - is spam (1 or 0)
-- key3 - configuration table in message pack
+-- key4 - is per user (1 or 0)
local cache_id = KEYS[1]
local is_spam = KEYS[2]
local conf = cmsgpack.unpack(KEYS[3])
-cache_id = string.sub(cache_id, 1, conf.cache_prefix_len)
+local is_per_user = KEYS[4] == "1"
+cache_id = string.sub(cache_id, 1, conf.cache_elt_len)
-- Try each prefix that is in Redis (as some other instance might have set it)
for i = 0, conf.cache_max_keys do
end
local added = false
+local lim = is_per_user and conf.cache_max_elt * conf.cache_per_user_mult or conf.cache_max_elt
for i = 0, conf.cache_max_keys do
if not added then
local prefix = conf.cache_prefix .. string.rep("X", i)
local count = redis.call('HLEN', prefix)
- if count < conf.cache_max_elt then
+ if count < lim then
-- We can add it to this prefix
redis.call('HSET', prefix, cache_id, is_spam)
added = true
if not added then
-- Need to expire some keys
+ local expired = false
for i = 0, conf.cache_max_keys do
local prefix = conf.cache_prefix .. string.rep("X", i)
local exists = redis.call('EXISTS', prefix)
if exists then
- redis.call('DEL', prefix)
- redis.call('HSET', prefix, cache_id, is_spam)
-
- -- Do not expire anything else
- return true
+ if expired then
+ redis.call('DEL', prefix)
+ redis.call('HSET', prefix, cache_id, is_spam)
+
+ -- Do not expire anything else
+ expired = true
+ elseif i > 0 then
+ -- Move key to a shorter prefix, so we will rotate them eventually from lower to upper
+ local new_prefix = conf.cache_prefix .. string.rep("X", i - 1)
+ redis.call('RENAME', prefix, new_prefix)
+ end
end
end
end