util/multitable.lua
author Kim Alvefur <zash@zash.se>
Mon, 12 Dec 2022 07:07:13 +0100
branch0.12
changeset 12803 3784a8ce0596
parent 9696 affcbccc1dff
child 12593 39ae08180c81
permissions -rw-r--r--
Merge 0.11->0.12
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 1104
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1523
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1523
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 4901
diff changeset
     4
--
758
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 650
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 650
diff changeset
     6
-- COPYING file in the source package for more information.
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     7
--
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     8
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
     9
local select = select;
4895
36df30395c44 util.multitable: No longer use table.remove to drop elements from the stack, when key is nil immediately (on empty tables) the previous stack entry's key gets removed instead
Matthew Wild <mwild1@gmail.com>
parents: 4894
diff changeset
    10
local t_insert = table.insert;
7188
5687788a2e4d util.multitable: Localize unpack() in Lua 5.2 compatible way
Kim Alvefur <zash@zash.se>
parents: 6780
diff changeset
    11
local pairs, next, type = pairs, next, type;
9696
affcbccc1dff lint: Remove use of the 143 error code
Kim Alvefur <zash@zash.se>
parents: 8558
diff changeset
    12
local unpack = table.unpack or unpack; --luacheck: ignore 113
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    13
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
    14
local _ENV = nil;
8558
4f0f5b49bb03 vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8392
diff changeset
    15
-- luacheck: std none
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    16
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    17
local function get(self, ...)
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    18
	local t = self.data;
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    19
	for n = 1,select('#', ...) do
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    20
		t = t[select(n, ...)];
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    21
		if not t then break; end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    22
	end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    23
	return t;
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    24
end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    25
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    26
local function add(self, ...)
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    27
	local t = self.data;
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    28
	local count = select('#', ...);
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    29
	for n = 1,count-1 do
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    30
		local key = select(n, ...);
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    31
		local tab = t[key];
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    32
		if not tab then tab = {}; t[key] = tab; end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    33
		t = tab;
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    34
	end
568
b2464849c1b0 Small fix for multitable
Matthew Wild <mwild1@gmail.com>
parents: 554
diff changeset
    35
	t_insert(t, (select(count, ...)));
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    36
end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    37
650
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    38
local function set(self, ...)
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    39
	local t = self.data;
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    40
	local count = select('#', ...);
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    41
	for n = 1,count-2 do
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    42
		local key = select(n, ...);
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    43
		local tab = t[key];
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    44
		if not tab then tab = {}; t[key] = tab; end
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    45
		t = tab;
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    46
	end
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    47
	t[(select(count-1, ...))] = (select(count, ...));
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    48
end
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    49
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    50
local function r(t, n, _end, ...)
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    51
	if t == nil then return; end
650
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    52
	local k = select(n, ...);
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    53
	if n == _end then
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    54
		t[k] = nil;
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
    55
		return;
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    56
	end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    57
	if k then
1104
e9c1650054c4 util.multitable: No globals today, thank you. Fixes missing table entries and a potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
    58
		local v = t[k];
554
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    59
		if v then
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    60
			r(v, n+1, _end, ...);
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    61
			if not next(v) then
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    62
				t[k] = nil;
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    63
			end
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    64
		end
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    65
	else
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    66
		for _,b in pairs(t) do
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    67
			r(b, n+1, _end, ...);
554
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    68
			if not next(b) then
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    69
				t[_] = nil;
9a695724681d MultiTable: Remove all empty sub-tables when elements are removed
Waqas Hussain <waqas20@gmail.com>
parents: 552
diff changeset
    70
			end
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    71
		end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    72
	end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    73
end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    74
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    75
local function remove(self, ...)
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    76
	local _end = select('#', ...);
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    77
	for n = _end,1 do
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    78
		if select(n, ...) then _end = n; break; end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    79
	end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    80
	r(self.data, 1, _end, ...);
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    81
end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    82
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    83
840
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    84
local function s(t, n, results, _end, ...)
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    85
	if t == nil then return; end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    86
	local k = select(n, ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    87
	if n == _end then
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    88
		if k == nil then
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    89
			for _, v in pairs(t) do
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    90
				t_insert(results, v);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    91
			end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    92
		else
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    93
			t_insert(results, t[k]);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    94
		end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    95
		return;
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    96
	end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    97
	if k then
1104
e9c1650054c4 util.multitable: No globals today, thank you. Fixes missing table entries and a potential traceback
Matthew Wild <mwild1@gmail.com>
parents: 896
diff changeset
    98
		local v = t[k];
840
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
    99
		if v then
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   100
			s(v, n+1, results, _end, ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   101
		end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   102
	else
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   103
		for _,b in pairs(t) do
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   104
			s(b, n+1, results, _end, ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   105
		end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   106
	end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   107
end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   108
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   109
-- Search for keys, nil == wildcard
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   110
local function search(self, ...)
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   111
	local _end = select('#', ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   112
	for n = _end,1 do
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   113
		if select(n, ...) then _end = n; break; end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   114
	end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   115
	local results = {};
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   116
	s(self.data, 1, results, _end, ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   117
	return results;
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   118
end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   119
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   120
-- Append results to an existing list
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   121
local function search_add(self, results, ...)
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   122
	if not results then results = {}; end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   123
	local _end = select('#', ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   124
	for n = _end,1 do
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   125
		if select(n, ...) then _end = n; break; end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   126
	end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   127
	s(self.data, 1, results, _end, ...);
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   128
	return results;
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   129
end
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   130
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   131
local function iter(self, ...)
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   132
	local query = { ... };
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   133
	local maxdepth = select("#", ...);
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   134
	local stack = { self.data };
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   135
	local keys = { };
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7188
diff changeset
   136
	local function it(self) -- luacheck: ignore 432/self
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   137
		local depth = #stack;
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   138
		local key = next(stack[depth], keys[depth]);
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   139
		if key == nil then -- Go up the stack
4895
36df30395c44 util.multitable: No longer use table.remove to drop elements from the stack, when key is nil immediately (on empty tables) the previous stack entry's key gets removed instead
Matthew Wild <mwild1@gmail.com>
parents: 4894
diff changeset
   140
			stack[depth], keys[depth] = nil, nil;
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   141
			if depth > 1 then
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   142
				return it(self);
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   143
			end
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   144
			return; -- The end
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   145
		else
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   146
			keys[depth] = key;
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   147
		end
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   148
		local value = stack[depth][key];
4901
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   149
		if query[depth] == nil or key == query[depth] then
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   150
			if depth == maxdepth then -- Result
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   151
				local result = {}; -- Collect keys forming path to result
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   152
				for i = 1, depth do
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   153
					result[i] = keys[i];
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   154
				end
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   155
				result[depth+1] = value;
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   156
				return unpack(result, 1, depth+1);
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   157
			elseif type(value) == "table" then
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   158
				t_insert(stack, value); -- Descend
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   159
			end
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   160
		end
4901
05ea6c1ae393 util.multitable: Some fixes for iter()... always match against query, and pass value after path results
Matthew Wild <mwild1@gmail.com>
parents: 4895
diff changeset
   161
		return it(self);
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   162
	end;
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   163
	return it, self;
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   164
end
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   165
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   166
local function new()
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   167
	return {
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   168
		data = {};
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   169
		get = get;
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   170
		add = add;
650
674531bcb5c4 Added util.multitable.set
Waqas Hussain <waqas20@gmail.com>
parents: 615
diff changeset
   171
		set = set;
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   172
		remove = remove;
840
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   173
		search = search;
ad842df925c7 util.multitable: Add mt:search(), use nil for wildcard keys
Matthew Wild <mwild1@gmail.com>
parents: 760
diff changeset
   174
		search_add = search_add;
4894
c874dc4ccbd7 util.multitable: Add :iter() method to iterate over results at a fixed depth (parameters are equivalent to :search())
Matthew Wild <mwild1@gmail.com>
parents: 2923
diff changeset
   175
		iter = iter;
552
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   176
	};
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   177
end
6db1f41e475a util.multitable - A table with multiple key for each entry
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
   178
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   179
return {
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   180
	iter = iter;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   181
	new = new;
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 5776
diff changeset
   182
};