SlideShare a Scribd company logo
"TABLE"INLUA
OUTLINE
Basic of Lua "table"
Adapt Lua "table" for multiple data structure
Dive into Lua "table" source code
OVERVIEWOFLUA
OVERVIEWOFLUA
Lua is a powerful, e cient, lightweight, embeddable
scripting language.
multi-paradigm: Lua supports procedural
programming, object-oriented programming,
functional programming, etc.
dynamically-type: types are attached to values rather
than to variables.
Lua has automatic memory management with
incremental garbage collection.
OVERVIEWOFLUA
basic types ( rst-class):
1. nil (like "None" in Python, including unde ned
variables)
2. boolean: true, false
3. number: double-precision oating-point numbers
(like "double" in C)
4. string: immutable (once internalized, cannot be
changed)
5. table: associative arrays
6. function: Lua functions, C functions
7. heavy userdata
8. light userdata
9. thread: coroutines
OVERVIEWOFTABLEINLUA
Tables are the main — in fact, the only — data-
structuring mechanism in Lua.
Tables in Lua are associative arrays, that is, they can be
indexed by any value (except nil) and can hold values
of any type.
Tables are dynamic in the sense that they may grow
when data is added to them (by assigning a value to a
hitherto non-existent eld) and shrink when data is
removed from them (by assigning nil to a eld).
BASIC
TABLECREATION
-- This is a comment.
-- Empty table
local t1 = {}
-- Table as an array
local t2 = { 1, 2, "str", t1 }
-- Table as a hashtable
local t3 = {
["k1"] = "v1",
k2 = "v2",
}
-- Table as mixed data structure of array and hashtable
local t4 = {
"e1", -- stored in the array part
["k1"] = "v1", -- stored in the hash part
TABLEASANARRAY
Array Operations:
Set the element of position "n"
Get the element of position "n"
Get the number of elements
Iterate over all elements
Delete the element of position "n"
TABLEASANARRAY:SETTER
Set the element of position "n"
NOTE: index in Lua starts from 1
-- Way #1: specify the index
local t = {}
t[1] = "e1"
t[2] = "e2"
t[3] = "e3"
t[4] = "e4"
-- Way #2: use table.insert (list, [pos,] value)
local t = {}
table.insert(t, 1, "e1")
table.insert(t, 2, "e2")
-- table.insert(t, x) inserts x at the end of list t
table.insert(t, "e3")
table.insert(t, "e4")
See the manual of table.insert
TABLEASANARRAY:GETTER
Get the element of position "n"
local t = {"e1", "e2", "e3", "e4"}
-- Get the fourth element
print(t[4])
--[[
This is a multi-line comment.
Output:
e4
]]
TABLEASANARRAY:GETELEMENTNUMBER
Get the number of elements
local t = {"e1", "e2", "e3", "e4"}
-- Way #1: the length operator "#"
print(#t)
--[[
Output:
4
]]
-- Way #2
--[[
table.unpack(t) returns "e1", "e2", "e3", "e4"
so it becomes:
print(select('#', "e1", "e2", "e3", "e4"))
]]
print(select('#', table.unpack(t)))
Refer to:
manual of the length operator "#"
manual of select
manual of table.unpack
TABLEASANARRAY:ITERATION
Iterate over all elements
local t = {"e1", "e2", "e3", "e4"}
-- Forward iteration
for i = 1, 4 do
print(t[i])
end
--[[
Output:
e1
e2
e3
e4
]]
-- More general way:
for i = 1, #t do
print(t[i])
There's another way of using an iterator. We will talk
about that later.
TABLEASANARRAY:DELETE
Delete the element of position "n"
-- Way #1: set the specified element as nil
local t = {"e1", "e2", "e3", "e4"}
-- Delete the third element
t[3] = nil
--[[
NOTE:
1. Lua table will not pack the elements backward to fill the empty slot
2. the number of elements will not change
]]
print("The number of elements:", #t)
for i = 1, #t do
print(t[i])
end
--[[
Output:
TABLEASANARRAY:DELETE
Delete the element of position "n"
-- Way #2: use table.remove (list [, pos])
local t = {"e1", "e2", "e3", "e4"}
table.remove(t, 3)
print("The number of elements:", #t)
for i = 1, #t do
print(t[i])
end
--[[
Output:
The number of elements: 3
e1
e2
e4
]]
-- table.remove(t) removes the last element of list t.
See the manual of table.remove
TABLEASANARRAY:DELETE
Common misuse of table.remove in a loop
local t = {1, 2, 3, 4}
for i = 1, #t do
if t[i] < 4 then
table.remove(t, i)
end
end
--[[
Opps...
lua: xxx.lua:4: attempt to compare nil with number
stack traceback:
xxx.lua:4: in main chunk
[C]: in ?
]]
Why?
TABLEASANARRAY:DELETE
Trace the source code using print
local t = {1, 2, 3, 4}
for i = 1, #t do
print(i, t[i])
if t[i] < 4 then
table.remove(t, i)
end
end
--[[
1 1
2 3
3 nil
lua: xxx.lua:5: attempt to compare nil with number
stack traceback:
xxx.lua:5: in main chunk
[C]: in ?
]]
TABLEASANARRAY:DELETE
Straightforward solution: use backward iteration.
local t = {1, 2, 3, 4}
for i = #t, 1, -1 do
if t[i] < 4 then
table.remove(t, i)
end
end
for i = 1, #t do
print(t[i])
end
--[[
Output:
4
]]
We will see another misuse case of table.remove when
we discuss iterator ;)
TABLEASAHASHTABLE
Hashtable Operations:
Set the value of key "k"
Get the value of key "k"
Delete the value of key "k"
Iterate over all key-value pairs
Get the number of key-value pairs
TABLEASAHASHTABLE:SETTER
local t = {}
-- Way #1
t["key"] = "value"
-- Way #2: syntactic sugar
t.key = "value"
-- Compare with the following code:
local key = "key"
t[key] = "value"
TABLEASAHASHTABLE:GETTER
local t = {
"key" = "value",
}
print("t["key"] = ", t["key"])
print("t.key = ", t.key)
local k = "key"
print("t[k] = ", t[k])
-- t.k is equivalent to t["k"]
print("t.k = ", t.k)
--[[
Output:
t["key"] = value
t.key = value
t[k] = value
t.k = nil
TABLEASAHASHTABLE:DELETE
local t = {
"key" = "value",
}
t.key = nil
TABLEASAHASHTABLE:ITERATION
TABLEASAHASHTABLE:ITERATION
Meet `next (table [, index])`
Allows a program to traverse all elds of a table. Its
rst argument is a table and its second argument is
an index in this table. next returns the next index of
the table and its associated value. When called with nil
as its second argument, next returns an initial index
and its associated value. When called with the last
index, or with nil in an empty table, next returns nil. If
the second argument is absent, then it is interpreted
as nil. In particular, you can use next(t) to check
whether a table is empty.
TABLEASAHASHTABLE:ITERATION
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
local k, v
-- Note: equivalent to:
-- local k = nil
-- local v = nil
for i = 1, 3 do
k, v = next(t, k)
print(k, v)
end
-- NOTE: The order in which the indices are enumerated is not specified, even for
--[[
Output:
See the manual of next
TABLEASAHASHTABLE:ITERATION
What if we don't know there's three key-value pairs in
the table `t`?
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
local k, v = next(t, k)
while k do
-- Note: equivalent to:
-- while k ~= nil do
print(k, v)
k, v = next(t, k)
end
--[[
Output:
k2 v2
k1 v1
ITERATOR
Advanced skill: meet the "generic for" in Lua.
for {var-list} in {exp-list} do
{body}
end
Now we can write an iterator and use it in the generic
for loop!
ITERATOR
Hand-written iterator (V1):
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
local function iter(t)
local last_k
return function()
local v
last_k, v = next(t, last_k)
return last_k, v
end
end
-- Use the iterator in the generic for loop
for k, v in iter(t) do
print(k, v)
It would be di cult to understand if you don't know
anything about closure or lambda! :(
ITERATOR
Hand-written iterator (V2): we can pass a function and its
parameters in {exp-list} of "generic for".
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
for k, v in next, t do
print(k, v)
end
--[[
Output:
k3 v3
k2 v2
k1 v1
]]
Simpler code :)
It would still be di cult to understand if you don't
know functions in Lua are rst-class variables! :(
ITERATOR
There's a built-in iterator: `pairs`! XD
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
for k, v in pairs(t) do
print(k, v)
end
--[[
Output:
k3 v3
k1 v1
k2 v2
]]
See the manual of pairs
ITERATOR
There's another built-in iterator for array: `ipairs`! XD
local t = {"e1", "e2", "e3", "e4"}
-- Only forward iteration
for i, v in ipairs(t) do
print(i, v)
end
--[[
Output:
1 e1
2 e2
3 e3
4 e4
]]
See the manual of ipairs
Now we can talk about another common misuse of
table.remove in loop.
local t = {1, 2, 3, 4}
for i, v in ipairs(t) do
print("Access the element: ", v)
if v < 4 then
table.remove(t, i)
end
end
print("Result:")
for i, v in ipairs(t) do
print(i, v)
end
--[[
Output:
Access the element: 1
Access the element: 3
TABLEASAHASHTABLE:GETTHENUMBEROFKEY-VALUEPAIRS
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
-- Try the length operator "#":
print(#t)
--[[
Output:
0
]]
Opps...The length operator "#" only deals with the array
part of table. :(
TABLEASAHASHTABLE:GETTHENUMBEROFKEY-VALUEPAIRS
Since we know how to iterator over the table, we know
how to count all the key-value pairs. :)
local t = {
k1 = "v1",
k2 = "v2",
k3 = "v3",
}
local cnt = 0
for i, v in pairs(t) do
cnt = cnt + 1
end
print(cnt)
--[[
Output:
3
]]
Complexity: O(N)
DATASTRUCTURE
MATRICES/MULTI-DIMENSIONALARRAYS
Like C array:
-- Create a matrix of zeros with dimensions N by M
-- Way #1
mt = {} -- create the matrix
for i = 1, N do
mt[i] = {} -- create a new row
for j = 1, M do
mt[i][j] = 0
end
end
-- Way #2
mt = {} -- create the matrix
for i = 1, N do
for j = 1, M do
mt[i*M + j] = 0
end
end
LINKEDLISTS
-- local node = {next = node, value = v}
-- local list = first_node
function traverse(list)
local node = list
while node do
print(node.value)
node = node.next
end
end
-- We counting the nodes from 1
function insert_kth_node(list, k, node)
assert(k > 0, "invalid k")
-- Insert from front
if k == 1 then
node.next = list
STACKS
-- Use Stack as a namespace
local Stack = {}
function Stack.push(stack, element)
table.insert(stack, element)
end
function Stack.pop(stack)
table.remove(stack)
end
function Stack.top(stack)
return stack[#stack]
end
return Stack
QUEUESANDDOUBLEQUEUES
local Queue = {}
function Queue.new()
return {first = 0, last = -1}
end
function Queue.pushleft(queue, value)
local first = queue.first - 1
queue.first = first
queue[first] = value
end
function Queue.pushright(queue, value)
local last = queue.last + 1
queue.last = last
queue[last] = value
end
SETS
local Set = {}
function Set.new()
return {}
end
function Set.add(set, element)
set[element] = true
end
function Set.has(set, element)
return set[element]
end
-- Union of two sets
function Set.union(set1, set2)
local union = {}
for _, set in ipairs({set1, set2}) do
DIVEINTOLUASOURCECODE
The version of Lua source code is 5.2
I omit and modify some code for simplicity. XD
HOWDOLUASTORETABLE?
HOWDOLUASTORETABLE?
De nition in lobject.h:
typedef struct Table {
lu_byte lsizenode; /* log2 of size of `node' array */
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
int sizearray; /* size of `array' array */
} Table;
WHATDOES`TABLE`CONTAIN?
A `Table` instance has at lease three continued areas
in memory:
The `Table` instance itself.
`array`: array part of `Table`
`node`: hash part of `Table`
WHATDOES`TABLE`CONTAIN?
Fields of recording the size:
size of array part: `sizearray`
size of hash part: 2^`lsizenode`
#define twoto(x) (1<<(x))
#define sizenode(t) (twoto((t)->lsizenode))
Macros related to `Table`:
#define gnode(t,i) (&(t)->node[i])
We will meet this macro later. ;)
WHATIS`NODE`?
typedef struct Node {
TValue i_val;
TKey i_key;
} Node;
`Node` is the structure for key-value pair
Macros related to `Node`:
#define gval(n) (&(n)->i_val)
WHATIS`TVALUE`THEN?
typedef struct lua_TValue TValue;
/*
** Tagged Values. This is the basic representation of values in Lua,
** an actual value plus a tag with its type.
*/
struct lua_TValue {
Value value_;
int tt_;
};
`TValue` = Tagged Value
`TValue` contains the value and a type tag
Lua represents values as tagged unions, that is, as
pairs (t, v), where t is an integer tag identifying the type
of the value v, which is a union of C types
implementing Lua types.
omitted source code: NaN Trick
Macros related to `TValue`:
#define val_(o) ((o)->value_)
/* raw type tag of a TValue */
#define rttype(o) ((o)->tt_)
#define setobj(L,obj1,obj2) 
{ const TValue *io2=(obj2); TValue *io1=(obj1); 
io1->value_ = io2->value_; io1->tt_ = io2->tt_; }
We will meet these macros later. ;)
HOWDOESTHETAGDISTINGUISHDIFFERENTTYPESOFLUA
VALUE?
lua.h
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_NUMTAGS 9
HOWDOESTHETAGDISTINGUISHDIFFERENTTYPESOFLUA
VALUE?
/* raw type tag of a TValue */
#define rttype(o) ((o)->tt_)
/* Macros to test type */
#define checktag(o,t) (rttype(o) == (t))
#define ttistable(o) checktag((o), LUA_TTABLE)
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
Again, we will meet these macros later. ;)
WHATIS`VALUE`?
union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Number n; /* numbers */
};
`Value` can be:
`nil`? No! Tag of `TValue` is enough.
#define settt_(o,t) ((o)->tt_=(t))
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define ttisnil(o) checktag((o), LUA_TNIL)
WHATIS`VALUE`?
union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Number n; /* numbers */
};
`Value` can be:
boolean? Yes! `Value` = `b`
number? Yes! `Value` = `n`
light userdata? Yes! `Value` = `p`
light C functions? Yes! `Value` = `f`
#define val_(o) ((o)->value_)
#define num_(o) (val_(o).n)
#define nvalue(o) check_exp(ttisnumber(o), num_(o))
#define setnvalue(obj,x) 
{ TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
WHATIS`VALUE`?
union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Number n; /* numbers */
};
`Value` can be:
string, table, other function, heavy userdata, thread?
`Value` = `gc`
#define sethvalue(L,obj,x) 
{ TValue *io=(obj); 
val_(io).gc=cast(GCObject *, (x)); settt_(io, LUA_TTABLE); }
WHATIS`GCOBJECT`THEN?
lstate.h
/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;
union GCObject {
GCheader gch; /* common header */
union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
};
REVIEW:WHATIS`TVALUE`?
WHATIS`TKEY`?
typedef union TKey {
struct {
Value value_;
int tt_;
struct Node *next; /* for chaining */
} nk;
TValue tvk;
} TKey;
Macros related to `TKey`:
#define gkey(n) (&(n)->i_key.tvk)
#define gnext(n) ((n)->i_key.nk.next)
REVIEW:WHATIS`NODE`?
Combine `TValue` and `TKey` into `Node`.
WHATHAPPENSWHENCREATINGA
`TABLE`?
GENERALPROCEDUREOFLUAPROGRAM:
Lua programs are not interpreted directly from the
textual Lua le, but are compiled into bytecode, which is
then run on the Lua virtual machine.
GENERALPROCEDUREOFLUAPROGRAM:
Here we care about the execution phrase, and we will
start our analysis from function `luaV_execute`.
BRIEFINTRODUCTIONOFLUAVMANDITSINSTRUCTIONS
xed size (32 bit unsigned integer)
register-based
instruction formats (`sBx' : signed Bx):
We will meet the following guys later:
R(A) : Register A
RK(B) : Register B or a constant index
STARTFROMTHENAIVEEXAMPLE
local t = {}
0+ params, 2 slots, 1 upvalue, 1 local, 0 constants, 0 functions
1 [1] NEWTABLE 0 0 0
2 [1] RETURN 0 1
Instructions related to table creation:
1 [1] NEWTABLE 0 0 0
NEWTABLEINSTRUCTION
NEWTABLE A B C R(A) := {} (size = B,C)
Creates a new empty table at register R(A).
B: encoded size information for the array part of the
table.
C: encoded size information for the hash part of the
table.
EXECUTENEWTABLEINLUAVM
void luaV_execute (lua_State *L) {
CallInfo *ci = L->ci;
LClosure *cl;
TValue *k;
StkId base;
newframe: /* reentry point when frame changes (call/return) */
lua_assert(ci == L->ci);
cl = clLvalue(ci->func);
k = cl->p->k;
base = ci->u.l.base;
/* main loop of interpreter */
for (;;) {
Instruction i = *(ci->u.l.savedpc++);
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
Protect(traceexec(L));
}
A bit confused?
EXECUTENEWTABLEINLUAVM
We only need to trace the following part of code for the
naive example. ;)
vmcase(OP_NEWTABLE,
// Get the operator B from the instruction
int b = GETARG_B(i);
// Get the operator C from the instruction
int c = GETARG_C(i);
Table *t = luaH_new(L);
// Remember this macro: `sethvalue` ? ;)
sethvalue(L, ra, t);
)
Now we only need to look at `luaH_new`. :)
EXECUTENEWTABLEINLUAVM
Table *luaH_new (lua_State *L) {
Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
t->array = NULL;
t->sizearray = 0;
setnodevector(L, t, 0);
return t;
}
static void setnodevector (lua_State *L, Table *t, int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common `dummynode' */
lsize = 0;
}
else {
int i;
lsize = luaO_ceillog2(size);
if (lsize > MAXBITS)
Confused by `setnodevector`?
IT'SSIMPLERINOURCASE...
Table *luaH_new (lua_State *L) {
Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
t->array = NULL;
t->sizearray = 0;
t->node = cast(Node *, dummynode); /* use common `dummynode' */
t->lsizenode = 0;
t->lastfree = gnode(t, 0); /* all positions are free */
return t;
}
WHAT'S`DUMMYNODE`?
/* macro defining a nil value */
#define NILCONSTANT {NULL}, LUA_TNIL
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
static const Node dummynode_ = {
{NILCONSTANT}, /* value */
{{NILCONSTANT, NULL}} /* key */
};
All empty table in Lua points to the same memory area.
CLEVER Lua!
WHATHAPPENSWHENCREATINGA
`TABLE`?
WHATABOUTCREATINGANON-EMPTYTABLE?
We will come back to this topic later. ;)
WHATHAPPENSWHENACCESSINGA
`TABLE`?
ANOTHERNAIVEEXAMPLE:
local t = {}
return t[1]
0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 0 functions
1 [1] NEWTABLE 0 0 0
2 [2] GETTABLE 1 0 -1 ; 1
3 [2] RETURN 1 2
4 [2] RETURN 0 1
Instructions related to accessing table:
2 [2] GETTABLE 1 0 -1 ; 1
GETTABLEINSTRUCTION
GETTABLE A B C R(A) := R(B)[RK(C)]
Copies the value from a table element into register
R(A).
The table is referenced by register R(B).
The index to the table is given by RK(C), which may be
the value of register R(C) or a constant number.
EXECUTEGETTABLEINLUAVM
Look at the for loop in `luaV_execute` (lvm.c):
vmcase(OP_GETTABLE,
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
)
Now we need to look at `luaV_gettable`. :)
EXECUTEGETTABLEINLUAVM
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, TValue *val)
// Remember this macro: `ttistable` ? ;)
if (ttistable(t)) { /* `t' is a table? */
// Remember this macro: `hvalue` ? ;)
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
// Remember this macro: `ttisnil` ? ;)
if (!ttisnil(res)) { /* result is not nil? */
// Remember this macro: `setobj` ? ;)
setobj(L, val, res);
}
}
return;
}
Now only the function `luaH_get` causes our
headaches.
DIVEINTO`LUAH_GET`
/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), n)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
IT'SSIMPLERINOURCASE...
const TValue *luaH_get (Table *t, const TValue *key) {
int k;
// Remember this macro: `nvalue` ? ;)
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), n)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
}
What's the so-called specialized function
`luaH_getint`?
DIVEINTO`LUAH_GET`
/*
** search function for integers
*/
const TValue *luaH_getint (Table *t, int key) {
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
else {
lua_Number nk = cast_num(key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
If the int key is smaller than the size of array, access
the array part.
Otherwises, compute the hash value of the key, and
access the hash part.
WHATDOESTHISLOOPDO?
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
DIVEINTO`LUAH_GET`
Lua table uses open addressing to resolve hash
collision:
DIVEINTO`LUAH_GET`
Lua de nes the index of the hash part of table as
"mainposition".
The rest part of `luaH_get` is similar to
`luaH_getint`. XD
WHATHAPPENSWHENSETTINGTHE
VALUEOFA`TABLE`ELEMENT?
ALWAYSNAIVEEXAMPLE:)
local t = {}
t[1] = 3
0+ params, 2 slots, 1 upvalue, 1 local, 2 constants, 0 functions
1 [1] NEWTABLE 0 0 0
2 [2] SETTABLE 0 -1 -2 ; 1 3
3 [2] RETURN 0 1
Instructions related to accessing table:
2 [2] SETTABLE 0 -1 -2 ; 1 3
SETTABLEINSTRUCTION
SETTABLE A B C R(A)[RK(B)] := RK(C)
Copies the value from register R(C) or a constant into a
table element.
The table is referenced by register R(A).
The index to the table is given by RK(B), which may be
the value of register R(B) or a constant number.
EXECUTESETTABLEINLUAVM
Look at the for loop in `luaV_execute` (lvm.c):
vmcase(OP_SETTABLE,
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
)
It looks like the case of `GETTABLE`. XD
EXECUTESETTABLEINLUAVM
Now look at function `luaV_settable`:
void luaV_settable (lua_State *L, const TValue *t, TValue *key, TValue *val)
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
// Remember `luaH_get`?
TValue *oldval = cast(TValue *, luaH_get(h, key));
/* is there a previous entry in the table? */
if (!ttisnil(oldval) ||
/* no previous entry; must create one. (The next test is
* always true; we only need the assignment.) */
(oldval = luaH_newkey(L, h, key), 1)) {
/* (now) there is an entry with given key */
setobj(L, oldval, val); /* assign new value to that entry */
}
}
return;
}
C trick of comma operator: (a, b, c) is a sequence of
expressions, separated by commas, which evaluates to
the last expression c.
WHATDOESLUAV_SETTABLEDO?
1. Get the old value of the key.
2. If
The old value is nil: create a new key by
`luaH_newkey` and write the corresponding value.
Otherwises, rewrite the value.
WHATDOESLUAH_NEWKEYDO?
/*
** inserts a new key into a hash table; first, check whether key's main
** position is free. If not, check whether colliding node is in its main
** position or not: if it is not, move colliding node to an empty place and
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp;
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
luaG_runerror(L, "table index is NaN");
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
Don't be scared, we will take it apart. ;D
THELUCKIESTCASE
There's free space. The main position has not been
occupied. XD
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp;
mp = mainposition(t, key);
setobj(L, gkey(mp), key);
return gval(mp);
}
CASE2
There's free space. The main position has been occupied,
and that bad guy is occupying its main position. :|
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp;
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
lua_assert(!isdummy(n));
/* colliding node is in its own main position */
/* new node will go into free position */
gnext(n) = gnext(mp); /* chain new position */
gnext(mp) = n;
mp = n;
}
setobj(L, gkey(mp), key);
return gval(mp);
}
CASE3
There's free space. The main position has been occupied,
and that bad guy is not occupying its main position. :(
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp;
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
lua_assert(!isdummy(n));
othern = mainposition(t, gkey(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
gnext(mp) = NULL; /* now `mp' is free */
setnilvalue(gval(mp));
}
}
setobj(L, gkey(mp), key);
CASE4
There's no free space. :(
It will cause rehashing.
The array part may grow or shrink so that at lease half
of the array is occupied. If the array part shrinks, its
rest elements will be inserted into the hash part.
The hash part may grow or shrink, too. Its size is
determined by the number of valid key-value pair,
whose value is not nil, and the number of elements
from the shrinked array part. Moreover, the size is
guaranteed to be power of two. (Remember the
`lsizenode` eld of `Table`?)
I will not show the source code of rehashing in order not
to scare you. XD
BACKTOTHETOPICOFCREATINGANON-
EMPTYTABLEXD
What's the di erence between the following code
snippets?
local t = {"e1", "e2", "e3", "e4", "e5"}
local t = {}
t[1] = "e1"
t[2] = "e2"
t[3] = "e3"
t[4] = "e4"
t[5] = "e5"
COUNTINGTHEOCCURRENCESOF
REHASHING:
Zero rehash, resize the array part once at table creation.
:)
local t = {"e1", "e2", "e3", "e4", "e5"}
Rehash four times at SETTABLE. :(
local t = {}
t[1] = "e1" -- rehash
t[2] = "e2" -- rehash
t[3] = "e3" -- rehash
t[4] = "e4"
t[5] = "e5" -- rehash
The rehashing overhead can be much higher if there's
lots of small table in your Lua program.
LESSONLEARNED
Prefer this way to avoid initial rehashings of table.
local t = {"e1", "e2", "e3", "e4", "e5"}
MOREABOUTTABLEINLUA
metatable, metamethod
OO in Lua
Weak table
Special table: `{}` (we have meet it), `_ENV`, `_G`,
etc.
How does luajit accelerate table operations?
...
REFERENCES
"The Implementation of Lua 5.0" by Roberto
Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar
Celes
"Programming in Lua" by the leading architect of Lua,
Roberto Ierusalimschy:
"A No-Frills Introduction to Lua 5.1 VM Instructions" by
Kein-Hong Man
"Lua Performance Tips" by Roberto Ierusalimschy
Lua o cial website
First version is free online (Lua
5.0)

More Related Content

What's hot

MySQL Tuning
MySQL TuningMySQL Tuning
MySQL Tuning
Ford AntiTrust
 
B+tree Data structures presentation
B+tree Data structures presentationB+tree Data structures presentation
B+tree Data structures presentation
Muhammad Bilal Khan
 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API Examples
Bobby Curtis
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
Ashwin Kumar
 
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program CorrectnessCMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
allyn joy calcaben
 
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
Jim Czuprynski
 
Avl trees
Avl treesAvl trees
Avl trees
amna izzat
 
How the Postgres Query Optimizer Works
How the Postgres Query Optimizer WorksHow the Postgres Query Optimizer Works
How the Postgres Query Optimizer Works
EDB
 
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAsOracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Zohar Elkayam
 
Oracle Golden Gate Bidirectional Replication
Oracle Golden Gate Bidirectional ReplicationOracle Golden Gate Bidirectional Replication
Oracle Golden Gate Bidirectional Replication
Arun Sharma
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQ
George Teo
 
MongoDB Fundamentals
MongoDB FundamentalsMongoDB Fundamentals
MongoDB Fundamentals
MongoDB
 
WAND Top-k Retrieval
WAND Top-k RetrievalWAND Top-k Retrieval
WAND Top-k Retrieval
Andrew Zhang
 
Tanel Poder - Performance stories from Exadata Migrations
Tanel Poder - Performance stories from Exadata MigrationsTanel Poder - Performance stories from Exadata Migrations
Tanel Poder - Performance stories from Exadata Migrations
Tanel Poder
 
05 Creating Stored Procedures
05 Creating Stored Procedures05 Creating Stored Procedures
05 Creating Stored Procedures
rehaniltifat
 
Avl trees
Avl treesAvl trees
Avl trees
Mohd Arif
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB
Habilelabs
 
Null / Not Null value
Null / Not Null valueNull / Not Null value
Null / Not Null value
Dhirendra Chauhan
 
Redis introduction
Redis introductionRedis introduction
Advanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & moreAdvanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & more
Lukas Fittl
 

What's hot (20)

MySQL Tuning
MySQL TuningMySQL Tuning
MySQL Tuning
 
B+tree Data structures presentation
B+tree Data structures presentationB+tree Data structures presentation
B+tree Data structures presentation
 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API Examples
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
 
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program CorrectnessCMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
CMSC 56 | Lecture 12: Recursive Definition & Algorithms, and Program Correctness
 
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
Fast and Furious: Handling Edge Computing Data With Oracle 19c Fast Ingest an...
 
Avl trees
Avl treesAvl trees
Avl trees
 
How the Postgres Query Optimizer Works
How the Postgres Query Optimizer WorksHow the Postgres Query Optimizer Works
How the Postgres Query Optimizer Works
 
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAsOracle Database Performance Tuning Advanced Features and Best Practices for DBAs
Oracle Database Performance Tuning Advanced Features and Best Practices for DBAs
 
Oracle Golden Gate Bidirectional Replication
Oracle Golden Gate Bidirectional ReplicationOracle Golden Gate Bidirectional Replication
Oracle Golden Gate Bidirectional Replication
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQ
 
MongoDB Fundamentals
MongoDB FundamentalsMongoDB Fundamentals
MongoDB Fundamentals
 
WAND Top-k Retrieval
WAND Top-k RetrievalWAND Top-k Retrieval
WAND Top-k Retrieval
 
Tanel Poder - Performance stories from Exadata Migrations
Tanel Poder - Performance stories from Exadata MigrationsTanel Poder - Performance stories from Exadata Migrations
Tanel Poder - Performance stories from Exadata Migrations
 
05 Creating Stored Procedures
05 Creating Stored Procedures05 Creating Stored Procedures
05 Creating Stored Procedures
 
Avl trees
Avl treesAvl trees
Avl trees
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB
 
Null / Not Null value
Null / Not Null valueNull / Not Null value
Null / Not Null value
 
Redis introduction
Redis introductionRedis introduction
Redis introduction
 
Advanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & moreAdvanced pg_stat_statements: Filtering, Regression Testing & more
Advanced pg_stat_statements: Filtering, Regression Testing & more
 

Viewers also liked

What's wrong with web
What's wrong with webWhat's wrong with web
What's wrong with web
Sergey Rubanov
 
Lua first steps
Lua first stepsLua first steps
Lua first steps
Sander van de Graaf
 
Lua and its Ecosystem
Lua and its EcosystemLua and its Ecosystem
Lua and its Ecosystem
François Perrad
 
Web development with Lua and Sailor @ GeeCon 2015
Web development with Lua and Sailor @ GeeCon 2015Web development with Lua and Sailor @ GeeCon 2015
Web development with Lua and Sailor @ GeeCon 2015
Etiene Dalcol
 
Get started with Lua - Hackference 2016
Get started with Lua - Hackference 2016Get started with Lua - Hackference 2016
Get started with Lua - Hackference 2016
Etiene Dalcol
 
Lua as a business logic language in high load application
Lua as a business logic language in high load applicationLua as a business logic language in high load application
Lua as a business logic language in high load application
Ilya Martynov
 
Hands on lua
Hands on luaHands on lua
Hands on lua
Javier Arauz
 
Lua vs python
Lua vs pythonLua vs python
Lua vs python
HoChul Shin
 
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
Universitat Politècnica de Catalunya
 
Script up your application with Lua! -- RyanE -- OpenWest 2014
Script up your application with Lua! -- RyanE -- OpenWest 2014Script up your application with Lua! -- RyanE -- OpenWest 2014
Script up your application with Lua! -- RyanE -- OpenWest 2014
ryanerickson
 
Nginx+lua在阿里巴巴的使用
Nginx+lua在阿里巴巴的使用Nginx+lua在阿里巴巴的使用
Nginx+lua在阿里巴巴的使用
OpenRestyCon
 
淺入淺出 GDB
淺入淺出 GDB淺入淺出 GDB
淺入淺出 GDB
Jim Chang
 
Gdb tutorial-handout
Gdb tutorial-handoutGdb tutorial-handout
Gdb tutorial-handout
Suraj Kumar
 
Jeff Johnson, Research Engineer, Facebook at MLconf NYC
Jeff Johnson, Research Engineer, Facebook at MLconf NYCJeff Johnson, Research Engineer, Facebook at MLconf NYC
Jeff Johnson, Research Engineer, Facebook at MLconf NYC
MLconf
 
Learn C Programming Language by Using GDB
Learn C Programming Language by Using GDBLearn C Programming Language by Using GDB
Learn C Programming Language by Using GDB
National Cheng Kung University
 
基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送
OpenRestyCon
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用
琛琳 饶
 
Nginx-lua
Nginx-luaNginx-lua
高性能Web服务器Nginx及相关新技术的应用实践
高性能Web服务器Nginx及相关新技术的应用实践高性能Web服务器Nginx及相关新技术的应用实践
高性能Web服务器Nginx及相关新技术的应用实践
rewinx
 
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
MLconf
 

Viewers also liked (20)

What's wrong with web
What's wrong with webWhat's wrong with web
What's wrong with web
 
Lua first steps
Lua first stepsLua first steps
Lua first steps
 
Lua and its Ecosystem
Lua and its EcosystemLua and its Ecosystem
Lua and its Ecosystem
 
Web development with Lua and Sailor @ GeeCon 2015
Web development with Lua and Sailor @ GeeCon 2015Web development with Lua and Sailor @ GeeCon 2015
Web development with Lua and Sailor @ GeeCon 2015
 
Get started with Lua - Hackference 2016
Get started with Lua - Hackference 2016Get started with Lua - Hackference 2016
Get started with Lua - Hackference 2016
 
Lua as a business logic language in high load application
Lua as a business logic language in high load applicationLua as a business logic language in high load application
Lua as a business logic language in high load application
 
Hands on lua
Hands on luaHands on lua
Hands on lua
 
Lua vs python
Lua vs pythonLua vs python
Lua vs python
 
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
Deep Convnets for Video Processing (Master in Computer Vision Barcelona, 2016)
 
Script up your application with Lua! -- RyanE -- OpenWest 2014
Script up your application with Lua! -- RyanE -- OpenWest 2014Script up your application with Lua! -- RyanE -- OpenWest 2014
Script up your application with Lua! -- RyanE -- OpenWest 2014
 
Nginx+lua在阿里巴巴的使用
Nginx+lua在阿里巴巴的使用Nginx+lua在阿里巴巴的使用
Nginx+lua在阿里巴巴的使用
 
淺入淺出 GDB
淺入淺出 GDB淺入淺出 GDB
淺入淺出 GDB
 
Gdb tutorial-handout
Gdb tutorial-handoutGdb tutorial-handout
Gdb tutorial-handout
 
Jeff Johnson, Research Engineer, Facebook at MLconf NYC
Jeff Johnson, Research Engineer, Facebook at MLconf NYCJeff Johnson, Research Engineer, Facebook at MLconf NYC
Jeff Johnson, Research Engineer, Facebook at MLconf NYC
 
Learn C Programming Language by Using GDB
Learn C Programming Language by Using GDBLearn C Programming Language by Using GDB
Learn C Programming Language by Using GDB
 
基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送基于OpenResty的百万级长连接推送
基于OpenResty的百万级长连接推送
 
Perl在nginx里的应用
Perl在nginx里的应用Perl在nginx里的应用
Perl在nginx里的应用
 
Nginx-lua
Nginx-luaNginx-lua
Nginx-lua
 
高性能Web服务器Nginx及相关新技术的应用实践
高性能Web服务器Nginx及相关新技术的应用实践高性能Web服务器Nginx及相关新技术的应用实践
高性能Web服务器Nginx及相关新技术的应用实践
 
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
Soumith Chintala, Artificial Intelligence Research Engineer, Facebook at MLco...
 

Similar to The basics and design of lua table

python_avw - Unit-03.pdf
python_avw - Unit-03.pdfpython_avw - Unit-03.pdf
python_avw - Unit-03.pdf
AshaWankar1
 
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptxLecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
lokeshgoud13
 
Revision Tour 1 and 2 complete.doc
Revision Tour 1 and 2 complete.docRevision Tour 1 and 2 complete.doc
Revision Tour 1 and 2 complete.doc
SrikrishnaVundavalli
 
Tuples-and-Dictionaries.pptx
Tuples-and-Dictionaries.pptxTuples-and-Dictionaries.pptx
Tuples-and-Dictionaries.pptx
AyushTripathi998357
 
Unit - 2.pdf
Unit - 2.pdfUnit - 2.pdf
Unit - 2.pdf
AravindAnand21
 
GE3151_PSPP_UNIT_4_Notes
GE3151_PSPP_UNIT_4_NotesGE3151_PSPP_UNIT_4_Notes
GE3151_PSPP_UNIT_4_Notes
Asst.prof M.Gokilavani
 
Pytho_tuples
Pytho_tuplesPytho_tuples
11 Introduction to lists.pptx
11 Introduction to lists.pptx11 Introduction to lists.pptx
11 Introduction to lists.pptx
ssuser8e50d8
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
Aleksandras Smirnovas
 
Python Course for Beginners
Python Course for BeginnersPython Course for Beginners
Python Course for Beginners
Nandakumar P
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
Denis
 
Please help solve this in C++ So the program is working fin.pdf
Please help solve this in C++ So the program is working fin.pdfPlease help solve this in C++ So the program is working fin.pdf
Please help solve this in C++ So the program is working fin.pdf
ankit11134
 
in C++ , Design a linked list class named IntegerList to hold a seri.pdf
in C++ , Design a linked list class named IntegerList to hold a seri.pdfin C++ , Design a linked list class named IntegerList to hold a seri.pdf
in C++ , Design a linked list class named IntegerList to hold a seri.pdf
eyewaregallery
 
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdfGE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
Asst.prof M.Gokilavani
 
‏‏chap6 list tuples.pptx
‏‏chap6 list tuples.pptx‏‏chap6 list tuples.pptx
‏‏chap6 list tuples.pptx
RamiHarrathi1
 
Lists.pptx
Lists.pptxLists.pptx
Lists.pptx
Yagna15
 
List,Stacks and Queues.pptx
List,Stacks and Queues.pptxList,Stacks and Queues.pptx
List,Stacks and Queues.pptx
UmatulSaboohSaleem1
 
The Ring programming language version 1.7 book - Part 26 of 196
The Ring programming language version 1.7 book - Part 26 of 196The Ring programming language version 1.7 book - Part 26 of 196
The Ring programming language version 1.7 book - Part 26 of 196
Mahmoud Samir Fayed
 
template ltclass Tgt struct nodeType T data n.pdf
template ltclass Tgt struct nodeType      T data     n.pdftemplate ltclass Tgt struct nodeType      T data     n.pdf
template ltclass Tgt struct nodeType T data n.pdf
aceautomate
 
Fundamentals of data structures
Fundamentals of data structuresFundamentals of data structures
Fundamentals of data structures
Niraj Agarwal
 

Similar to The basics and design of lua table (20)

python_avw - Unit-03.pdf
python_avw - Unit-03.pdfpython_avw - Unit-03.pdf
python_avw - Unit-03.pdf
 
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptxLecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
 
Revision Tour 1 and 2 complete.doc
Revision Tour 1 and 2 complete.docRevision Tour 1 and 2 complete.doc
Revision Tour 1 and 2 complete.doc
 
Tuples-and-Dictionaries.pptx
Tuples-and-Dictionaries.pptxTuples-and-Dictionaries.pptx
Tuples-and-Dictionaries.pptx
 
Unit - 2.pdf
Unit - 2.pdfUnit - 2.pdf
Unit - 2.pdf
 
GE3151_PSPP_UNIT_4_Notes
GE3151_PSPP_UNIT_4_NotesGE3151_PSPP_UNIT_4_Notes
GE3151_PSPP_UNIT_4_Notes
 
Pytho_tuples
Pytho_tuplesPytho_tuples
Pytho_tuples
 
11 Introduction to lists.pptx
11 Introduction to lists.pptx11 Introduction to lists.pptx
11 Introduction to lists.pptx
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
 
Python Course for Beginners
Python Course for BeginnersPython Course for Beginners
Python Course for Beginners
 
Demystifying functional programming with Scala
Demystifying functional programming with ScalaDemystifying functional programming with Scala
Demystifying functional programming with Scala
 
Please help solve this in C++ So the program is working fin.pdf
Please help solve this in C++ So the program is working fin.pdfPlease help solve this in C++ So the program is working fin.pdf
Please help solve this in C++ So the program is working fin.pdf
 
in C++ , Design a linked list class named IntegerList to hold a seri.pdf
in C++ , Design a linked list class named IntegerList to hold a seri.pdfin C++ , Design a linked list class named IntegerList to hold a seri.pdf
in C++ , Design a linked list class named IntegerList to hold a seri.pdf
 
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdfGE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
GE3151 PSPP UNIT IV QUESTION BANK.docx.pdf
 
‏‏chap6 list tuples.pptx
‏‏chap6 list tuples.pptx‏‏chap6 list tuples.pptx
‏‏chap6 list tuples.pptx
 
Lists.pptx
Lists.pptxLists.pptx
Lists.pptx
 
List,Stacks and Queues.pptx
List,Stacks and Queues.pptxList,Stacks and Queues.pptx
List,Stacks and Queues.pptx
 
The Ring programming language version 1.7 book - Part 26 of 196
The Ring programming language version 1.7 book - Part 26 of 196The Ring programming language version 1.7 book - Part 26 of 196
The Ring programming language version 1.7 book - Part 26 of 196
 
template ltclass Tgt struct nodeType T data n.pdf
template ltclass Tgt struct nodeType      T data     n.pdftemplate ltclass Tgt struct nodeType      T data     n.pdf
template ltclass Tgt struct nodeType T data n.pdf
 
Fundamentals of data structures
Fundamentals of data structuresFundamentals of data structures
Fundamentals of data structures
 

Recently uploaded

Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
James Anderson
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
Kumud Singh
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
Pixlogix Infotech
 

Recently uploaded (20)

Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
Alt. GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using ...
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Mind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AIMind map of terminologies used in context of Generative AI
Mind map of terminologies used in context of Generative AI
 
20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website20 Comprehensive Checklist of Designing and Developing a Website
20 Comprehensive Checklist of Designing and Developing a Website
 

The basics and design of lua table

  • 2. OUTLINE Basic of Lua "table" Adapt Lua "table" for multiple data structure Dive into Lua "table" source code
  • 4. OVERVIEWOFLUA Lua is a powerful, e cient, lightweight, embeddable scripting language. multi-paradigm: Lua supports procedural programming, object-oriented programming, functional programming, etc. dynamically-type: types are attached to values rather than to variables. Lua has automatic memory management with incremental garbage collection.
  • 5. OVERVIEWOFLUA basic types ( rst-class): 1. nil (like "None" in Python, including unde ned variables) 2. boolean: true, false 3. number: double-precision oating-point numbers (like "double" in C) 4. string: immutable (once internalized, cannot be changed) 5. table: associative arrays 6. function: Lua functions, C functions 7. heavy userdata 8. light userdata
  • 6. 9. thread: coroutines OVERVIEWOFTABLEINLUA Tables are the main — in fact, the only — data- structuring mechanism in Lua. Tables in Lua are associative arrays, that is, they can be indexed by any value (except nil) and can hold values of any type. Tables are dynamic in the sense that they may grow when data is added to them (by assigning a value to a hitherto non-existent eld) and shrink when data is removed from them (by assigning nil to a eld).
  • 8. TABLECREATION -- This is a comment. -- Empty table local t1 = {} -- Table as an array local t2 = { 1, 2, "str", t1 } -- Table as a hashtable local t3 = { ["k1"] = "v1", k2 = "v2", } -- Table as mixed data structure of array and hashtable local t4 = { "e1", -- stored in the array part ["k1"] = "v1", -- stored in the hash part
  • 9. TABLEASANARRAY Array Operations: Set the element of position "n" Get the element of position "n" Get the number of elements Iterate over all elements Delete the element of position "n"
  • 10. TABLEASANARRAY:SETTER Set the element of position "n" NOTE: index in Lua starts from 1 -- Way #1: specify the index local t = {} t[1] = "e1" t[2] = "e2" t[3] = "e3" t[4] = "e4" -- Way #2: use table.insert (list, [pos,] value) local t = {} table.insert(t, 1, "e1") table.insert(t, 2, "e2") -- table.insert(t, x) inserts x at the end of list t table.insert(t, "e3") table.insert(t, "e4") See the manual of table.insert
  • 11. TABLEASANARRAY:GETTER Get the element of position "n" local t = {"e1", "e2", "e3", "e4"} -- Get the fourth element print(t[4]) --[[ This is a multi-line comment. Output: e4 ]]
  • 12. TABLEASANARRAY:GETELEMENTNUMBER Get the number of elements local t = {"e1", "e2", "e3", "e4"} -- Way #1: the length operator "#" print(#t) --[[ Output: 4 ]] -- Way #2 --[[ table.unpack(t) returns "e1", "e2", "e3", "e4" so it becomes: print(select('#', "e1", "e2", "e3", "e4")) ]] print(select('#', table.unpack(t))) Refer to: manual of the length operator "#" manual of select manual of table.unpack
  • 13. TABLEASANARRAY:ITERATION Iterate over all elements local t = {"e1", "e2", "e3", "e4"} -- Forward iteration for i = 1, 4 do print(t[i]) end --[[ Output: e1 e2 e3 e4 ]] -- More general way: for i = 1, #t do print(t[i]) There's another way of using an iterator. We will talk about that later.
  • 14. TABLEASANARRAY:DELETE Delete the element of position "n" -- Way #1: set the specified element as nil local t = {"e1", "e2", "e3", "e4"} -- Delete the third element t[3] = nil --[[ NOTE: 1. Lua table will not pack the elements backward to fill the empty slot 2. the number of elements will not change ]] print("The number of elements:", #t) for i = 1, #t do print(t[i]) end --[[ Output:
  • 15. TABLEASANARRAY:DELETE Delete the element of position "n" -- Way #2: use table.remove (list [, pos]) local t = {"e1", "e2", "e3", "e4"} table.remove(t, 3) print("The number of elements:", #t) for i = 1, #t do print(t[i]) end --[[ Output: The number of elements: 3 e1 e2 e4 ]] -- table.remove(t) removes the last element of list t. See the manual of table.remove
  • 16. TABLEASANARRAY:DELETE Common misuse of table.remove in a loop local t = {1, 2, 3, 4} for i = 1, #t do if t[i] < 4 then table.remove(t, i) end end --[[ Opps... lua: xxx.lua:4: attempt to compare nil with number stack traceback: xxx.lua:4: in main chunk [C]: in ? ]] Why?
  • 17. TABLEASANARRAY:DELETE Trace the source code using print local t = {1, 2, 3, 4} for i = 1, #t do print(i, t[i]) if t[i] < 4 then table.remove(t, i) end end --[[ 1 1 2 3 3 nil lua: xxx.lua:5: attempt to compare nil with number stack traceback: xxx.lua:5: in main chunk [C]: in ? ]]
  • 18. TABLEASANARRAY:DELETE Straightforward solution: use backward iteration. local t = {1, 2, 3, 4} for i = #t, 1, -1 do if t[i] < 4 then table.remove(t, i) end end for i = 1, #t do print(t[i]) end --[[ Output: 4 ]] We will see another misuse case of table.remove when we discuss iterator ;)
  • 19. TABLEASAHASHTABLE Hashtable Operations: Set the value of key "k" Get the value of key "k" Delete the value of key "k" Iterate over all key-value pairs Get the number of key-value pairs
  • 20. TABLEASAHASHTABLE:SETTER local t = {} -- Way #1 t["key"] = "value" -- Way #2: syntactic sugar t.key = "value" -- Compare with the following code: local key = "key" t[key] = "value"
  • 21. TABLEASAHASHTABLE:GETTER local t = { "key" = "value", } print("t["key"] = ", t["key"]) print("t.key = ", t.key) local k = "key" print("t[k] = ", t[k]) -- t.k is equivalent to t["k"] print("t.k = ", t.k) --[[ Output: t["key"] = value t.key = value t[k] = value t.k = nil
  • 22. TABLEASAHASHTABLE:DELETE local t = { "key" = "value", } t.key = nil
  • 24. TABLEASAHASHTABLE:ITERATION Meet `next (table [, index])` Allows a program to traverse all elds of a table. Its rst argument is a table and its second argument is an index in this table. next returns the next index of the table and its associated value. When called with nil as its second argument, next returns an initial index and its associated value. When called with the last index, or with nil in an empty table, next returns nil. If the second argument is absent, then it is interpreted as nil. In particular, you can use next(t) to check whether a table is empty.
  • 25. TABLEASAHASHTABLE:ITERATION local t = { k1 = "v1", k2 = "v2", k3 = "v3", } local k, v -- Note: equivalent to: -- local k = nil -- local v = nil for i = 1, 3 do k, v = next(t, k) print(k, v) end -- NOTE: The order in which the indices are enumerated is not specified, even for --[[ Output: See the manual of next
  • 26. TABLEASAHASHTABLE:ITERATION What if we don't know there's three key-value pairs in the table `t`? local t = { k1 = "v1", k2 = "v2", k3 = "v3", } local k, v = next(t, k) while k do -- Note: equivalent to: -- while k ~= nil do print(k, v) k, v = next(t, k) end --[[ Output: k2 v2 k1 v1
  • 27. ITERATOR Advanced skill: meet the "generic for" in Lua. for {var-list} in {exp-list} do {body} end Now we can write an iterator and use it in the generic for loop!
  • 28. ITERATOR Hand-written iterator (V1): local t = { k1 = "v1", k2 = "v2", k3 = "v3", } local function iter(t) local last_k return function() local v last_k, v = next(t, last_k) return last_k, v end end -- Use the iterator in the generic for loop for k, v in iter(t) do print(k, v) It would be di cult to understand if you don't know anything about closure or lambda! :(
  • 29. ITERATOR Hand-written iterator (V2): we can pass a function and its parameters in {exp-list} of "generic for". local t = { k1 = "v1", k2 = "v2", k3 = "v3", } for k, v in next, t do print(k, v) end --[[ Output: k3 v3 k2 v2 k1 v1 ]] Simpler code :) It would still be di cult to understand if you don't know functions in Lua are rst-class variables! :(
  • 30. ITERATOR There's a built-in iterator: `pairs`! XD local t = { k1 = "v1", k2 = "v2", k3 = "v3", } for k, v in pairs(t) do print(k, v) end --[[ Output: k3 v3 k1 v1 k2 v2 ]] See the manual of pairs
  • 31. ITERATOR There's another built-in iterator for array: `ipairs`! XD local t = {"e1", "e2", "e3", "e4"} -- Only forward iteration for i, v in ipairs(t) do print(i, v) end --[[ Output: 1 e1 2 e2 3 e3 4 e4 ]] See the manual of ipairs
  • 32. Now we can talk about another common misuse of table.remove in loop. local t = {1, 2, 3, 4} for i, v in ipairs(t) do print("Access the element: ", v) if v < 4 then table.remove(t, i) end end print("Result:") for i, v in ipairs(t) do print(i, v) end --[[ Output: Access the element: 1 Access the element: 3
  • 33. TABLEASAHASHTABLE:GETTHENUMBEROFKEY-VALUEPAIRS local t = { k1 = "v1", k2 = "v2", k3 = "v3", } -- Try the length operator "#": print(#t) --[[ Output: 0 ]] Opps...The length operator "#" only deals with the array part of table. :(
  • 34. TABLEASAHASHTABLE:GETTHENUMBEROFKEY-VALUEPAIRS Since we know how to iterator over the table, we know how to count all the key-value pairs. :) local t = { k1 = "v1", k2 = "v2", k3 = "v3", } local cnt = 0 for i, v in pairs(t) do cnt = cnt + 1 end print(cnt) --[[ Output: 3 ]] Complexity: O(N)
  • 36. MATRICES/MULTI-DIMENSIONALARRAYS Like C array: -- Create a matrix of zeros with dimensions N by M -- Way #1 mt = {} -- create the matrix for i = 1, N do mt[i] = {} -- create a new row for j = 1, M do mt[i][j] = 0 end end -- Way #2 mt = {} -- create the matrix for i = 1, N do for j = 1, M do mt[i*M + j] = 0 end end
  • 37. LINKEDLISTS -- local node = {next = node, value = v} -- local list = first_node function traverse(list) local node = list while node do print(node.value) node = node.next end end -- We counting the nodes from 1 function insert_kth_node(list, k, node) assert(k > 0, "invalid k") -- Insert from front if k == 1 then node.next = list
  • 38. STACKS -- Use Stack as a namespace local Stack = {} function Stack.push(stack, element) table.insert(stack, element) end function Stack.pop(stack) table.remove(stack) end function Stack.top(stack) return stack[#stack] end return Stack
  • 39. QUEUESANDDOUBLEQUEUES local Queue = {} function Queue.new() return {first = 0, last = -1} end function Queue.pushleft(queue, value) local first = queue.first - 1 queue.first = first queue[first] = value end function Queue.pushright(queue, value) local last = queue.last + 1 queue.last = last queue[last] = value end
  • 40. SETS local Set = {} function Set.new() return {} end function Set.add(set, element) set[element] = true end function Set.has(set, element) return set[element] end -- Union of two sets function Set.union(set1, set2) local union = {} for _, set in ipairs({set1, set2}) do
  • 41. DIVEINTOLUASOURCECODE The version of Lua source code is 5.2 I omit and modify some code for simplicity. XD
  • 43. HOWDOLUASTORETABLE? De nition in lobject.h: typedef struct Table { lu_byte lsizenode; /* log2 of size of `node' array */ TValue *array; /* array part */ Node *node; Node *lastfree; /* any free position is before this position */ int sizearray; /* size of `array' array */ } Table;
  • 44. WHATDOES`TABLE`CONTAIN? A `Table` instance has at lease three continued areas in memory: The `Table` instance itself. `array`: array part of `Table` `node`: hash part of `Table`
  • 45. WHATDOES`TABLE`CONTAIN? Fields of recording the size: size of array part: `sizearray` size of hash part: 2^`lsizenode` #define twoto(x) (1<<(x)) #define sizenode(t) (twoto((t)->lsizenode))
  • 46. Macros related to `Table`: #define gnode(t,i) (&(t)->node[i]) We will meet this macro later. ;)
  • 47. WHATIS`NODE`? typedef struct Node { TValue i_val; TKey i_key; } Node; `Node` is the structure for key-value pair
  • 48. Macros related to `Node`: #define gval(n) (&(n)->i_val)
  • 49. WHATIS`TVALUE`THEN? typedef struct lua_TValue TValue; /* ** Tagged Values. This is the basic representation of values in Lua, ** an actual value plus a tag with its type. */ struct lua_TValue { Value value_; int tt_; }; `TValue` = Tagged Value `TValue` contains the value and a type tag Lua represents values as tagged unions, that is, as pairs (t, v), where t is an integer tag identifying the type of the value v, which is a union of C types implementing Lua types. omitted source code: NaN Trick
  • 50. Macros related to `TValue`: #define val_(o) ((o)->value_) /* raw type tag of a TValue */ #define rttype(o) ((o)->tt_) #define setobj(L,obj1,obj2) { const TValue *io2=(obj2); TValue *io1=(obj1); io1->value_ = io2->value_; io1->tt_ = io2->tt_; } We will meet these macros later. ;)
  • 51. HOWDOESTHETAGDISTINGUISHDIFFERENTTYPESOFLUA VALUE? lua.h /* ** basic types */ #define LUA_TNONE (-1) #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUMBER 3 #define LUA_TSTRING 4 #define LUA_TTABLE 5 #define LUA_TFUNCTION 6 #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 #define LUA_NUMTAGS 9
  • 52. HOWDOESTHETAGDISTINGUISHDIFFERENTTYPESOFLUA VALUE? /* raw type tag of a TValue */ #define rttype(o) ((o)->tt_) /* Macros to test type */ #define checktag(o,t) (rttype(o) == (t)) #define ttistable(o) checktag((o), LUA_TTABLE) #define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) Again, we will meet these macros later. ;)
  • 53. WHATIS`VALUE`? union Value { GCObject *gc; /* collectable objects */ void *p; /* light userdata */ int b; /* booleans */ lua_CFunction f; /* light C functions */ lua_Number n; /* numbers */ }; `Value` can be: `nil`? No! Tag of `TValue` is enough. #define settt_(o,t) ((o)->tt_=(t)) #define setnilvalue(obj) settt_(obj, LUA_TNIL) #define ttisnil(o) checktag((o), LUA_TNIL)
  • 54. WHATIS`VALUE`? union Value { GCObject *gc; /* collectable objects */ void *p; /* light userdata */ int b; /* booleans */ lua_CFunction f; /* light C functions */ lua_Number n; /* numbers */ }; `Value` can be: boolean? Yes! `Value` = `b` number? Yes! `Value` = `n` light userdata? Yes! `Value` = `p` light C functions? Yes! `Value` = `f` #define val_(o) ((o)->value_) #define num_(o) (val_(o).n) #define nvalue(o) check_exp(ttisnumber(o), num_(o)) #define setnvalue(obj,x) { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
  • 55. WHATIS`VALUE`? union Value { GCObject *gc; /* collectable objects */ void *p; /* light userdata */ int b; /* booleans */ lua_CFunction f; /* light C functions */ lua_Number n; /* numbers */ }; `Value` can be: string, table, other function, heavy userdata, thread? `Value` = `gc` #define sethvalue(L,obj,x) { TValue *io=(obj); val_(io).gc=cast(GCObject *, (x)); settt_(io, LUA_TTABLE); }
  • 56. WHATIS`GCOBJECT`THEN? lstate.h /* ** Union of all collectable objects */ typedef union GCObject GCObject; union GCObject { GCheader gch; /* common header */ union TString ts; union Udata u; union Closure cl; struct Table h; struct Proto p; struct UpVal uv; struct lua_State th; /* thread */ };
  • 58. WHATIS`TKEY`? typedef union TKey { struct { Value value_; int tt_; struct Node *next; /* for chaining */ } nk; TValue tvk; } TKey;
  • 59. Macros related to `TKey`: #define gkey(n) (&(n)->i_key.tvk) #define gnext(n) ((n)->i_key.nk.next)
  • 62. GENERALPROCEDUREOFLUAPROGRAM: Lua programs are not interpreted directly from the textual Lua le, but are compiled into bytecode, which is then run on the Lua virtual machine.
  • 63. GENERALPROCEDUREOFLUAPROGRAM: Here we care about the execution phrase, and we will start our analysis from function `luaV_execute`.
  • 64. BRIEFINTRODUCTIONOFLUAVMANDITSINSTRUCTIONS xed size (32 bit unsigned integer) register-based instruction formats (`sBx' : signed Bx): We will meet the following guys later: R(A) : Register A RK(B) : Register B or a constant index
  • 65. STARTFROMTHENAIVEEXAMPLE local t = {} 0+ params, 2 slots, 1 upvalue, 1 local, 0 constants, 0 functions 1 [1] NEWTABLE 0 0 0 2 [1] RETURN 0 1 Instructions related to table creation: 1 [1] NEWTABLE 0 0 0
  • 66. NEWTABLEINSTRUCTION NEWTABLE A B C R(A) := {} (size = B,C) Creates a new empty table at register R(A). B: encoded size information for the array part of the table. C: encoded size information for the hash part of the table.
  • 67. EXECUTENEWTABLEINLUAVM void luaV_execute (lua_State *L) { CallInfo *ci = L->ci; LClosure *cl; TValue *k; StkId base; newframe: /* reentry point when frame changes (call/return) */ lua_assert(ci == L->ci); cl = clLvalue(ci->func); k = cl->p->k; base = ci->u.l.base; /* main loop of interpreter */ for (;;) { Instruction i = *(ci->u.l.savedpc++); StkId ra; if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { Protect(traceexec(L)); } A bit confused?
  • 68. EXECUTENEWTABLEINLUAVM We only need to trace the following part of code for the naive example. ;) vmcase(OP_NEWTABLE, // Get the operator B from the instruction int b = GETARG_B(i); // Get the operator C from the instruction int c = GETARG_C(i); Table *t = luaH_new(L); // Remember this macro: `sethvalue` ? ;) sethvalue(L, ra, t); ) Now we only need to look at `luaH_new`. :)
  • 69. EXECUTENEWTABLEINLUAVM Table *luaH_new (lua_State *L) { Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; t->array = NULL; t->sizearray = 0; setnodevector(L, t, 0); return t; } static void setnodevector (lua_State *L, Table *t, int size) { int lsize; if (size == 0) { /* no elements to hash part? */ t->node = cast(Node *, dummynode); /* use common `dummynode' */ lsize = 0; } else { int i; lsize = luaO_ceillog2(size); if (lsize > MAXBITS) Confused by `setnodevector`?
  • 70. IT'SSIMPLERINOURCASE... Table *luaH_new (lua_State *L) { Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; t->array = NULL; t->sizearray = 0; t->node = cast(Node *, dummynode); /* use common `dummynode' */ t->lsizenode = 0; t->lastfree = gnode(t, 0); /* all positions are free */ return t; }
  • 71. WHAT'S`DUMMYNODE`? /* macro defining a nil value */ #define NILCONSTANT {NULL}, LUA_TNIL #define dummynode (&dummynode_) #define isdummy(n) ((n) == dummynode) static const Node dummynode_ = { {NILCONSTANT}, /* value */ {{NILCONSTANT, NULL}} /* key */ }; All empty table in Lua points to the same memory area. CLEVER Lua!
  • 74. ANOTHERNAIVEEXAMPLE: local t = {} return t[1] 0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 0 functions 1 [1] NEWTABLE 0 0 0 2 [2] GETTABLE 1 0 -1 ; 1 3 [2] RETURN 1 2 4 [2] RETURN 0 1 Instructions related to accessing table: 2 [2] GETTABLE 1 0 -1 ; 1
  • 75. GETTABLEINSTRUCTION GETTABLE A B C R(A) := R(B)[RK(C)] Copies the value from a table element into register R(A). The table is referenced by register R(B). The index to the table is given by RK(C), which may be the value of register R(C) or a constant number.
  • 76. EXECUTEGETTABLEINLUAVM Look at the for loop in `luaV_execute` (lvm.c): vmcase(OP_GETTABLE, Protect(luaV_gettable(L, RB(i), RKC(i), ra)); ) Now we need to look at `luaV_gettable`. :)
  • 77. EXECUTEGETTABLEINLUAVM void luaV_gettable (lua_State *L, const TValue *t, TValue *key, TValue *val) // Remember this macro: `ttistable` ? ;) if (ttistable(t)) { /* `t' is a table? */ // Remember this macro: `hvalue` ? ;) Table *h = hvalue(t); const TValue *res = luaH_get(h, key); /* do a primitive get */ // Remember this macro: `ttisnil` ? ;) if (!ttisnil(res)) { /* result is not nil? */ // Remember this macro: `setobj` ? ;) setobj(L, val, res); } } return; } Now only the function `luaH_get` causes our headaches.
  • 78. DIVEINTO`LUAH_GET` /* ** main search function */ const TValue *luaH_get (Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); case LUA_TNIL: return luaO_nilobject; case LUA_TNUMBER: { int k; lua_Number n = nvalue(key); lua_number2int(k, n); if (luai_numeq(cast_num(k), n)) /* index is int? */ return luaH_getint(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */
  • 79. IT'SSIMPLERINOURCASE... const TValue *luaH_get (Table *t, const TValue *key) { int k; // Remember this macro: `nvalue` ? ;) lua_Number n = nvalue(key); lua_number2int(k, n); if (luai_numeq(cast_num(k), n)) /* index is int? */ return luaH_getint(t, k); /* use specialized version */ } What's the so-called specialized function `luaH_getint`?
  • 80. DIVEINTO`LUAH_GET` /* ** search function for integers */ const TValue *luaH_getint (Table *t, int key) { /* (1 <= key && key <= t->sizearray) */ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) return &t->array[key-1]; else { lua_Number nk = cast_num(key); Node *n = hashnum(t, nk); do { /* check whether `key' is somewhere in the chain */ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return luaO_nilobject; } } If the int key is smaller than the size of array, access the array part. Otherwises, compute the hash value of the key, and access the hash part.
  • 81. WHATDOESTHISLOOPDO? do { /* check whether `key' is somewhere in the chain */ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return luaO_nilobject;
  • 82. DIVEINTO`LUAH_GET` Lua table uses open addressing to resolve hash collision:
  • 83. DIVEINTO`LUAH_GET` Lua de nes the index of the hash part of table as "mainposition". The rest part of `luaH_get` is similar to `luaH_getint`. XD
  • 85. ALWAYSNAIVEEXAMPLE:) local t = {} t[1] = 3 0+ params, 2 slots, 1 upvalue, 1 local, 2 constants, 0 functions 1 [1] NEWTABLE 0 0 0 2 [2] SETTABLE 0 -1 -2 ; 1 3 3 [2] RETURN 0 1 Instructions related to accessing table: 2 [2] SETTABLE 0 -1 -2 ; 1 3
  • 86. SETTABLEINSTRUCTION SETTABLE A B C R(A)[RK(B)] := RK(C) Copies the value from register R(C) or a constant into a table element. The table is referenced by register R(A). The index to the table is given by RK(B), which may be the value of register R(B) or a constant number.
  • 87. EXECUTESETTABLEINLUAVM Look at the for loop in `luaV_execute` (lvm.c): vmcase(OP_SETTABLE, Protect(luaV_settable(L, ra, RKB(i), RKC(i))); ) It looks like the case of `GETTABLE`. XD
  • 88. EXECUTESETTABLEINLUAVM Now look at function `luaV_settable`: void luaV_settable (lua_State *L, const TValue *t, TValue *key, TValue *val) if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); // Remember `luaH_get`? TValue *oldval = cast(TValue *, luaH_get(h, key)); /* is there a previous entry in the table? */ if (!ttisnil(oldval) || /* no previous entry; must create one. (The next test is * always true; we only need the assignment.) */ (oldval = luaH_newkey(L, h, key), 1)) { /* (now) there is an entry with given key */ setobj(L, oldval, val); /* assign new value to that entry */ } } return; } C trick of comma operator: (a, b, c) is a sequence of expressions, separated by commas, which evaluates to the last expression c.
  • 89. WHATDOESLUAV_SETTABLEDO? 1. Get the old value of the key. 2. If The old value is nil: create a new key by `luaH_newkey` and write the corresponding value. Otherwises, rewrite the value.
  • 90. WHATDOESLUAH_NEWKEYDO? /* ** inserts a new key into a hash table; first, check whether key's main ** position is free. If not, check whether colliding node is in its main ** position or not: if it is not, move colliding node to an empty place and ** put new key in its main position; otherwise (colliding node is in its main ** position), new key goes to an empty position. */ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *mp; if (ttisnil(key)) luaG_runerror(L, "table index is nil"); else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) luaG_runerror(L, "table index is NaN"); mp = mainposition(t, key); if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ if (n == NULL) { /* cannot find a free place? */ rehash(L, t, key); /* grow table */ Don't be scared, we will take it apart. ;D
  • 91. THELUCKIESTCASE There's free space. The main position has not been occupied. XD TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *mp; mp = mainposition(t, key); setobj(L, gkey(mp), key); return gval(mp); }
  • 92. CASE2 There's free space. The main position has been occupied, and that bad guy is occupying its main position. :| TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *mp; mp = mainposition(t, key); if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ lua_assert(!isdummy(n)); /* colliding node is in its own main position */ /* new node will go into free position */ gnext(n) = gnext(mp); /* chain new position */ gnext(mp) = n; mp = n; } setobj(L, gkey(mp), key); return gval(mp); }
  • 93. CASE3 There's free space. The main position has been occupied, and that bad guy is not occupying its main position. :( TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { Node *mp; mp = mainposition(t, key); if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ lua_assert(!isdummy(n)); othern = mainposition(t, gkey(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ gnext(mp) = NULL; /* now `mp' is free */ setnilvalue(gval(mp)); } } setobj(L, gkey(mp), key);
  • 94. CASE4 There's no free space. :( It will cause rehashing. The array part may grow or shrink so that at lease half of the array is occupied. If the array part shrinks, its rest elements will be inserted into the hash part. The hash part may grow or shrink, too. Its size is determined by the number of valid key-value pair, whose value is not nil, and the number of elements from the shrinked array part. Moreover, the size is guaranteed to be power of two. (Remember the `lsizenode` eld of `Table`?) I will not show the source code of rehashing in order not to scare you. XD
  • 95. BACKTOTHETOPICOFCREATINGANON- EMPTYTABLEXD What's the di erence between the following code snippets? local t = {"e1", "e2", "e3", "e4", "e5"} local t = {} t[1] = "e1" t[2] = "e2" t[3] = "e3" t[4] = "e4" t[5] = "e5"
  • 96. COUNTINGTHEOCCURRENCESOF REHASHING: Zero rehash, resize the array part once at table creation. :) local t = {"e1", "e2", "e3", "e4", "e5"} Rehash four times at SETTABLE. :( local t = {} t[1] = "e1" -- rehash t[2] = "e2" -- rehash t[3] = "e3" -- rehash t[4] = "e4" t[5] = "e5" -- rehash The rehashing overhead can be much higher if there's lots of small table in your Lua program.
  • 97. LESSONLEARNED Prefer this way to avoid initial rehashings of table. local t = {"e1", "e2", "e3", "e4", "e5"}
  • 98. MOREABOUTTABLEINLUA metatable, metamethod OO in Lua Weak table Special table: `{}` (we have meet it), `_ENV`, `_G`, etc. How does luajit accelerate table operations? ...
  • 99. REFERENCES "The Implementation of Lua 5.0" by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes "Programming in Lua" by the leading architect of Lua, Roberto Ierusalimschy: "A No-Frills Introduction to Lua 5.1 VM Instructions" by Kein-Hong Man "Lua Performance Tips" by Roberto Ierusalimschy Lua o cial website First version is free online (Lua 5.0)