Question

In section 4, Tables, in The Implementation of Lua 5.0 there is and example:
local t = {100, 200, 300, x = 9.3}

So we have t[4] == nil. If I write t[0] = 0, this will go to hash part.
If I write t[5] = 500 where it will go? Array part or hash part?
I would eager to hear answer for Lua 5.1, Lua 5.2 and LuaJIT 2 implementation if there is difference.

Was it helpful?

Solution

Contiguous integer keys starting from 1 always go in the array part.

Keys that are not positive integers always go in the hash part.

Other than that, it is unspecified, so you cannot predict where t[5] will be stored according to the spec (and it may or may not move between the two, for example if you create then delete t[4].)

LuaJIT 2 is slightly different - it will also store t[0] in the array part.

If you need it to be predictable (which is probably a design smell), stick to pure-array tables (contiguous integer keys starting from 1 - if you want to leave gap use a value of false instead of nil) or pure hash tables (avoid non-negative integer keys.)

OTHER TIPS

Quoting from Implementation of Lua 5.0

The array part tries to store the values corresponding to integer keys from 1 to some limit n.Values corresponding to non-integer keys or to integer keys outside the array range are stored in the hash part.

The index of the array part starts from 1, that's why t[0] = 0 will go to hash part.

The computed size of the array part is the largest nsuch that at least half the slots between 1 and n are in use (to avoid wasting space with sparse arrays) and there is at least one used slot between n/2+1 and n(to avoid a size n when n/2 would do).

According from this rule, in the example table:

local t = {100, 200, 300, x = 9.3}

The array part which holds 3 elements, may have a size of 3, 4 or 5. (EDIT: the size should be 4, see @dualed's comment.)

Assume that the array has a size of 4, when writing t[5] = 500, the array part can no longer hold the element t[5], what if the array part resize to 8? With a size of 8, the array part holds 4 elements, which is equal to (so, not less that) half of the array size. And the index from between n/2+1 and n, which in this case, is 5 to 8, has one element:t[5]. So an array size of 8 can accomplish the requirement. In this case, t[5] will go to the array part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top