Temp Table

There are ocasionally cases where a lot of tables need to be created for use within a tight loop and relying on Lua’s GC to clean them up afterwards can result in a noticeable performance hit. For these situations, the TempTable module provides a set of APIs for manually managing the lifecycle of Lua tables. Some common use-cases are below.

Example

One common use-case for a temp table is for an API which returns a set of values which it needs to build in an iterative fasion.

local MyModule = select(2, ...).MyModule
local TempTable = MyModule:From("LibTSMUtil"):Include("BaseType.TempTable")

function PrintLettersSortedSingleLine(str)
   local letters = TempTable.Acquire()
   for i = 1, #str do
      local c = strsub(str, i, i)
      if not letters[c] then
         letters[c] = true
         tinsert(letters, c)
      end
   end
   sort(letters)
   print(TempTable.UnpackAndRelease(letters))
end

function PrintLettersSortedMultipleLines(str)
   local letters = TempTable.Acquire()
   for i = 1, #str do
      local c = strsub(str, i, i)
      if not letters[c] then
         letters[c] = true
         tinsert(letters, c)
      end
   end
   sort(letters)
   for _, letter in TempTable.Iterator(letters) do
      print(letter)
   end
end

API

class BaseType.TempTable: LibTSMModule
staticmethod Acquire(...: any): table

Acquires a temporary table.

Temporary tables are recycled tables which can be used instead of creating a new table every time one is needed for a defined lifecycle. This avoids relying on the garbage collector and improves overall performance.

Parameters:

... (any) – Any number of values to insert into the table initially

staticmethod AcquireWithOwner(owner: table, ...: any): table

Acquires a temporary table and takes ownership.

Parameters:
  • owner (table) – The owner

  • ... (any) – Any number of values to insert into the table initially

staticmethod Iterator(tbl: table, numFields?: number): fun(): number, ...unknown, table, number

Iterators over a temporary table, releasing it when done.

NOTE: This iterator must be run to completion and not be interrupted (i.e. with a break or return).

Parameters:
  • tbl (table) – The temporary table to iterator over

  • numFields? (number) – The number of fields to unpack with each iteration (defaults to 1)

Returns:

_1 (fun(): number, ...unknown) – Iterator with fields: index, {numFields…}

staticmethod KeyIterator(tbl: table): fun(): number, ...unknown, table

Iterators over the keys of a temporary table, releasing it when done.

NOTE: This iterator must be run to completion and not be interrupted (i.e. with a break or return).

Parameters:

tbl (table) – The temporary table to iterator over

Returns:

_1 (fun(): number, ...unknown) – Iterator with fields: key

staticmethod Release(tbl: table)

Releases a temporary table.

The temporary table will be returned to the pool and must not be accessed after being released.

Parameters:

tbl (table) – The temporary table to release

staticmethod UnpackAndRelease(tbl: <T>[]): (...: <T>)

Releases the temporary table and returns its unpacked values.

Parameters:

tbl (<T>[]) – The temporary table to release and unpack

staticmethod ConcatAndRelease(
    tbl: string[],
    sep: string,
    startIndex?: number,
    endIndex?: number
): string

Concatenates the temporary table and releases it.

Parameters:
  • tbl (string[]) – The temporary table

  • sep (string) – The separator

  • startIndex? (number) – The first index to concat

  • endIndex? (number) – The last index to concat

staticmethod TakeOwnership(tbl: table, owner: table)

Assigns ownership of a temp table.

Parameters:
  • tbl (table) – The temp table

  • owner (table) – The owner

staticmethod ReleaseAllOwned(owner: table)

Releases all owned temp tables.

Parameters:

owner (table) – The owner

staticmethod EnableLeakDebug()

Enables tracking of where temp tables are created from in order to debug leaks.

staticmethod GetDebugInfo(): string[]

Gets debug information describing allocated and free temp tables.