-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
237 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
local ffi = require("ffi") | ||
local base = require("resty.core.base") | ||
|
||
|
||
local DEFAULT_VALUE_BUF_SIZE = 512 * 2048 -- 1MB | ||
base.set_string_buf_size(DEFAULT_VALUE_BUF_SIZE) | ||
|
||
|
||
ffi.cdef([[ | ||
typedef unsigned int MDB_dbi; | ||
typedef enum { | ||
NGX_LMDB_OP_GET = 0, | ||
NGX_LMDB_OP_PREFIX, | ||
NGX_LMDB_OP_SET, | ||
NGX_LMDB_OP_DB_OPEN, | ||
NGX_LMDB_OP_DB_DROP | ||
} ngx_lua_resty_lmdb_operation_e; | ||
typedef struct { | ||
ngx_lua_resty_lmdb_operation_e opcode; | ||
ngx_str_t key; /* GET, SET */ | ||
ngx_str_t value; /* GET, SET */ | ||
MDB_dbi dbi; /* ALL OPS */ | ||
unsigned int flags; /* SET, DROP */ | ||
} ngx_lua_resty_lmdb_operation_t; | ||
typedef struct { | ||
size_t map_size; /**< Size of the data memory map */ | ||
unsigned int page_size; /**< Size of a database page. */ | ||
unsigned int max_readers; /**< max reader slots in the environment */ | ||
unsigned int num_readers; /**< max reader slots used in the environment */ | ||
unsigned int allocated_pages; /**< number of pages allocated */ | ||
size_t in_use_pages; /**< number of pages currently in-use */ | ||
unsigned int entries; /**< the number of entries (key/value pairs) in the environment */ | ||
} ngx_lua_resty_lmdb_ffi_status_t; | ||
int ngx_lua_resty_lmdb_ffi_env_info(ngx_lua_resty_lmdb_ffi_status_t *lst, char **err); | ||
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); | ||
]]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
local _M = {} | ||
|
||
|
||
local ffi = require("ffi") | ||
local table_new = require("table.new") | ||
require("resty.lmdb.ffi") | ||
local transaction = require("resty.lmdb.transaction") | ||
local base = require("resty.core.base") | ||
|
||
|
||
local DEFAULT_OPS_SIZE = 512 | ||
local DEFAULT_DB = transaction.DEFAULT_DB | ||
local C = ffi.C | ||
|
||
|
||
local ffi_string = ffi.string | ||
local get_dbi = transaction.get_dbi | ||
local err_ptr = base.get_errmsg_ptr() | ||
|
||
|
||
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) | ||
|
||
::again:: | ||
local buf = get_string_buf(value_buf_size, false) | ||
local ret = C.ngx_lua_resty_lmdb_ffi_range(ops, DEFAULT_OPS_SIZE, | ||
buf, value_buf_size, err_ptr) | ||
if ret == NGX_ERROR then | ||
return nil, ffi_string(err_ptr[0]) | ||
end | ||
|
||
if ret == NGX_AGAIN then | ||
value_buf_size = value_buf_size * 2 | ||
goto again | ||
end | ||
|
||
if ret == 0 then | ||
-- unlikely case | ||
return {} | ||
end | ||
|
||
assert(ret > 0) | ||
|
||
local res = table_new(ret, 0) | ||
|
||
for i = 1, DEFAULT_OPS_SIZE 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), | ||
} | ||
|
||
res[i] = pair | ||
end | ||
|
||
return res | ||
end | ||
|
||
|
||
return _M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#include <ngx_lua_resty_lmdb_module.h> | ||
|
||
|
||
/* | ||
* This function is the FFI call used for range lookups. | ||
* It is very similar to `ngx_lua_resty_lmdb_ffi_execute` above, | ||
* except we can only specify one key as the starting point at a time. | ||
* | ||
* The `ops[0]` will be the key to lookup, this function returns all keys | ||
* >= `ops[0].key` and up to `n` will be returned at a time. | ||
* | ||
* Returns: | ||
* * >= 0 - number of keys found. If return < `n`, then it is the last | ||
* key in the map (no more keys afterward the last result) | ||
* * `NGX_ERROR` - an error occurred, *err will contain the error string | ||
* * `NGX_AGAIN` - `buf_len` is not enough, try again with larger `buf` | ||
*/ | ||
int ngx_lua_resty_lmdb_ffi_range(ngx_lua_resty_lmdb_operation_t *ops, | ||
size_t n, u_char *buf, size_t buf_len, const char **err) | ||
{ | ||
ngx_lua_resty_lmdb_conf_t *lcf; | ||
size_t i; | ||
MDB_txn *txn; | ||
int rc; | ||
MDB_val key; | ||
MDB_val value; | ||
MDB_cursor *cur; | ||
|
||
ngx_lua_resty_lmdb_assert(n >= 1); | ||
ngx_lua_resty_lmdb_assert(ops[0].opcode == NGX_LMDB_OP_PREFIX); | ||
|
||
lcf = (ngx_lua_resty_lmdb_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, | ||
ngx_lua_resty_lmdb_module); | ||
|
||
if (lcf == NULL || lcf->env == NULL) { | ||
*err = "no LMDB environment defined"; | ||
return NGX_ERROR; | ||
} | ||
|
||
txn = lcf->ro_txn; | ||
rc = mdb_txn_renew(txn); | ||
if (rc != 0) { | ||
*err = mdb_strerror(rc); | ||
return NGX_ERROR; | ||
} | ||
|
||
rc = mdb_cursor_open(txn, ops[0].dbi, &cur); | ||
if (rc != 0) { | ||
*err = mdb_strerror(rc); | ||
mdb_txn_reset(txn); | ||
|
||
return NGX_ERROR; | ||
} | ||
|
||
/* we always have at least one ops slot as asserted above */ | ||
|
||
for (i = 0; i < n; i++) { | ||
key.mv_size = ops[i].key.len; | ||
key.mv_data = ops[i].key.data; | ||
|
||
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) { | ||
mdb_cursor_close(cur); | ||
mdb_txn_reset(txn); | ||
|
||
return NGX_AGAIN; | ||
} | ||
|
||
ops[i].value.data = buf; | ||
ops[i].value.len = 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; | ||
|
||
} else if (rc == MDB_NOTFOUND) { | ||
return i; | ||
|
||
} else { | ||
*err = mdb_strerror(rc); | ||
goto err; | ||
} | ||
} | ||
|
||
err: | ||
mdb_cursor_close(cur); | ||
mdb_txn_reset(txn); | ||
|
||
return NGX_ERROR; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters