mod_storage_appendmap/mod_storage_appendmap.lua
author Kim Alvefur <zash@zash.se>
Sun, 09 Oct 2022 21:35:18 +0200
changeset 5065 e44b868cc575
parent 2800 6a7b7cb7148e
child 5694 ea6c18ec0669
permissions -rw-r--r--
mod_storage_appendmap: Fix keyvalue writes store_raw() takes a filename, unlike most other datamanager functions that take a series of path components, leading to this bug where it would write the hostname into a file named after the first argument (commonly a username) in the working directory.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
     5
local REMOVE = {}; -- Special value for removing keys
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
     6
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
local driver = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
     9
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    10
local keywords = {
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    11
	["do"] = true; ["and"] = true; ["else"] = true; ["break"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    12
	["if"] = true; ["end"] = true; ["goto"] = true; ["false"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    13
	["in"] = true; ["for"] = true; ["then"] = true; ["local"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    14
	["or"] = true; ["nil"] = true; ["true"] = true; ["until"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    15
	["elseif"] = true; ["function"] = true; ["not"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    16
	["repeat"] = true; ["return"] = true; ["while"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    17
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    18
	-- _ENV is not technically a keyword but we need to treat it as such
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    19
	["_ENV"] = true;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    20
};
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    21
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    22
local function is_usable_identifier(s)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    23
	return type(s) == "string" and not keywords[s] and s:find("^[%a_][%w_]*$");
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    24
end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    25
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    26
local function serialize_key(key)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    27
	if is_usable_identifier(key) then
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    28
		return key;
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    29
	else
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    30
		return "_ENV[" .. dump(key) .. "]";
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    31
	end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    32
end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    33
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    34
local function serialize_value(value)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    35
	if value == REMOVE then
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    36
		return "nil";
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    37
	else
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    38
		return dump(value);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    39
	end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    40
end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    41
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    42
local function serialize_pair(key, value)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    43
	key = serialize_key(key);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    44
	value = serialize_value(value);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    45
	return key .. " = " .. value .. ";\n";
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    46
end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    47
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    48
local function serialize_map(keyvalues)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    49
	local keys, values = {}, {};
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    50
	for key, value in pairs(keyvalues) do
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    51
		key = serialize_key(key);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    52
		value = serialize_value(value);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    53
		table.insert(keys, key);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    54
		table.insert(values, value);
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    55
	end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    56
	return table.concat(keys, ", ") .. " = " .. table.concat(values, ", ") .. ";\n";
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    57
end
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    58
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    59
local map = { remove = REMOVE };
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
local map_mt = { __index = map };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
function map:get(user, key)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
	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
    64
	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
    65
	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
    66
	local env = {};
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
	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
    68
		env._ENV = env; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
	end -- SO MANY HACKS
2639
4548c3d685b4 mod_storage_appendmap: Successfully return nothing on ENOENT
Kim Alvefur <zash@zash.se>
parents: 2435
diff changeset
    70
	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
    71
	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
    72
	local ok, err = pcall(chunk);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	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
    74
	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
    75
		env._ENV = nil; -- HACK
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	end -- HACKS EVERYWHERE
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
	if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
		return env;
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
	return env[key];
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
function map:set_keys(user, keyvalues)
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    84
	local data = serialize_map(keyvalues);
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
	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
    86
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
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
    89
	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
    90
		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
    91
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
	if key == nil then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
		local filename = dm.getpath(user, module.host, self.store, "map");
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    94
		return os.remove(filename);
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
	end
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
    96
	local data = serialize_pair(key, value);
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	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
    98
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
   100
local keyval = { remove = REMOVE };
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
local keyval_mt = { __index = keyval };
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
function keyval:get(user)
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
   104
	return map.get(self, user, nil);
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
2800
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
   107
function keyval:set(user, keyvalues)
6a7b7cb7148e mod_storage_appendmap: Factor out serialization into reusable functions
Kim Alvefur <zash@zash.se>
parents: 2639
diff changeset
   108
	local data = serialize_map(keyvalues);
5065
e44b868cc575 mod_storage_appendmap: Fix keyvalue writes
Kim Alvefur <zash@zash.se>
parents: 2800
diff changeset
   109
	return dm.store_raw(dm.getpath(user, module.host, self.store, "map"), data);
2066
8f7083b980cf mod_storage_appendmap: Fix keyvalue:set()
Kim Alvefur <zash@zash.se>
parents: 2065
diff changeset
   110
end
2065
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
-- 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
   113
function map:_compact(user)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
	local data = self:get(user);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
	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
   116
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
function driver:open(store, typ)
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
	if typ == "map" then
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
		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
   121
	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
   122
		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
   123
	end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
	return nil, "unsupported-store";
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
end
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
module:provides("storage", driver);
b84284144e21 mod_storage_appendmap: Experimental storage module optimized for map stores
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128