nupp.mem.arena

A paged allocator of struct rows whose pages never move.

Rows are handed out in order from fixed-size pages of one struct type. A page is allocated once and stays where it is, so a row reference is good for as long as the arena is; growth adds a page beside the others rather than moving anything. A reset rewinds to the first row of the first page and keeps every page, which is what makes the next epoch allocation-free.

local arena = nupp.mem.arena

local struct Impact
    x: float
    y: float
end

local impacts = arena.newArena(Impact, 256)
local impact = impacts:acquire() -- zero-filled
impact.x = 1.5
impacts:release(impact)
impacts:reset() -- rewinds; the page stays

Every acquired row reads as zero, whether it is fresh or one a reset made available again. A release ends that row's lease and nothing more: the cursor does not rewind until reset, and reset refuses while any lease is live, so a row that is out is never handed out twice. Releasing a row that is not live in this arena raises without changing its lease count.

Storage comes from the cstorage capability, so the module is available on native LuaJIT and on the Wasm and browser backends, and refused by portable. Table-backed record instances are nupp.util.Pool.

Module contents

Types

TypeKindDescription
ArenarecordA paged allocator of rows of a struct type.

Functions

FunctionKindDescription
newArenafunctionCreates an arena of witness rows with a page of pageSize rows already allocated.

Types#

Arenarecord#

record arena.Arena<S> ...

A paged allocator of rows of a struct type.

Type parameters

NameDescription
S

Members

NameKindDescription
elementfield
widthfield
pageSizefieldHow many rows each page holds.
pageListfield
rowsfield
pageIndexfield
cursorfield
usedCountfield
liveCountfield
leasesfield
acquiremethodHands out the next row, zero-filled.
releasemethodEnds a lease without rewinding the cursor.
resetmethodRewinds every used page's cursor and keeps the pages.
pagesmethodHow many pages the arena holds.
usedmethodHow many rows were handed out since the last reset.
livemethodHow many rows are acquired and not yet released.

elementfield#

element: any
@private@readonly

widthfield#

width: integer
@private@readonly

pageSizefield#

pageSize: integer
@readonly

How many rows each page holds.

pageListfield#

pageList: {S[?]}
@private

rowsfield#

rows: {{S}}
@private

pageIndexfield#

pageIndex: integer
@private

cursorfield#

cursor: integer
@private

usedCountfield#

usedCount: integer
@private

liveCountfield#

liveCount: integer
@private

leasesfield#

leases: table
@private

acquiremethod#

acquire: function(exclusive self: Arena<S>): S

Hands out the next row, zero-filled.

Arguments
NameTypeDescription
exclusive selfArena<S>
Returns
TypeDescription
S

releasemethod#

release: function(exclusive self: Arena<S>, row: S): nil

Ends a lease without rewinding the cursor.

Arguments
NameTypeDescription
exclusive selfArena<S>
rowS
Returns
TypeDescription
nil
Raises
TypeCondition
string

when row is not live in this arena

resetmethod#

reset: function(exclusive self: Arena<S>): nil

Rewinds every used page's cursor and keeps the pages.

Arguments
NameTypeDescription
exclusive selfArena<S>
Returns
TypeDescription
nil
Raises
TypeCondition
string

when any lease is live

pagesmethod#

pages: function(self: Arena<S>): integer

How many pages the arena holds.

Arguments
NameTypeDescription
selfArena<S>
Returns
TypeDescription
integer

usedmethod#

used: function(self: Arena<S>): integer

How many rows were handed out since the last reset.

Arguments
NameTypeDescription
selfArena<S>
Returns
TypeDescription
integer

livemethod#

live: function(self: Arena<S>): integer

How many rows are acquired and not yet released.

Arguments
NameTypeDescription
selfArena<S>
Returns
TypeDescription
integer

Functions#

arena.newArenafunction#

function arena.newArena<S>(witness: Type<S>, pageSize: integer?): arena.Arena<S>

Creates an arena of witness rows with a page of pageSize rows already allocated.

local struct Cell
    value: int32
end

local cells = arena.newArena(Cell, 16)
assert(cells:pages() == 1 and cells:used() == 0)

Type parameters

NameDescription
S

Arguments

NameTypeDescription
witnessType<S>

the struct declaration every row is laid out as

pageSizeinteger?

rows per page, 256 when omitted

Returns

TypeDescription
arena.Arena<S>

the arena, holding its first page

Raises

TypeCondition
string

when pageSize is not a positive integer