aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-05-19 04:12:41 +0100
committerMatthew Wild <mwild1@gmail.com>2012-05-19 04:12:41 +0100
commit62317e3d6f1948213df6ca67bb0f28a0e36022fe (patch)
treec18cf1a047eb487e34480df575541cc6627e875d
parentc7136a5b2cc9e6da35df23c4f4dfa7d0668e5a28 (diff)
downloadprosody-62317e3d6f1948213df6ca67bb0f28a0e36022fe.tar.gz
prosody-62317e3d6f1948213df6ca67bb0f28a0e36022fe.zip
util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
-rw-r--r--util/multitable.lua43
1 files changed, 38 insertions, 5 deletions
diff --git a/util/multitable.lua b/util/multitable.lua
index 66b9bd8a..388f60f3 100644
--- a/util/multitable.lua
+++ b/util/multitable.lua
@@ -6,12 +6,9 @@
-- COPYING file in the source package for more information.
--
-
-
local select = select;
-local t_insert = table.insert;
-local pairs = pairs;
-local next = next;
+local t_insert, t_remove = table.insert, table.remove;
+local unpack, pairs, next, type = unpack, pairs, next, type;
module "multitable"
@@ -129,6 +126,41 @@ local function search_add(self, results, ...)
return results;
end
+function iter(self, ...)
+ local query = { ... };
+ local maxdepth = select("#", ...);
+ local stack = { self.data };
+ local keys = { };
+ local function it(self)
+ local depth = #stack;
+ local key = next(stack[depth], keys[depth]);
+ if key == nil then -- Go up the stack
+ t_remove(stack);
+ t_remove(keys);
+ if depth > 1 then
+ return it(self);
+ end
+ return; -- The end
+ else
+ keys[depth] = key;
+ end
+ local value = stack[depth][key];
+ if depth == maxdepth then -- Result
+ local result = {}; -- Collect keys forming path to result
+ for i = 1, depth do
+ result[i] = keys[i];
+ end
+ return unpack(result, 1, depth);
+ else
+ if (query[depth] == nil or key == query[depth]) and type(value) == "table" then -- Descend
+ t_insert(stack, value);
+ end
+ return it(self);
+ end
+ end;
+ return it, self;
+end
+
function new()
return {
data = {};
@@ -138,6 +170,7 @@ function new()
remove = remove;
search = search;
search_add = search_add;
+ iter = iter;
};
end