MINOR: hlua_fcn: add Patref:add_bulk()
There is no cli equivalent for this one. It is similar to Patref:add() excepts thay it takes a table as parameter (for acl: table of keys, for maps: table of keys:values). The goal is to add multiple entries at once to limit locking time to the strict minimum. It is recommended to use this one over Patref:add() when adding multiple entries at once.
This commit is contained in:
parent
9ee37de5cf
commit
884dc6232a
@ -3498,6 +3498,22 @@ Patref class
|
||||
Affects the live pattern reference version, unless :js:func:`Patref.prepare()`
|
||||
was called and is still ongoing (waiting for commit or giveup)
|
||||
|
||||
.. js:function:: patref.add_bulk(ref, table)
|
||||
|
||||
Adds multiple entries at once to the Pattern reference. It is recommended
|
||||
to use this one over :js:func:`Patref.prepare()` to add a lot of entries
|
||||
at once because this one is more efficient.
|
||||
|
||||
:param table table: For ACL, a table of keys strings: t[0] = "key1",
|
||||
t[1] = "key2"...
|
||||
|
||||
For Maps, a table of key:value string pairs: t["key"] = "value"
|
||||
:returns: true on success and nil on failure (followed by an error message).
|
||||
|
||||
.. Note::
|
||||
Affects the live pattern reference version, unless :js:func:`Patref.prepare()`
|
||||
was called and is still pending (waiting for commit or giveup)
|
||||
|
||||
.. js:function:: Patref.del(ref, key)
|
||||
|
||||
Delete all entries matching the input key in the pattern reference. In
|
||||
|
@ -2773,6 +2773,80 @@ int hlua_patref_add(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* re-entrant helper, expects table of string as second argument on the stack */
|
||||
static int _hlua_patref_add_bulk(lua_State *L, int status, lua_KContext ctx)
|
||||
{
|
||||
struct hlua_patref *ref = hlua_checkudata(L, 1, class_patref_ref);
|
||||
char *errmsg;
|
||||
unsigned int curr_gen;
|
||||
int count = 0;
|
||||
int ret;
|
||||
|
||||
if ((ref->flags & HLUA_PATREF_FL_GEN) &&
|
||||
pat_ref_may_commit(ref->ptr, ref->curr_gen))
|
||||
curr_gen = ref->curr_gen;
|
||||
else
|
||||
curr_gen = ref->ptr->curr_gen;
|
||||
|
||||
HA_RWLOCK_WRLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
|
||||
while (lua_next(L, 2) != 0) {
|
||||
const char *key;
|
||||
const char *value = NULL;
|
||||
|
||||
/* check if we may do something to try to prevent thread contention,
|
||||
* unless we run from body/init state where hlua_yieldk is no-op
|
||||
*/
|
||||
if (count > 100 && hlua_gethlua(L)) {
|
||||
/* let's yield and wait for being called again to continue where we left off */
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
hlua_yieldk(L, 0, 0, _hlua_patref_add_bulk, TICK_ETERNITY, HLUA_CTRLYIELD); // continue
|
||||
return 0; // not reached
|
||||
|
||||
}
|
||||
|
||||
if (ref->ptr->flags & PAT_REF_SMP) {
|
||||
/* key:val table */
|
||||
luaL_checktype(L, -2, LUA_TSTRING);
|
||||
key = lua_tostring(L, -2);
|
||||
luaL_checktype(L, -1, LUA_TSTRING);
|
||||
value = lua_tostring(L, -1);
|
||||
}
|
||||
else {
|
||||
/* key-only table, use value as key */
|
||||
luaL_checktype(L, -1, LUA_TSTRING);
|
||||
key = lua_tostring(L, -1);
|
||||
}
|
||||
|
||||
if (!pat_ref_load(ref->ptr, curr_gen, key, value, -1, &errmsg)) {
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
ret = hlua_error(L, errmsg);
|
||||
ha_free(&errmsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* removes 'value'; keeps 'key' for next iteration */
|
||||
lua_pop(L, 1);
|
||||
count += 1;
|
||||
}
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
int hlua_patref_add_bulk(lua_State *L)
|
||||
{
|
||||
struct hlua_patref *ref;
|
||||
|
||||
ref = hlua_checkudata(L, 1, class_patref_ref);
|
||||
|
||||
BUG_ON(!ref);
|
||||
|
||||
/* table is in the stack at index 't' */
|
||||
lua_pushnil(L); /* first key */
|
||||
return _hlua_patref_add_bulk(L, LUA_OK, 0);
|
||||
}
|
||||
|
||||
int hlua_patref_del(lua_State *L)
|
||||
{
|
||||
struct hlua_patref *ref;
|
||||
@ -2879,6 +2953,7 @@ void hlua_fcn_new_patref(lua_State *L, struct pat_ref *ref)
|
||||
hlua_class_function(L, "giveup", hlua_patref_giveup);
|
||||
hlua_class_function(L, "purge", hlua_patref_purge);
|
||||
hlua_class_function(L, "add", hlua_patref_add);
|
||||
hlua_class_function(L, "add_bulk", hlua_patref_add_bulk);
|
||||
hlua_class_function(L, "del", hlua_patref_del);
|
||||
hlua_class_function(L, "set", hlua_patref_set);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user