author | Kim Alvefur <zash@zash.se> |
Thu, 23 Mar 2017 14:31:01 +0100 | |
changeset 2648 | 0f44d04d0d18 |
parent 2639 | 4548c3d685b4 |
child 2800 | 6a7b7cb7148e |
permissions | -rw-r--r-- |
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 |
local dump = require "util.serialization".serialize; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 |
local load = require "util.envload".envloadfile; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 |
local dm = require "core.storagemanager".olddm; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 |
local driver = {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 |
local map = {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 |
local map_mt = { __index = map }; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 |
map.remove = {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 |
function map:get(user, key) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 |
module:log("debug", "map:get(%s, %s)", tostring(user), tostring(key)) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 |
local filename = dm.getpath(user, module.host, self.store, "map"); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
14 |
module:log("debug", "File is %s", filename); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
15 |
local env = {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 |
if _VERSION == "Lua 5.1" then -- HACK |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
17 |
env._ENV = env; -- HACK |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
18 |
end -- SO MANY HACKS |
2639
4548c3d685b4
mod_storage_appendmap: Successfully return nothing on ENOENT
Kim Alvefur <zash@zash.se>
parents:
2435
diff
changeset
|
19 |
local chunk, err, errno = load(filename, env); |
4548c3d685b4
mod_storage_appendmap: Successfully return nothing on ENOENT
Kim Alvefur <zash@zash.se>
parents:
2435
diff
changeset
|
20 |
if not chunk then if errno == 2 then return end return chunk, err; end |
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
21 |
local ok, err = pcall(chunk); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
22 |
if not ok then return ok, err; end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
23 |
if _VERSION == "Lua 5.1" then -- HACK |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
24 |
env._ENV = nil; -- HACK |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
25 |
end -- HACKS EVERYWHERE |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
26 |
if key == nil then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
27 |
return env; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
28 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
29 |
return env[key]; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
30 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
31 |
|
2435
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
32 |
local keywords = { |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
33 |
["do"] = true; ["and"] = true; ["else"] = true; ["break"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
34 |
["if"] = true; ["end"] = true; ["goto"] = true; ["false"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
35 |
["in"] = true; ["for"] = true; ["then"] = true; ["local"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
36 |
["or"] = true; ["nil"] = true; ["true"] = true; ["until"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
37 |
["elseif"] = true; ["function"] = true; ["not"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
38 |
["repeat"] = true; ["return"] = true; ["while"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
39 |
|
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
40 |
-- _ENV is not technically a keyword but we need to treat it as such |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
41 |
["_ENV"] = true; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
42 |
}; |
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
43 |
|
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
44 |
function map:set_keys(user, keyvalues) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
45 |
local keys, values = {}, {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
46 |
if _VERSION == "Lua 5.1" then |
2209
98354fbea63c
mod_storage_appendmap: Prevent _ENV = false
Kim Alvefur <zash@zash.se>
parents:
2066
diff
changeset
|
47 |
assert(keyvalues._ENV == nil, "'_ENV' is a restricted key"); |
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
48 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
49 |
for key, value in pairs(keyvalues) do |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
50 |
module:log("debug", "user %s sets %q to %s", user, key, tostring(value)) |
2435
623e23190c3e
mod_storage_appendmap: Escape Lua keywords
Kim Alvefur <zash@zash.se>
parents:
2434
diff
changeset
|
51 |
if type(key) ~= "string" or not key:find("^[%a_][%w_]*$") or keywords[key] then |
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
52 |
key = "_ENV[" .. dump(key) .. "]"; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
53 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
54 |
table.insert(keys, key); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
55 |
if value == self.remove then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
56 |
table.insert(values, "nil") |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
57 |
else |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
58 |
table.insert(values, dump(value)) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
59 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
61 |
local data = table.concat(keys, ", ") .. " = " .. table.concat(values, ", ") .. ";\n"; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
62 |
return dm.append_raw(user, module.host, self.store, "map", data); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
63 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
64 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 |
function map:set(user, key, value) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 |
if _VERSION == "Lua 5.1" then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
67 |
assert(key ~= "_ENV", "'_ENV' is a restricted key"); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
68 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
69 |
if key == nil then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
70 |
local filename = dm.getpath(user, module.host, self.store, "map"); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
71 |
os.remove(filename); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
72 |
return true; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
73 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 |
if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 |
key = "_ENV[" .. dump(key) .. "]"; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
76 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 |
local data = key .. " = " .. dump(value) .. ";\n"; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
78 |
return dm.append_raw(user, module.host, self.store, "map", data); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
79 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
80 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
81 |
local keyval = {}; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
82 |
local keyval_mt = { __index = keyval }; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
83 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 |
function keyval:get(user) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
85 |
return map.get(self, user); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 |
|
2066
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
88 |
function keyval:set(user, data) |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
89 |
map.set(self, user); |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
90 |
if data then |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
91 |
for k, v in pairs(data) do |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
92 |
map.set(self, user, k, v); |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
93 |
end |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
94 |
end |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
95 |
return true; |
8f7083b980cf
mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents:
2065
diff
changeset
|
96 |
end |
2065
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
97 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
98 |
-- TODO some kind of periodic compaction thing? |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
99 |
function map:_compact(user) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
100 |
local data = self:get(user); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
101 |
return keyval.set(self, user, data); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
102 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
103 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
104 |
function driver:open(store, typ) |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
105 |
if typ == "map" then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
106 |
return setmetatable({ store = store, }, map_mt); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
107 |
elseif typ == nil or typ == "keyval" then |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
108 |
return setmetatable({ store = store, }, keyval_mt); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
109 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
110 |
return nil, "unsupported-store"; |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
111 |
end |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
112 |
|
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
113 |
module:provides("storage", driver); |
b84284144e21
mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
114 |