Skip to content

Commit

Permalink
added tests and fixed bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
dndx committed Nov 3, 2023
1 parent 9b9e0a4 commit 1f683f8
Show file tree
Hide file tree
Showing 5 changed files with 338 additions and 41 deletions.
106 changes: 81 additions & 25 deletions lib/resty/lmdb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,104 @@ local _M = {}


local transaction = require("resty.lmdb.transaction")
local range = require("resty.lmdb.range")
local status = require("resty.lmdb.status")


do
local CACHED_TXN = transaction.begin(1)
local next = next
local error = error
local assert = assert
local range_page = range.page


function _M.get(key, db)
CACHED_TXN:reset()
CACHED_TXN:get(key, db)
local res, err = CACHED_TXN:commit()
if not res then
return nil, err
end
local CACHED_TXN = transaction.begin(1)


return CACHED_TXN[1].result
function _M.get(key, db)
CACHED_TXN:reset()
CACHED_TXN:get(key, db)
local res, err = CACHED_TXN:commit()
if not res then
return nil, err
end

return CACHED_TXN[1].result
end

function _M.set(key, value, db)
CACHED_TXN:reset()
CACHED_TXN:set(key, value, db)
local res, err = CACHED_TXN:commit()
if not res then
return nil, err
end

return true
function _M.set(key, value, db)
CACHED_TXN:reset()
CACHED_TXN:set(key, value, db)
local res, err = CACHED_TXN:commit()
if not res then
return nil, err
end

return true
end


function _M.db_drop(delete, db)
delete = not not delete

CACHED_TXN:reset()
CACHED_TXN:db_drop(delete, db)
local res, err = CACHED_TXN:commit()
if not res then
return nil, err
end

return true
end

function _M.db_drop(delete, db)
delete = not not delete

CACHED_TXN:reset()
CACHED_TXN:db_drop(delete, db)
local res, err = CACHED_TXN:commit()
function _M.prefix(prefix, db)
local res, i, res_n, err_or_more
local last = prefix

return function()
::more::
if not res then
return nil, err
-- need to fetch more data
res, err_or_more = range_page(last, db)
if not res then
return nil, err_or_more
end

res_n = #res
if res_n == 0 or (i and res_n == 1) then
return nil
end

if i then
-- not the first call to prefix_page, skip the first key
i = 2

else
-- first call to prefix_page
i = 1
end
end

assert(res_n > 0)

if i > res_n then
if err_or_more then
last = res[i - 1].key
res = nil
goto more
end

-- more = false

return nil
end

return true
local key = res[i].key
local value = res[i].value
i = i + 1

return key, value
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/resty/lmdb/ffi.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ int ngx_lua_resty_lmdb_ffi_env_info(ngx_lua_resty_lmdb_ffi_status_t *lst, char *
int ngx_lua_resty_lmdb_ffi_execute(ngx_lua_resty_lmdb_operation_t *ops,
size_t n, int need_write, unsigned char *buf, size_t buf_len, char **err);
size_t n, int need_write, u_char *buf, size_t buf_len, char **err);
int ngx_lua_resty_lmdb_ffi_range(ngx_lua_resty_lmdb_operation_t *ops,
size_t n, u_char *buf, size_t buf_len, char **err);
]])
34 changes: 25 additions & 9 deletions lib/resty/lmdb/range.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,39 @@ local transaction = require("resty.lmdb.transaction")
local base = require("resty.core.base")


local C = ffi.C
local DEFAULT_OPS_SIZE = 512
local DEFAULT_DB = transaction.DEFAULT_DB
local C = ffi.C
local NGX_ERROR = ngx.ERROR
local NGX_AGAIN = ngx.AGAIN


local ffi_string = ffi.string
local ffi_new = ffi.new
local get_dbi = transaction.get_dbi
local err_ptr = base.get_errmsg_ptr()
local get_string_buf = base.get_string_buf
local get_string_buf_size = base.get_string_buf_size
local assert = assert


function _M.page(start, db)
local value_buf_size = get_string_buf_size()
local ops = ffi_new("ngx_lua_resty_lmdb_operation_t[?]", DEFAULT_OPS_SIZE)

ops[0].opcode = C.NGX_LMDB_OP_GET
cop.key.data = start
cop.key.len = #start
cop.dbi = get_dbi(false, db or DEFAULT_DB)
ops[0].opcode = C.NGX_LMDB_OP_PREFIX
ops[0].key.data = start
ops[0].key.len = #start

local dbi, err = get_dbi(false, db or DEFAULT_DB)
if err then
return nil, "unable to open DB for access: " .. err

elseif not dbi then
return nil, "DB " .. lop.db .. " does not exist"
end

ops[0].dbi = dbi

::again::
local buf = get_string_buf(value_buf_size, false)
Expand All @@ -42,27 +57,28 @@ function _M.page(start, db)

if ret == 0 then
-- unlikely case
return {}
return {}, false
end

assert(ret > 0)

local res = table_new(ret, 0)

for i = 1, DEFAULT_OPS_SIZE do
for i = 1, ret do
local cop = ops[i - 1]

assert(cop.opcode == C.NGX_LMDB_OP_PREFIX)

local pair = {
key = ffi_string(cop.key.data, cop.key.len),
value = ffi_string(cop.key.data, cop.key.len),
value = ffi_string(cop.value.data, cop.value.len),
}

res[i] = pair
end

return res
-- if ret == DEFAULT_OPS_SIZE, then it is possible there are more keys
return res, ret == DEFAULT_OPS_SIZE
end


Expand Down
23 changes: 17 additions & 6 deletions src/ngx_lua_resty_lmdb_range.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,43 @@ int ngx_lua_resty_lmdb_ffi_range(ngx_lua_resty_lmdb_operation_t *ops,
rc = mdb_cursor_get(cur, &key, &value, i == 0 ? MDB_SET_RANGE : MDB_NEXT);
if (rc == 0) {
/* key found, copy result into buf */
if (value.mv_size > buf_len) {
if (key.mv_size + value.mv_size > buf_len) {
mdb_cursor_close(cur);
mdb_txn_reset(txn);

return NGX_AGAIN;
}

ops[i].key.data = buf;
ops[i].key.len = key.mv_size;
buf = ngx_cpymem(buf, key.mv_data, key.mv_size);

ops[i].value.data = buf;
ops[i].value.len = value.mv_size;
buf = ngx_cpymem(buf, value.mv_data, value.mv_size);

ops[i].opcode = NGX_LMDB_OP_PREFIX;

buf = ngx_cpymem(buf, value.mv_data, value.mv_size);
buf_len -= value.mv_size;
buf_len -= key.mv_size + value.mv_size;

} else if (rc == MDB_NOTFOUND) {
mdb_cursor_close(cur);
mdb_txn_reset(txn);

return i;

} else {
*err = mdb_strerror(rc);
goto err;

mdb_cursor_close(cur);
mdb_txn_reset(txn);

return NGX_ERROR;
}
}

err:
mdb_cursor_close(cur);
mdb_txn_reset(txn);

return NGX_ERROR;
return i;
}
Loading

0 comments on commit 1f683f8

Please sign in to comment.