Skip to content

PgMemoryContext

Namespace: Ankus

Assembly: Ankus.Runtime.dll

Represents a checked PostgreSQL memory context accessed from synchronous backend callbacks.

public sealed class PgMemoryContext : IDisposable

A function, operator, or cast can declare this type as a by-value parameter to receive a borrowed context without adding a SQL argument. Scalar functions receive the current context; set factories receive their multi-call context. The handle keeps that identity across ambient context switches and becomes stale when PostgreSQL reclaims its owner. Nullable annotations and optional managed defaults do not make the injected context null.

Inheritance: object

Implements: IDisposable

Allocate(nuint, PgAllocationOptions, nuint)

Section titled “Allocate(nuint, PgAllocationOptions, nuint)”

Allocates bytes owned by this context with checked access through the returned handle.

public PgAllocation Allocate(nuint length, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0)

Parameters:

length — nuint

The number of bytes.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The checked allocation.

Native allocator restrictions apply. Slab requires its configured chunk size. Bump permits allocation but reclaims storage only through context reset or deletion, rejecting individual disposal and resizing. Prefer context-owned values when individual release is unavailable.

Copies strict UTF-8 text and one terminating zero into a distinct native allocation.

public PgAllocation AllocateUtf8String(string value)

Parameters:

value — string

Text without embedded zero characters or malformed UTF-16.

Returns: PgAllocation

The allocation containing UTF-8 bytes and their terminating zero.

This copies UTF-8 without conversion to PostgreSQL’s database encoding.

AllocateZeroed(nuint, PgAllocationOptions, nuint)

Section titled “AllocateZeroed(nuint, PgAllocationOptions, nuint)”

Allocates zeroed bytes owned by this context.

public PgAllocation AllocateZeroed(nuint length, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0)

Parameters:

length — nuint

The number of bytes.

options — PgAllocationOptions

Additional native allocation policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The checked zeroed allocation.

AllocateZeroedBox<T>(PgAllocationOptions, nuint)

Section titled “AllocateZeroedBox<T>(PgAllocationOptions, nuint)”

Allocates an individually owned value whose entire representation is zeroed without running a constructor.

public PgNativeBox<T> AllocateZeroedBox<T>(PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation.

Parameters:

options — PgAllocationOptions

Additional native size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgNativeBox<T>

The individually disposable zeroed owner.

AllocateZeroed<T>(nuint, PgAllocationOptions, nuint)

Section titled “AllocateZeroed<T>(nuint, PgAllocationOptions, nuint)”

Allocates zeroed native bytes for a checked number of unmanaged values.

public PgAllocation AllocateZeroed<T>(nuint count = 1, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged value type.

Parameters:

count — nuint

The number of values.

options — PgAllocationOptions

Additional native allocation policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The byte-addressed checked zeroed allocation.

Allocate<T>(nuint, PgAllocationOptions, nuint)

Section titled “Allocate<T>(nuint, PgAllocationOptions, nuint)”

Allocates enough native bytes for a checked number of unmanaged values.

public PgAllocation Allocate<T>(nuint count = 1, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged value type; no catalog or C struct layout is inferred.

Parameters:

count — nuint

The number of values.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The byte-addressed checked allocation.

CopyFrom(ReadOnlySpan<byte>, PgAllocationOptions, nuint)

Section titled “CopyFrom(ReadOnlySpan<byte>, PgAllocationOptions, nuint)”

Copies managed bytes into a distinct native allocation.

public PgAllocation CopyFrom(ReadOnlySpan<byte> source, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0)

Parameters:

source — ReadOnlySpan<byte>

The bytes to copy.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The independently owned checked allocation.

CopyFrom<T>(ReadOnlySpan<T>, PgAllocationOptions, nuint)

Section titled “CopyFrom<T>(ReadOnlySpan<T>, PgAllocationOptions, nuint)”

Copies the exact unmanaged representation of managed values into distinct native storage.

public PgAllocation CopyFrom<T>(ReadOnlySpan<T> source, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged value type; its bytes are copied without SQL conversion.

Parameters:

source — ReadOnlySpan<T>

The values to copy.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The independently owned byte-addressed allocation.

Create(string, PgMemoryContext?, PgMemoryContextOptions?)

Section titled “Create(string, PgMemoryContext?, PgMemoryContextOptions?)”

Creates an owned AllocSet child of the current context.

public static PgMemoryContext Create(string name, PgMemoryContext? parent = null, PgMemoryContextOptions? options = null)

Parameters:

name — string

The identifier shown by PostgreSQL memory statistics.

parent — PgMemoryContext

The parent context, or null for the callback’s current context.

options — PgMemoryContextOptions

The AllocSet block sizes, or null for PostgreSQL’s default preset.

Returns: PgMemoryContext

The new owned context.

CreateBox<T>(T, PgAllocationOptions, nuint)

Section titled “CreateBox<T>(T, PgAllocationOptions, nuint)”

Creates an initialized unmanaged value with individual native allocation ownership.

public PgNativeBox<T> CreateBox<T>(T value, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation to copy; no C ABI or SQL type is inferred.

Parameters:

value — T

The initial value copied into native storage.

options — PgAllocationOptions

The native initialization and size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgNativeBox<T>

The individually disposable owner.

CreateContextValue<T>(T, PgAllocationOptions, nuint)

Section titled “CreateContextValue<T>(T, PgAllocationOptions, nuint)”

Creates an initialized unmanaged value reclaimed by its native context rather than individual disposal.

public PgContextValue<T> CreateContextValue<T>(T value, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation to copy.

Parameters:

value — T

The initial value.

options — PgAllocationOptions

The native initialization and size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgContextValue<T>

The context-owned value.

CreateFlatArray<T>(ReadOnlySpan<int>, ReadOnlySpan<int>)

Section titled “CreateFlatArray<T>(ReadOnlySpan<int>, ReadOnlySpan<int>)”

Allocates a zeroed flat array of fixed-size scalars in this context, as pgrx’s FlatArray::new_zeroed_in does.

public PgFlatArray<T> CreateFlatArray<T>(ReadOnlySpan<int> lengths, ReadOnlySpan<int> lowerBounds = default) where T : unmanaged

Type parameters:

T

The element: sbyte (“char”), short, int, long, uint (oid), float, double or bool.

Parameters:

lengths — ReadOnlySpan<int>

The length of each dimension; none creates an empty array.

lowerBounds — ReadOnlySpan<int>

The lower bound of each dimension, or none for one-based dimensions.

Returns: PgFlatArray<T>

The array, filled with zero and living until this context resets or is deleted.

Exceptions:

Adopts exclusive individual ownership of an initialized palloc-compatible value, mapping a null address to null.

public PgNativeBox<T>? DangerousAdoptBox<T>(void* address, bool huge = false, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The complete unmanaged representation at the supplied address.

Parameters:

address — void*

The live palloc-family address, or null.

huge — bool

Whether the allocation uses PostgreSQL’s huge-size policy.

alignment — nuint

The allocation’s original explicit alignment, or zero for the server default.

Returns: PgNativeBox<T>

The individually disposable owner, or null without backend access for a null address.

The caller guarantees accessible initialized bytes, native allocator provenance, and exclusive ownership.

DangerousAdoptContextValue<T>(void*, bool, nuint)

Section titled “DangerousAdoptContextValue<T>(void*, bool, nuint)”

Adopts a non-null initialized palloc-compatible value for reclamation by its native context.

public PgContextValue<T> DangerousAdoptContextValue<T>(void* address, bool huge = false, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The complete unmanaged representation at the supplied address.

Parameters:

address — void*

The non-null live palloc-family address.

huge — bool

Whether the allocation uses PostgreSQL’s huge-size policy.

alignment — nuint

The allocation’s original explicit alignment, or zero for the server default.

Returns: PgContextValue<T>

The non-null context-owned value.

The caller transfers exclusive ownership and guarantees accessible initialized bytes and native allocator provenance.

DangerousAllocateUninitializedBox<T>(PgAllocationOptions, nuint)

Section titled “DangerousAllocateUninitializedBox<T>(PgAllocationOptions, nuint)”

Allocates individually owned native storage that must be fully initialized before its value is read.

public PgNativeBox<T> DangerousAllocateUninitializedBox<T>(PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation.

Parameters:

options — PgAllocationOptions

The native initialization and size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgNativeBox<T>

The individually disposable uninitialized owner.

Borrows a native MemoryContext address, such as a function’s fn_mcxt obtained through raw bindings, so the managed allocation, scoping and callback APIs can use it, as pgrx’s PgMemoryContexts::For does.

[NativeUnsafeAccess]
public static PgMemoryContext DangerousBorrow(nint context)

Parameters:

context — nint

The native MemoryContext address.

Returns: PgMemoryContext

A borrowed handle that does not delete the context when disposed.

Exceptions:

The caller must supply the address of a live context in this backend. Ankus checks only its node tag, so a dangling or foreign address is undefined behavior. The handle survives a reset and becomes stale when PostgreSQL deletes the context.

Borrows an external initialized address using this context as a reset-sensitive lifetime anchor.

public PgNativeReference<T>? DangerousBorrow<T>(void* address) where T : unmanaged

Type parameters:

T

The complete unmanaged representation available at the address.

Parameters:

address — void*

The accessible initialized raw address, or null.

Returns: PgNativeReference<T>

A borrowed view, or null without backend access for a null address.

The address need not be a palloc chunk start. No native allocator ownership is inferred or acquired. The caller guarantees at least sizeof(T) valid bytes and honors any shorter external lifetime, including stack return, resource closure, external free, or external resize.

Borrows an initialized raw value with an explicit accessible byte extent and this context’s reset generation.

public PgNativeReference<T>? DangerousBorrow<T>(void* address, nuint byteLength) where T : unmanaged

Type parameters:

T

The complete unmanaged representation available at the address.

Parameters:

address — void*

The accessible initialized raw address, or null.

byteLength — nuint

The caller-guaranteed accessible extent, at least the size of T.

Returns: PgNativeReference<T>

A borrowed view, or null without backend access for a null address.

No allocator ownership is inferred. The caller guarantees the entire extent remains accessible and honors shorter external lifetimes. Typed casts retain this extent and the captured generation; a cast never increases the caller’s original storage guarantee.

Finds the context that owns a palloc’d allocation, as PostgreSQL’s GetMemoryChunkContext and pgrx’s PgMemoryContexts::of do.

[NativeUnsafeAccess]
public static PgMemoryContext DangerousGetOwner(nint allocation)

Parameters:

allocation — nint

The address palloc returned.

Returns: PgMemoryContext

A borrowed handle for the owning context.

Exceptions:

  • ArgumentException: The address is null, misaligned or not owned by a memory context.

The caller must supply an address returned by PostgreSQL’s allocator that has not been freed; any other address, including one inside an allocation, is undefined behavior. A Bump context does not record its chunks’ owner, so its allocations are not supported.

Gets the native MemoryContext address for raw PostgreSQL calls, as pgrx’s PgMemoryContexts::value does.

[NativeUnsafeAccess]
public nint DangerousGetPointer()

Returns: nint

The address, valid until the context is reset or deleted.

Disposes an owned context. Borrowed contexts remain owned by PostgreSQL.

public void Dispose()

Resolves a predefined PostgreSQL memory context, or null when that context is not active.

public static PgMemoryContext? Get(PgMemoryContextKind kind)

Parameters:

kind — PgMemoryContextKind

The predefined context to resolve.

Returns: PgMemoryContext

A borrowed context, or null when PostgreSQL has no such context in this phase.

Gets the context’s native allocation statistics.

public nuint GetAllocatedBytes()

Returns: nuint

The bytes accounted to this context and its descendants.

Registers a one-shot callback before this context’s next reset or deletion.

public PgMemoryCallback RegisterResetCallback(Action callback)

Parameters:

callback — Action

The synchronous cleanup action.

Returns: PgMemoryCallback

A registration whose disposal cancels the pending callback.

Callbacks run in reverse registration order, including callbacks registered during cleanup. SQL, logging, configuration reads, and aggregate operations are unavailable during cleanup. Errors propagate after managed frames unwind; callbacks not yet invoked remain pending for a subsequent reset or deletion. Cleanup owned by ErrorContext or its descendants cannot perform guarded native memory or SPI operations.

Resets this context, invalidates its existing allocations, and deletes its descendant contexts.

public void Reset()

Resets all child contexts while retaining this context and its direct allocations.

public void ResetChildren()

Resets this context without deleting its child contexts.

public void ResetOnly()

Executes a synchronous callback with this context current and restores the previous context on every exit path.

public void Run(Action action)

Parameters:

action — Action

The callback that runs with this context current.

RunTransient(string, Action<PgMemoryContext>, PgMemoryContext?, PgMemoryContextOptions?)

Section titled “RunTransient(string, Action<PgMemoryContext>, PgMemoryContext?, PgMemoryContextOptions?)”

Runs synchronous work in a new child context and attempts its deletion on every exit path.

public static void RunTransient(string name, Action<PgMemoryContext> action, PgMemoryContext? parent = null, PgMemoryContextOptions? options = null)

Parameters:

name — string

The transient context’s native identifier.

action — Action<PgMemoryContext>

The work performed with the transient context current.

parent — PgMemoryContext

The parent context, or null for the caller’s current context.

options — PgMemoryContextOptions

The AllocSet block sizes, or null for PostgreSQL’s default preset.

RunTransient<TResult>(string, Func<PgMemoryContext, TResult>, PgMemoryContext?, PgMemoryContextOptions?)

Section titled “RunTransient<TResult>(string, Func<PgMemoryContext, TResult>, PgMemoryContext?, PgMemoryContextOptions?)”

Runs synchronous work in a new child context and attempts its deletion after restoring the caller.

public static TResult RunTransient<TResult>(string name, Func<PgMemoryContext, TResult> func, PgMemoryContext? parent = null, PgMemoryContextOptions? options = null)

Type parameters:

TResult

The managed result type.

Parameters:

name — string

The transient context’s native identifier.

func — Func<PgMemoryContext, TResult>

The work performed with the transient context current.

parent — PgMemoryContext

The parent context, or null for the caller’s current context.

options — PgMemoryContextOptions

The AllocSet block sizes, or null for PostgreSQL’s default preset.

Returns: TResult

The callback’s result.

Return copied managed values rather than native pointers. Escaped checked handles become stale after successful deletion. Callback, restoration, and deletion failures are preserved together. If native cleanup fails, the context remains owned by its parent until cleanup is retried. Recover actual PostgreSQL errors with RunInSubtransaction(Action) before retrying cleanup or performing further backend work.

Executes a synchronous callback with this context current and restores the previous context on every exit path.

public TResult Run<TResult>(Func<TResult> func)

Type parameters:

TResult

The callback result type.

Parameters:

func — Func<TResult>

The callback that runs with this context current.

Returns: TResult

The callback result.

TryAllocate(nuint, PgAllocationOptions, nuint)

Section titled “TryAllocate(nuint, PgAllocationOptions, nuint)”

Attempts an allocation with explicit native policies without raising an out-of-memory error.

public PgAllocation? TryAllocate(nuint length, PgAllocationOptions options, nuint alignment = 0)

Parameters:

length — nuint

The number of bytes.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The allocation, or null for allocator exhaustion; other native errors still throw.

Attempts a no-OOM allocation and returns null only for allocator exhaustion.

public PgAllocation? TryAllocate(nuint length, bool zeroed = false)

Parameters:

length — nuint

The number of bytes.

zeroed — bool

Whether to clear the allocated bytes.

Returns: PgAllocation

The allocation, or null when PostgreSQL reports out of memory.

TryAllocate<T>(nuint, PgAllocationOptions, nuint)

Section titled “TryAllocate<T>(nuint, PgAllocationOptions, nuint)”

Attempts native allocation for a checked number of unmanaged values.

public PgAllocation? TryAllocate<T>(nuint count = 1, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged value type.

Parameters:

count — nuint

The number of values.

options — PgAllocationOptions

The initialization and native size policies.

alignment — nuint

A power of two below 128 MiB, or zero for PostgreSQL’s default alignment.

Returns: PgAllocation

The checked allocation, or null for allocator exhaustion.

TryCreateBox<T>(T, PgAllocationOptions, nuint)

Section titled “TryCreateBox<T>(T, PgAllocationOptions, nuint)”

Attempts initialized native value allocation using PostgreSQL’s no-OOM policy.

public PgNativeBox<T>? TryCreateBox<T>(T value, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation to copy.

Parameters:

value — T

The initial value.

options — PgAllocationOptions

The native initialization and size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgNativeBox<T>

The individually disposable owner, or null only for allocator exhaustion.

TryCreateContextValue<T>(T, PgAllocationOptions, nuint)

Section titled “TryCreateContextValue<T>(T, PgAllocationOptions, nuint)”

Attempts initialized context-owned storage using PostgreSQL’s no-OOM policy.

public PgContextValue<T>? TryCreateContextValue<T>(T value, PgAllocationOptions options = PgAllocationOptions.None, nuint alignment = 0) where T : unmanaged

Type parameters:

T

The unmanaged representation to copy.

Parameters:

value — T

The initial value.

options — PgAllocationOptions

The native initialization and size policies.

alignment — nuint

The requested explicit alignment, or zero for the server default.

Returns: PgContextValue<T>

The context-owned value, or null only for allocator exhaustion.

Gets the callback’s current PostgreSQL memory context.

public static PgMemoryContext Current { get; }

Value: PgMemoryContext

Each lookup resolves the ambient context at that moment. A previously returned or injected handle continues to represent its original context after a context switch.

Gets whether this handle still refers to a live native context.

public bool IsAlive { get; }

Value: bool

Gets whether PostgreSQL reports this context as empty.

public bool IsEmpty { get; }

Value: bool

PostgreSQL marks AllocSet contexts with registered invalidation callbacks as nonempty, including after an explicit reset. Slab, Generation, and Bump use allocator-specific block or live-chunk accounting; this is not a portable count of user allocations.

Gets the native context identifier, copied before the next reset can invalidate it.

public string Name { get; }

Value: string

Gets the live parent context, or null for a top-level context.

public PgMemoryContext? Parent { get; }

Value: PgMemoryContext