Skip to content

Data Structures

Joachim Stolberg edited this page Jan 15, 2019 · 20 revisions

It is not possible to easily control the memory usage of a Lua table at runtime. Therefore, Lua tables can't be used for SaferLua Controller programs. Because of this, there are the following alternatives, which are secure shells over the Lua table type:

Arrays

Arrays are lists of elements, which can be addressed by means of an index. An index must be an integer number. The first element in an array has the index value 1. Arrays have the following methods:

  • add(value) - add a new element at the end of the array
  • set(idx, value) - overwrite an existing array element on index idx
  • get(idx) - return the value of the array element on index idx
  • remove(idx) - remove the array element on index idx
  • insert(idx, val) - insert a new element at index idx (the array becomes one element longer)
  • size() - return the number of array elements
  • memsize() - return the needed array memory space
  • next() - for loop iterator function, returning idx,val
  • sort(reverse) - sort the array elements in place. If reverse is true, sort in descending order.

Example:

a = Array(1,2,3,4)     --> {1,2,3,4}
a.add(6)               --> {1,2,3,4,6}
a.set(2, 8)            --> {1,8,3,4,6}
a.get(2)               --> function returns 8
a.insert(5,7)          --> {1,8,3,4,7,6}
a.remove(3)            --> {1,8,4,7,6}
a.insert(1, "hello")   --> {"hello",1,8,4,7,6}
a.size()               --> function returns 6
a.memsize()            --> function returns 10
for idx,val in a.next() do
    ...
end

Stores

Unlike arrays, which are indexed by a range of numbers, stores are indexed by keys, which can be a string or a number. The main operations on a store are storing a value with some key and extracting the value given the key. The store has the following methods:

  • set(key, val) - store/overwrite the value val behind the keyword key
  • get(key) - read the value behind key
  • del(key) - delete a value
  • size() - return the number of store elements
  • memsize() - return the needed store memory space
  • next() - for loop iterator function, returning key,val
  • keys(order) - return an array with the keys. If order is "up" or "down", return the keys as sorted array, in order of the store values.

Example:

s = Store("a", 4, "b", 5)  --> {a = 4, b = 5}
s.set("val", 12)           --> {a = 4, b = 5, val = 12}
s.get("val")               --> returns 12
s.set(0, "hello")          --> {a = 4, b = 5, val = 12, [0] = "hello"}
s.del("val")               --> {a = 4, b = 5, [0] = "hello"}
s.size()                   --> function returns 3
s.memsize()                --> function returns 9
for key,val in s.next() do
    ...
end

Keys sort example:

s = Store()            --> {}
s.set("Joe", 800)      --> {Joe=800}
s.set("Susi", 1000)    --> {Joe=800, Susi=1000}
s.set("Tom", 60)       --> {Joe=800, Susi=1000, Tom=60}
s.keys()               --> {Joe, Susi, Tom}
s.keys("down")         --> {Susi, Joe, Tom}
s.keys("up")           --> {Tom, Joe, Susi}

Sets

A set is an unordered collection with no duplicate elements. The basic use of a set is to test if an element is in the set, e.g. if a player name is stored in the set. The set has the following methods:

  • add(val) - add a value to the set
  • del(val) - delete a value from the set
  • has(val) - test if value is stored in the set
  • size() - return the number of set elements
  • memsize() - return the needed set memory space
  • next() - for loop iterator function, returning idx,val

Example:

s = Set("Tom", "Lucy")     --> {Tom = true, Lucy = true}
s.add("Susi")              --> {Tom = true, Lucy = true, Susi = true}
s.del("Tom")               --> {Lucy = true, Susi = true}
s.has("Susi")              --> function returns `true`
s.has("Mike")              --> function returns `false`
s.size()                   --> function returns 2
s.memsize()                --> function returns 8
for idx,val in s.next() do
    ...
end

All three types of data structures allow nested elements, e.g. you can store a set in a store or an array and so on. But note that the overall size over all data structures can't exceed the predefined limit. This value is configurable for the server admin. The default value is 1000. The configured limit can be determined via memsize():

memsize()  --> function returns 1000  (example)