Namespaces
Relevant source files
Purpose and Scope
This document provides a detailed explanation of the Namespace
struct in the AXNS system, which serves as a container for resources. It covers the internal structure, creation, resource access methods, and memory management of namespaces. For information about the resources themselves and how they're wrapped, see Resources and ResWrapper. For details on thread-local namespace features, see Thread-Local Features.
Namespace Structure
In AXNS, a Namespace
is a collection of resources, each accessed through a reference-counted pointer (ResArc
). The Namespace
struct is defined in src/ns.rs
and consists of a single pointer field that points to an array of ResArc
instances.
flowchart TD subgraph subGraph0["Namespace Structure"] Namespace["Namespace {ptr: NonNull}"] ResArcArray["Array of ResArcs (size = Resources.len())"] ResArc1["ResArc[0]"] ResArc2["ResArc[1]"] ResArcN["ResArc[n-1]"] Resource1["Resource Data 1"] Resource2["Resource Data 2"] ResourceN["Resource Data n"] end Namespace --> ResArcArray ResArc1 --> Resource1 ResArc2 --> Resource2 ResArcArray --> ResArc1 ResArcArray --> ResArc2 ResArcArray --> ResArcN ResArcN --> ResourceN
Sources: src/ns.rs(L6 - L13)
Namespace Creation and Initialization
When a new Namespace
is created using Namespace::new()
, it:
- Allocates memory for an array of
ResArc
instances (one for each resource in the system) - Initializes each
ResArc
with its corresponding resource's default value - Returns the constructed
Namespace
sequenceDiagram participant CodecreatingNamespace as "Code creating Namespace" participant Namespacenew as "Namespace::new()" participant MemoryAllocator as "Memory Allocator" participant ResourcesCollection as "Resources Collection" CodecreatingNamespace ->> Namespacenew: Call new() Namespacenew ->> ResourcesCollection: Get resources count (Resources.len()) ResourcesCollection -->> Namespacenew: Return count Namespacenew ->> MemoryAllocator: Allocate array of ResArc (size) MemoryAllocator -->> Namespacenew: Return allocated memory loop For each resource in Resources Namespacenew ->> ResourcesCollection: Get resource ResourcesCollection -->> Namespacenew: Return resource Namespacenew ->> Namespacenew: Initialize ResArc for resource end Namespacenew -->> CodecreatingNamespace: Return new Namespace
Sources: src/ns.rs(L16 - L36)
Resource Access
The Namespace
provides two primary methods for accessing resources:
get(&self, res: &'static Resource) -> &ResArc
: Returns a reference to theResArc
for a given resource.get_mut(&mut self, res: &'static Resource) -> &mut ResArc
: Returns a mutable reference to theResArc
for a given resource.
Both methods use the resource's index (obtained via res.index()
) to locate the corresponding ResArc
in the array.
Method | Description | Implementation |
---|---|---|
get | Returns a reference to a resource'sResArc | Uses the resource's index to find the correspondingResArcin the array |
get_mut | Returns a mutable reference to a resource'sResArc | Uses the resource's index to find the correspondingResArcin the array |
Sources: src/ns.rs(L38 - L46)
Global and Thread-Local Namespaces
AXNS supports two namespace access patterns:
- Global Namespace: A singleton namespace accessible from anywhere via the
global_ns()
function - Thread-Local Namespaces: When the "thread-local" feature is enabled, each thread can have its own namespace
flowchart TD subgraph subGraph0["Namespace Resolution"] A["current_ns()"] B["thread-local feature?"] C["Thread-Local CurrentNsImpl"] D["Global CurrentNsImpl"] E["Thread's Namespace"] F["Global Namespace (from global_ns())"] G["Access Resources"] end A --> B B --> C B --> D C --> E D --> F E --> G F --> G
Sources: src/lib.rs(L16 - L59)
Memory Management
The Namespace
struct carefully manages memory for all its resources. When a Namespace
is dropped:
- It calls
drop_in_place()
on the array ofResArc
instances, which decrements the reference count for each resource - It deallocates the memory used for the array itself
This ensures that resources are properly cleaned up when they're no longer needed.
Sources: src/ns.rs(L55 - L63)
Namespace in the AXNS Architecture
The Namespace
is a central component in the AXNS system, working closely with other components:
flowchart TD subgraph subGraph0["AXNS Component Relationships"] Namespace["Namespace(Container for resources)"] ResArc["ResArc(Reference-counted resource)"] Resource["Resource(Resource metadata)"] ResWrapper["ResWrapper(Type-safe resource access)"] GlobalNs["global_ns()(Returns static Namespace)"] CurrentNs["current_ns()(Thread-local or global)"] end CurrentNs --> Namespace GlobalNs --> Namespace Namespace --> ResArc ResArc --> Resource ResWrapper --> Namespace ResWrapper --> Resource
Sources: src/lib.rs(L10 - L14) src/ns.rs(L1 - L4)
Implementation Details
The Namespace
implementation includes several important features:
- Memory Efficiency: Uses a single pointer to an array rather than a standard Rust collection to minimize overhead
- Safety Markers: Implements
Send
andSync
traits to indicate thread safety - Default Implementation: Provides a
Default
implementation that callsnew()
- Manual Memory Management: Performs explicit allocation and deallocation to maintain control over memory layout
API Summary
Method | Description | Example Usage |
---|---|---|
Namespace::new() | Creates a newNamespacewith default values | let ns = Namespace::new(); |
ns.get(resource) | Gets a reference to a resource | let r = ns.get(&MY_RESOURCE); |
ns.get_mut(resource) | Gets a mutable reference to a resource | let r = ns.get_mut(&MY_RESOURCE); |
global_ns() | Gets the global namespace | let ns = global_ns(); |
current_ns() | Gets the current namespace (global or thread-local) | let ns = current_ns(); |