2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
10 local t_insert = table.insert;
11 local pairs, next, type = pairs, next, type;
12 local unpack = table.unpack or unpack; --luacheck: ignore 113
16 local function get(self, ...)
18 for n = 1,select('#', ...) do
19 t = t[select(n, ...)];
20 if not t then break; end
25 local function add(self, ...)
27 local count = select('#', ...);
29 local key = select(n, ...);
31 if not tab then tab = {}; t[key] = tab; end
34 t_insert(t, (select(count, ...)));
37 local function set(self, ...)
39 local count = select('#', ...);
41 local key = select(n, ...);
43 if not tab then tab = {}; t[key] = tab; end
46 t[(select(count-1, ...))] = (select(count, ...));
49 local function r(t, n, _end, ...)
50 if t == nil then return; end
51 local k = select(n, ...);
65 for _,b in pairs(t) do
74 local function remove(self, ...)
75 local _end = select('#', ...);
77 if select(n, ...) then _end = n; break; end
79 r(self.data, 1, _end, ...);
83 local function s(t, n, results, _end, ...)
84 if t == nil then return; end
85 local k = select(n, ...);
88 for _, v in pairs(t) do
92 t_insert(results, t[k]);
99 s(v, n+1, results, _end, ...);
102 for _,b in pairs(t) do
103 s(b, n+1, results, _end, ...);
108 -- Search for keys, nil == wildcard
109 local function search(self, ...)
110 local _end = select('#', ...);
112 if select(n, ...) then _end = n; break; end
115 s(self.data, 1, results, _end, ...);
119 -- Append results to an existing list
120 local function search_add(self, results, ...)
121 if not results then results = {}; end
122 local _end = select('#', ...);
124 if select(n, ...) then _end = n; break; end
126 s(self.data, 1, results, _end, ...);
130 local function iter(self, ...)
131 local query = { ... };
132 local maxdepth = select("#", ...);
133 local stack = { self.data };
135 local function it(self)
136 local depth = #stack;
137 local key = next(stack[depth], keys[depth]);
138 if key == nil then -- Go up the stack
139 stack[depth], keys[depth] = nil, nil;
147 local value = stack[depth][key];
148 if query[depth] == nil or key == query[depth] then
149 if depth == maxdepth then -- Result
150 local result = {}; -- Collect keys forming path to result
154 result[depth+1] = value;
155 return unpack(result, 1, depth+1);
156 elseif type(value) == "table" then
157 t_insert(stack, value); -- Descend
173 search_add = search_add;