Lua.VM.Table (Lua v1.0.0-rc.2)
View SourceLua table data structure with split array/hash storage.
Dense positive-integer keys (1..n) live in an Erlang :array (the
arr field), giving O(1) functional read/write and a free sequence
length. Every other key — strings, non-positive integers, sparse
integers beyond the contiguous array border, float/boolean/table keys —
lives in the data hash map alongside the iteration-order bookkeeping.
Keeping string keys in data means the executor's field/global fast
paths (%{^name => value}) and metatable lookups read the hash map
directly with no change. Integer-keyed reads/writes route through the
split-aware helpers in this module.
Array border
arr_n is the count of contiguous integer keys 1..arr_n currently
stored in arr. Writing key arr_n + 1 extends the border; clearing a
key inside the border splits it (the tail beyond the hole migrates to
data lazily on read). A write to a sparse integer key beyond the
border goes to data until a later contiguous fill promotes it.
Dead-key tracking
Lua 5.3 §6.1 dead-key iteration semantics are preserved for the hash
portion via order/order_tail/dead exactly as before. Array-portion
keys iterate first, in index order, then hash keys in insertion order.
Summary
Functions
Flushes any pending order_tail appends into order. Idempotent.
Builds a table struct from a plain data map.
Reads a value from a table by key, split-aware (array then hash).
Reads a value from a bare hash data map, applying key normalization.
Returns true when the bare hash data map has an entry for key.
Returns true when the table (array or hash) has a live entry for key.
Returns true if a key is invalid for use in a table assignment.
Returns the Lua sequence length: the largest n with keys 1..n present.
Returns the next key/value pair in iteration order after key.
Normalizes a table key per Lua 5.3 §3.4.11.
Writes value into the table under key, honoring Lua semantics
Writes value into a raw data map under key (hash-only, no array).
Applies an ordered list of {key, value} writes, equivalent to folding
put/3 left-to-right but rebuilding the struct once.
Replaces the table contents wholesale from a plain data map, rebuilding
the array/hash split and clearing dead.
Materializes the full table contents (array + hash) as a single flat map.
Types
@type t() :: %Lua.VM.Table{ arr: :array.array() | :undefined, arr_n: non_neg_integer(), data: %{optional(term()) => term()}, dead: %{optional(term()) => true}, metatable: {:tref, non_neg_integer()} | nil, order: [term()], order_tail: [term()] }
Functions
Flushes any pending order_tail appends into order. Idempotent.
Builds a table struct from a plain data map.
Splits dense positive-integer keys into the array and leaves the rest in
data, so callers that pass a literal map (stdlib init, table.pack,
encode) get split storage with no extra effort.
Reads a value from a table by key, split-aware (array then hash).
This is the struct-level read. Prefer it over the bare-map get_data/2
for any code that has the full %Table{}.
Reads a value from a bare hash data map, applying key normalization.
Hash-only: does not consult the array. Callers with a full struct should
use get/2.
Returns true when the bare hash data map has an entry for key.
Returns true when the table (array or hash) has a live entry for key.
Returns true if a key is invalid for use in a table assignment.
@spec length(t()) :: non_neg_integer()
Returns the Lua sequence length: the largest n with keys 1..n present.
The contiguous array border gives this for free; we only fall back to probing the hash for sparse integers parked beyond the border.
Returns the next key/value pair in iteration order after key.
Array keys (1..arr_n) iterate first in index order, then hash keys in
insertion order. Mirrors the old next_entry/2 contract: returns {k, v},
nil at the end, or :invalid_key when key is absent everywhere.
Normalizes a table key per Lua 5.3 §3.4.11.
Writes value into the table under key, honoring Lua semantics:
- Assigning
nilremoves the key. - Dense positive integers route to the array; other keys to the hash.
Writes value into a raw data map under key (hash-only, no array).
Retained for callers that operate on a bare hash map with no surrounding struct. Integer keys still land in the map here.
Applies an ordered list of {key, value} writes, equivalent to folding
put/3 left-to-right but rebuilding the struct once.
Replaces the table contents wholesale from a plain data map, rebuilding
the array/hash split and clearing dead.
Materializes the full table contents (array + hash) as a single flat map.
Used by code paths that genuinely need the whole table as a map (decode,
display, string.gsub replacement lookups). Walks the array once.