author | Kim Alvefur <zash@zash.se> |
Mon, 24 Aug 2015 23:17:36 +0200 | |
changeset 1788 | 1656d4fd71d0 |
parent 1759 | 0a21b16b9075 |
child 1803 | d2dd1db9ece6 |
permissions | -rw-r--r-- |
1759
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 |
-- mod_storage_lmdb |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 |
-- Copyright (C) 2015 Kim Alvefur |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 |
-- |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 |
-- This file is MIT/X11 licensed. |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 |
-- |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
-- Depends on lightningdbm |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 |
-- https://github.com/shmul/lightningdbm |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 |
-- |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 |
-- luacheck: globals prosody open |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 |
local lmdb = require"lightningmdb"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 |
local lfs = require"lfs"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 |
local path = require"util.paths"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
14 |
local serialization = require"util.serialization"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
15 |
local serialize = serialization.serialize; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 |
local deserialize = serialization.deserialize; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
17 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
18 |
local base_path = path.resolve_relative_path(prosody.paths.data, module.host); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
19 |
lfs.mkdir(base_path); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
20 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
21 |
local env = lmdb.env_create(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
22 |
assert(env:set_maxdbs(module:get_option_number("lmdb_maxdbs", 20))); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
23 |
local env_flags = 0; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
24 |
for i, flag in ipairs(module:get_option_array("lmdb_flags", {})) do |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
25 |
env_flags = env_flags + assert(lmdb["MDB_"..flag:upper()], "No such flag "..flag); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
26 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
27 |
env:open(base_path, env_flags, tonumber("640", 8)); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
28 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
29 |
local keyval = {}; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
30 |
local keyval_mt = { __index = keyval, flags = lmdb.MDB_CREATE }; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
31 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
32 |
function keyval:set(user, value) |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
33 |
local t = self.env:txn_begin(nil, 0); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
34 |
if type(value) == "table" and next(value) == nil then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
35 |
value = nil; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
36 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
37 |
if value ~= nil then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
38 |
value = serialize(value); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
39 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
40 |
local ok, err; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
41 |
if value ~= nil then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
42 |
ok, err = t:put(self.db, user, value, 0); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
43 |
else |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
44 |
ok, err = t:del(self.db, user, value); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
46 |
if not ok then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
47 |
t:abort(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
48 |
return nil, err; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 |
return t:commit(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
51 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
52 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
53 |
function keyval:get(user) |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
54 |
local t = self.env:txn_begin(nil, 0); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
55 |
local data, err = t:get(self.db, user, 0); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
56 |
if not data then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 |
t:abort(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
58 |
return nil, err; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
59 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
t:commit(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
61 |
return deserialize(data); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
63 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 |
local drivers = { |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 |
keyval = keyval_mt; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 |
} |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 |
function open(_, store, typ) |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 |
typ = typ or "keyval"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 |
local driver_mt = drivers[typ]; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 |
if not driver_mt then |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 |
return nil, "unsupported-store"; |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
73 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 |
local t = env:txn_begin(nil, 0); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 |
local db = t:dbi_open(store.."_"..typ, driver_mt.flags); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
76 |
assert(t:commit()); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
78 |
return setmetatable({ env = env, store = store, type = typ, db = db }, driver_mt); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
79 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
80 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
81 |
function module.unload() |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
82 |
env:sync(1); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
83 |
env:close(); |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 |
end |
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
85 |
|
0a21b16b9075
mod_storage_lmdb: Storage module using Lightning Memory-Mapped Database
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 |
module:provides("storage"); |