Software / code / prosody
Comparison
util/multitable.lua @ 4894:c874dc4ccbd7
util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sat, 19 May 2012 04:12:41 +0100 |
| parent | 2923:b7049746bd29 |
| child | 4895:36df30395c44 |
comparison
equal
deleted
inserted
replaced
| 4893:98ff89ab5d1d | 4894:c874dc4ccbd7 |
|---|---|
| 4 -- | 4 -- |
| 5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
| 6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
| 7 -- | 7 -- |
| 8 | 8 |
| 9 | |
| 10 | |
| 11 local select = select; | 9 local select = select; |
| 12 local t_insert = table.insert; | 10 local t_insert, t_remove = table.insert, table.remove; |
| 13 local pairs = pairs; | 11 local unpack, pairs, next, type = unpack, pairs, next, type; |
| 14 local next = next; | |
| 15 | 12 |
| 16 module "multitable" | 13 module "multitable" |
| 17 | 14 |
| 18 local function get(self, ...) | 15 local function get(self, ...) |
| 19 local t = self.data; | 16 local t = self.data; |
| 127 end | 124 end |
| 128 s(self.data, 1, results, _end, ...); | 125 s(self.data, 1, results, _end, ...); |
| 129 return results; | 126 return results; |
| 130 end | 127 end |
| 131 | 128 |
| 129 function iter(self, ...) | |
| 130 local query = { ... }; | |
| 131 local maxdepth = select("#", ...); | |
| 132 local stack = { self.data }; | |
| 133 local keys = { }; | |
| 134 local function it(self) | |
| 135 local depth = #stack; | |
| 136 local key = next(stack[depth], keys[depth]); | |
| 137 if key == nil then -- Go up the stack | |
| 138 t_remove(stack); | |
| 139 t_remove(keys); | |
| 140 if depth > 1 then | |
| 141 return it(self); | |
| 142 end | |
| 143 return; -- The end | |
| 144 else | |
| 145 keys[depth] = key; | |
| 146 end | |
| 147 local value = stack[depth][key]; | |
| 148 if depth == maxdepth then -- Result | |
| 149 local result = {}; -- Collect keys forming path to result | |
| 150 for i = 1, depth do | |
| 151 result[i] = keys[i]; | |
| 152 end | |
| 153 return unpack(result, 1, depth); | |
| 154 else | |
| 155 if (query[depth] == nil or key == query[depth]) and type(value) == "table" then -- Descend | |
| 156 t_insert(stack, value); | |
| 157 end | |
| 158 return it(self); | |
| 159 end | |
| 160 end; | |
| 161 return it, self; | |
| 162 end | |
| 163 | |
| 132 function new() | 164 function new() |
| 133 return { | 165 return { |
| 134 data = {}; | 166 data = {}; |
| 135 get = get; | 167 get = get; |
| 136 add = add; | 168 add = add; |
| 137 set = set; | 169 set = set; |
| 138 remove = remove; | 170 remove = remove; |
| 139 search = search; | 171 search = search; |
| 140 search_add = search_add; | 172 search_add = search_add; |
| 173 iter = iter; | |
| 141 }; | 174 }; |
| 142 end | 175 end |
| 143 | 176 |
| 144 return _M; | 177 return _M; |