-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Region.mo
library offering isolated regions of IC stable memory
#580
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor fixes
src/Region.mo
Outdated
// Region is a stable type and regions can be stored in stable variables. | ||
public type Region = Prim.Types.Region; | ||
|
||
// Allocate a new, isolated Region of size 0. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
src/Region.mo
Outdated
// Allocate a new, isolated Region of size 0. | ||
public let new = Prim.regionNew; | ||
|
||
public let id = Prim.regionId; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rubber-stamping!
Region.mo
library offering isolated regions of IC stable memory
Note this is intended for branch next-moc.
CI expected to fail for base branch next-moc.
Builds fine against moc regions branch
Replaces original PR #516 (that I forgot existed but also targeted master, not next-moc as required)
Region
). motoko#3768, sources.nix and udpdate base doc there.Region
Byte-level access to isolated, (virtual) stable memory regions.
This is a moderately lightweight abstraction over IC stable memory and supports persisting
regions of binary data across Motoko upgrades.
Use of this module is fully compatible with Motoko's use of
stable variables, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.
It is also fully compatible with existing uses of the
ExperimentalStableMemory
library, which has a similar interface, but,only supported a single memory region, without isolation between different applications.
Memory is allocated, using
grow(region, pages)
, sequentially and on demand, in units of 64KiB logical pages, starting with 0 allocated pages.New pages are zero initialized.
Growth is capped by a soft limit on physical page count controlled by compile-time flag
--max-stable-pages <n>
(the default is 65536, or 4GiB).Each
load
operation loads from region relative byte addressoffset
in little-endianformat using the natural bit-width of the type in question.
The operation traps if attempting to read beyond the current region size.
Each
store
operation stores to region relative byte addressoffset
in little-endian format using the natural bit-width of the type in question.The operation traps if attempting to write beyond the current region size.
Text values can be handled by using
Text.decodeUtf8
andText.encodeUtf8
, in conjunction withloadBlob
andstoreBlob
.The current region allocation and region contents are preserved across upgrades.
NB: The IC's actual stable memory size (
ic0.stable_size
) may exceed thetotal page size reported by summing all regions sizes.
This (and the cap on growth) are to accommodate Motoko's stable variables and bookkeeping for regions.
Applications that plan to use Motoko stable variables sparingly or not at all can
increase
--max-stable-pages
as desired, approaching the IC maximum (initially 8GiB, then 32Gib, currently 64Gib).All applications should reserve at least one page for stable variable data, even when no stable variables are used.
Usage:
Type
Region
A stateful handle to an isolated region of IC stable memory.
Region
is a stable type and regions can be stored in stable variables.Value
new
Allocate a new, isolated Region of size 0.
Example:
Value
id
Return a Nat identifying the given region.
Maybe be used for equality, comparison and hashing.
NB: Regions returned by
new()
are numbered from 16(regions 0..15 are currently reserved for internal use).
Allocate a new, isolated Region of size 0.
Example:
Value
size
Current size of
region
, in pages.Each page is 64KiB (65536 bytes).
Initially
0
.Preserved across upgrades, together with contents of allocated
stable memory.
Example:
Value
grow
Grow current
size
ofregion
by the given number of pages.Each page is 64KiB (65536 bytes).
Returns the previous
size
when able to grow.Returns
0xFFFF_FFFF_FFFF_FFFF
if remaining pages insufficient.Every new page is zero-initialized, containing byte 0x00 at every offset.
Function
grow
is capped by a soft limit onsize
controlled by compile-time flag--max-stable-pages <n>
(the default is 65536, or 4GiB).Example:
Value
loadNat8
Within
region
, load aNat8
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeNat8
Within
region
, store aNat8
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadNat16
Within
region
, load aNat16
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeNat16
Within
region
, store aNat16
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadNat32
Within
region
, load aNat32
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeNat32
Within
region
, store aNat32
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadNat64
Within
region
, load aNat64
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeNat64
Within
region
, store aNat64
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadInt8
Within
region
, load aInt8
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeInt8
Within
region
, store aInt8
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadInt16
Within
region
, load aInt16
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeInt16
Within
region
, store aInt16
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadInt32
Within
region
, load aInt32
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeInt32
Within
region
, store aInt32
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadInt64
Within
region
, load aInt64
value fromoffset
.Traps on an out-of-bounds access.
Example:
Value
storeInt64
Within
region
, store aInt64
value atoffset
.Traps on an out-of-bounds access.
Example:
Value
loadFloat
Within
region
, loads aFloat
value from the givenoffset
.Traps on an out-of-bounds access.
Example:
Value
storeFloat
Within
region
, store floatvalue
at the givenoffset
.Traps on an out-of-bounds access.
Example:
Value
loadBlob
Within
region,
loadsize
bytes starting fromoffset
as aBlob
.Traps on an out-of-bounds access.
Example:
Value
storeBlob
Within
region, write
blob.size()bytes of
blobbeginning at
offset`.Traps on an out-of-bounds access.
Example: