Comparison

mod_storage_appendmap/mod_storage_appendmap.lua @ 2061:b84284144e21

mod_storage_appendmap: Experimental storage module optimized for map stores
author Kim Alvefur <zash@zash.se>
date Sun, 06 Mar 2016 17:03:19 +0100
child 2062:8f7083b980cf
comparison
equal deleted inserted replaced
2060:bd0c5d546bf8 2061:b84284144e21
1 local dump = require "util.serialization".serialize;
2 local load = require "util.envload".envloadfile;
3 local dm = require "core.storagemanager".olddm;
4
5 local driver = {};
6
7 local map = {};
8 local map_mt = { __index = map };
9 map.remove = {};
10
11 function map:get(user, key)
12 module:log("debug", "map:get(%s, %s)", tostring(user), tostring(key))
13 local filename = dm.getpath(user, module.host, self.store, "map");
14 module:log("debug", "File is %s", filename);
15 local env = {};
16 if _VERSION == "Lua 5.1" then -- HACK
17 env._ENV = env; -- HACK
18 end -- SO MANY HACKS
19 local chunk, err = load(filename, env);
20 if not chunk then return chunk, err; end
21 local ok, err = pcall(chunk);
22 if not ok then return ok, err; end
23 if _VERSION == "Lua 5.1" then -- HACK
24 env._ENV = nil; -- HACK
25 end -- HACKS EVERYWHERE
26 if key == nil then
27 return env;
28 end
29 return env[key];
30 end
31
32 function map:set_keys(user, keyvalues)
33 local keys, values = {}, {};
34 if _VERSION == "Lua 5.1" then
35 assert(not keyvalues._ENV, "'_ENV' is a restricted key");
36 end
37 for key, value in pairs(keyvalues) do
38 module:log("debug", "user %s sets %q to %s", user, key, tostring(value))
39 if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then
40 key = "_ENV[" .. dump(key) .. "]";
41 end
42 table.insert(keys, key);
43 if value == self.remove then
44 table.insert(values, "nil")
45 else
46 table.insert(values, dump(value))
47 end
48 end
49 local data = table.concat(keys, ", ") .. " = " .. table.concat(values, ", ") .. ";\n";
50 return dm.append_raw(user, module.host, self.store, "map", data);
51 end
52
53 function map:set(user, key, value)
54 if _VERSION == "Lua 5.1" then
55 assert(key ~= "_ENV", "'_ENV' is a restricted key");
56 end
57 if key == nil then
58 local filename = dm.getpath(user, module.host, self.store, "map");
59 os.remove(filename);
60 return true;
61 end
62 if type(key) ~= "string" or not key:find("^[%w_][%w%d_]*$") or key == "_ENV" then
63 key = "_ENV[" .. dump(key) .. "]";
64 end
65 local data = key .. " = " .. dump(value) .. ";\n";
66 return dm.append_raw(user, module.host, self.store, "map", data);
67 end
68
69 local keyval = {};
70 local keyval_mt = { __index = keyval };
71
72 function keyval:get(user)
73 return map.get(self, user);
74 end
75
76 keyval.set = map.set_keys;
77
78 -- TODO some kind of periodic compaction thing?
79 function map:_compact(user)
80 local data = self:get(user);
81 return keyval.set(self, user, data);
82 end
83
84 function driver:open(store, typ)
85 if typ == "map" then
86 return setmetatable({ store = store, }, map_mt);
87 elseif typ == nil or typ == "keyval" then
88 return setmetatable({ store = store, }, keyval_mt);
89 end
90 return nil, "unsupported-store";
91 end
92
93 module:provides("storage", driver);
94