⌂ Modules nupp nupp.mem nupp.mem.soa nupp.mem.soa
Structure-of-arrays storage for reified structs.
Every top-level field of a reified struct gets its own contiguous column, so a loop that walks one field of many rows brings nothing else along.
local soa = nupp . mem . soa
local struct Position
x : float
velocity : float
end
local positions = soa . allocate ( ffi . typeof < Position > ( ) , 128 )
with rows = positions : write ( ) do
for index = 1 , # rows do
rows [ index ] . x += rows [ index ] . velocity
end
end
The compiler supplies the private layout argument to allocate and layoutof, and lowers indexed row fields directly to the typed columns kept by these views. This module owns allocation, checked whole-row operations, slicing, and field-span construction; it never exposes the slab or its column pointers in the public types.
See Structure-of-arrays storage for when this layout is the one to reach for, and NEP 10: Structure-of-arrays storage for why the container rather than the declaration chooses it.
Module contents Types Type Kind Description Arrayrecord One owned native slab whose top-level struct fields occupy separate segments. ArrayTokeninterface FieldLayoutrecord One stored top-level field in a SoA descriptor. InstanceLayoutrecord The count-dependent layout of one complete SoA slab. Layoutrecord Immutable reflection for a reified struct's SoA representation. SegmentLayoutrecord One field segment for a particular element count. Spaninterface A shared checked view over SoA rows. Writabletype An affine exclusive row view, released at its lexical boundary. WriteSpaninterface An affine exclusive checked view over SoA rows. WriteTokeninterface
Functions Function Kind Description allocatefunction Allocates one SoA slab for a reified struct type. destroyArrayfunction Frees a slab, which is what every SoA array's contract names. destroyWriteSpanfunction Ends a row writer, which is what every writable row view's contract names. layoutoffunction Answers immutable SoA reflection for a reified struct type without allocating.
Types
Arrayrecord
One owned native slab whose top-level struct fields occupy separate segments.
Type parameters
Methods
read
read : function ( borrows self : Array < T > ) : soa . Span < T > borrows ( self )
Borrows the rows as a shared checked view.
The borrow lasts as long as the view does, so a writer cannot be taken out while one is live.
Arguments Name Type Description borrows selfArray < T >
Returns Type Description soa . Span < T > borrows ( self )
write
Borrows the rows as an exclusive checked view.
Exclusive for as long as the writer is live, and affine, so a scope boundary or an explicit drop is what ends it.
Arguments Name Type Description exclusive selfArray < T >
Returns
close
close : nosuspend function ( takes self : Array < T > ) : nil
Frees the slab. drop and scope exit both reach this.
Arguments Name Type Description takes selfArray < T >
Returns
drop
drop : nosuspend function ( takes self : Array < T > ) : nil
Arguments Name Type Description takes selfArray < T >
Returns
Fields
count
How many rows the slab holds.
fingerprint
The layout fingerprint the slab was allocated under.
ArrayTokeninterface
Methods
FieldLayoutrecord
One stored top-level field in a SoA descriptor.
Fields
name
The field's name, as the struct declared it.
identity
The struct name and the field name joined, which is what a fingerprint entry is filed under.
ctype
The C type of one element of this column.
ordinal
Where this field sits in the declaration, counted from one.
elementSize
Bytes per element.
alignment
The alignment the column starts on.
InstanceLayoutrecord
The count-dependent layout of one complete SoA slab.
Fields
count
The row count this layout was computed for.
byteSize
The slab's size in bytes, before alignment padding.
segments
One segment per field, in declaration order.
Layoutrecord
Immutable reflection for a reified struct's SoA representation.
Methods
forCount
Computes checked segment offsets for count rows without allocating storage.
Arguments Name Type Description selfany countinteger
Returns
Raises
Fields
fingerprint
Every field's identity, type, size and alignment in one string, so two layouts can be compared without walking them.
alignment
The alignment the whole slab starts on, which is the widest field's.
fields
One entry per stored top-level field, in declaration order.
SegmentLayoutrecord
One field segment for a particular element count.
Fields
field
Which field this segment holds.
offset
Where the segment starts, in bytes from the slab's aligned base.
byteCount
How many bytes it occupies.
Spaninterface
sealed interface soa . Span < T >
metamethod __len : function ( self : Span < T > ) : integer
metamethod __index : function ( borrows self : Span < T > , index : integer ) : T
slice : function ( borrows self : Span < T > , first : integer , last : integer ? ) : soa . Span < T > borrows ( self )
field : function ( borrows self : Span < T > , name : string ) : any borrows ( self )
end
A shared checked view over SoA rows.
Type parameters
Methods
__len
__len : function ( self : Span < T > ) : integer
Arguments Name Type Description selfSpan < T >
Returns
__index
__index : function ( borrows self : Span < T > , index : integer ) : T
Arguments Name Type Description borrows selfSpan < T > indexinteger
Returns
slice
slice : function ( borrows self : Span < T > , first : integer , last : integer ? ) : soa . Span < T > borrows ( self )
Answers a subrange of rows, inclusive at both ends.
The result borrows this view, and omitting last runs through to the end.
Arguments Name Type Description borrows selfSpan < T > firstinteger lastinteger ?
Returns Type Description soa . Span < T > borrows ( self )
field
Answers one field's column as a nupp.mem.span view over this range.
The name must be a string literal naming a stored field, which is what lets the checker give the result that field's element type rather than any. A dynamic string or a missing field reports NUPP2403.
const rows = positions : read ( )
const velocity : span . Span < float > = rows : field ( "velocity" )
for index = 1 , # velocity do
print ( velocity [ index ] )
end
Arguments Name Type Description borrows selfSpan < T > namestring
Returns Type Description any borrows ( self )
Writabletype
An affine exclusive row view, released at its lexical boundary.
Type parameters
WriteSpaninterface
sealed interface soa . WriteSpan < T >
metamethod __len : function ( self : WriteSpan < T > ) : integer
metamethod __index : function ( borrows self : WriteSpan < T > , index : integer ) : T
metamethod __newindex : function ( exclusive self : WriteSpan < T > , index : integer , value : T ) : nil
field : function ( exclusive self : WriteSpan < T > , name : string ) : any borrows ( self )
shared : function ( borrows self : WriteSpan < T > ) : soa . Span < T > borrows ( self )
copyFrom : function (
exclusive self : WriteSpan < T > ,
targetFirst : integer ,
borrows source : soa . Span < T > ,
sourceFirst : integer ,
count : integer
) : nil
slice : function (
exclusive self : WriteSpan < T > ,
first : integer ,
last : integer ?
) : affine ( soa . WriteToken & soa . WriteSpan < T > , soa . destroyWriteSpan ) borrows ( self )
end
An affine exclusive checked view over SoA rows.
Type parameters
Methods
__index
__index : function ( borrows self : WriteSpan < T > , index : integer ) : T
Arguments Name Type Description borrows selfWriteSpan < T > indexinteger
Returns
__newindex
__newindex : function ( exclusive self : WriteSpan < T > , index : integer , value : T ) : nil
Arguments Name Type Description exclusive selfWriteSpan < T > indexinteger valueT
Returns
field
Answers one field's column as a writable nupp.mem.span view.
Two different fields may be projected at once, because the columns do not overlap. The name must be a string literal naming a stored field; a dynamic string or a missing field reports NUPP2403.
Arguments Name Type Description exclusive selfWriteSpan < T > namestring
Returns Type Description any borrows ( self )
shared
shared : function ( borrows self : WriteSpan < T > ) : soa . Span < T > borrows ( self )
Downgrades this writer to a shared row view for the lifetime of the result.
Arguments
Returns Type Description soa . Span < T > borrows ( self )
copyFrom
copyFrom : function (
exclusive self : WriteSpan < T > ,
targetFirst : integer ,
borrows source : soa . Span < T > ,
sourceFirst : integer ,
count : integer
) : nil
Copies a row range from another view of the same struct.
Both ranges are checked before the first byte moves, and the copy is one contiguous run per column rather than a row at a time, so no row struct is ever materialized.
with rows = target : write ( ) do
rows : copyFrom ( 3 , source : read ( ) , 1 , 2 )
end
Arguments Name Type Description exclusive selfWriteSpan < T > targetFirstinteger borrows sourcesoa . Span < T > sourceFirstinteger countinteger
Returns
slice
Answers an affine writable subrange of rows, inclusive at both ends.
The child borrows this view, so the parent is unusable until the child is dropped. Row indexes start at one in the child, as they do in the parent.
Arguments Name Type Description exclusive selfWriteSpan < T > firstinteger lastinteger ?
Returns
WriteTokeninterface
Methods
drop
drop : nosuspend function ( takes self : WriteToken ) : nil
Arguments
Returns
Functions
soa.allocatefunction
Allocates one SoA slab for a reified struct type.
The compiler injects the descriptor, and aliases of this exact function retain the intrinsic identity. The result owns the slab and frees it at its lexical boundary; the bytes are not zeroed.
local positions = soa . allocate ( ffi . typeof < Position > ( ) , 128 )
with rows = positions : write ( ) do
rows [ 1 ] . x = 3.5
end
Type parameters
Arguments Name Type Description elementctype < T > the ctype of one row
countinteger how many rows to allocate
Returns
Raises
soa.destroyArrayfunction
Frees a slab, which is what every SoA array's contract names.
Nothing calls this by hand. It is the terminal consumer affine carries, so a scope boundary or an explicit drop reaches it.
Type parameters
Arguments Name Type Description takes selfT the array, spent by this call
Returns
soa.destroyWriteSpanfunction
Ends a row writer, which is what every writable row view's contract names.
Nothing calls this by hand. It is the terminal consumer affine carries, so a scope boundary or an explicit drop reaches it.
Type parameters
Arguments Name Type Description takes selfT the writer, spent by this call
Returns
soa.layoutoffunction
Answers immutable SoA reflection for a reified struct type without allocating.
Only top-level fields are split, so a nested struct or fixed array is one field here whatever it holds.
Type parameters
Arguments Name Type Description elementctype < T > the ctype of one row
Returns Type Description soa . Layout the count-independent descriptor
Raises
← Previous nupp.mem.sharedbytes Next → nupp.mem.span