0.2->0.3
[prosody.git] / util / multitable.lua
1 -- Prosody IM v0.3
2 -- Copyright (C) 2008 Matthew Wild
3 -- Copyright (C) 2008 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9
10
11 local select = select;
12 local t_insert = table.insert;
13 local pairs = pairs;
14 local next = next;
15
16 module "multitable"
17
18 local function get(self, ...)
19         local t = self.data;
20         for n = 1,select('#', ...) do
21                 t = t[select(n, ...)];
22                 if not t then break; end
23         end
24         return t;
25 end
26
27 local function add(self, ...)
28         local t = self.data;
29         local count = select('#', ...);
30         for n = 1,count-1 do
31                 local key = select(n, ...);
32                 local tab = t[key];
33                 if not tab then tab = {}; t[key] = tab; end
34                 t = tab;
35         end
36         t_insert(t, (select(count, ...)));
37 end
38
39 local function set(self, ...)
40         local t = self.data;
41         local count = select('#', ...);
42         for n = 1,count-2 do
43                 local key = select(n, ...);
44                 local tab = t[key];
45                 if not tab then tab = {}; t[key] = tab; end
46                 t = tab;
47         end
48         t[(select(count-1, ...))] = (select(count, ...));
49 end
50
51 local function r(t, n, _end, ...)
52         if t == nil then return; end
53         local k = select(n, ...);
54         if n == _end then
55                 t[k] = nil;
56                 return;
57         end
58         if k then
59                 v = t[k];
60                 if v then
61                         r(v, n+1, _end, ...);
62                         if not next(v) then
63                                 t[k] = nil;
64                         end
65                 end
66         else
67                 for _,b in pairs(t) do
68                         r(b, n+1, _end, ...);
69                         if not next(b) then
70                                 t[_] = nil;
71                         end
72                 end
73         end
74 end
75
76 local function remove(self, ...)
77         local _end = select('#', ...);
78         for n = _end,1 do
79                 if select(n, ...) then _end = n; break; end
80         end
81         r(self.data, 1, _end, ...);
82 end
83
84
85 function new()
86         return {
87                 data = {};
88                 get = get;
89                 add = add;
90                 set = set;
91                 remove = remove;
92         };
93 end
94
95 return _M;