PSpace named roots

Each PSpace contains a set of named persistent root objects that implement interface IPersistable. Any non-empty null terminated UTF-8 encoded string serves as a valid name as long as it is unique amongst the root objects in the PSpace.

Note that the PSpace internally stores prefs to the roots, which means that they can be evicted from memory. Therefore it can't be assumed that the pointer returned by GetRoot() remains usable after the CSpace lock is released. A client may want to call AddGcRoot() to prevent eviction of the root.

The following methods on a PSpace allow for getting, adding and removing the named roots:


$adt+ PSpace
{
    ...
    ptr<IPersistable> GetRoot(ConstStringZ name);
    bool AddRoot(ConstStringZ name, ptr<IPersistable> root);
    bool RemoveRoot(ConstStringZ name);
};

ptr<IPersistable> GetRoot(ConstStringZ name)

Find the root with the given name in this PSpace. Returns null if not found The calling thread must have opened a transaction with read or write access on the PSpace


bool AddRoot(ConstStringZ name, ptr<IPersistable> root)

Add the given root with the given name in this PSpace. RepresentsSubTree() must return true for the given root. The given root object must not be reachable from a PSpace when this function is called. Usually it will have just been allocated from the heap. If a root with the given name already exists then this function makes no changes and returns false. The calling thread must have opened a transaction with exclusive write access to the PSpace


bool RemoveRoot(ConstStringZ name)

Remove the root with the given name from this PSpace. Returns false if no root with the given name exists. The calling thread must have opened a transaction with exclusive write access to the PSpace

Free function versions using the PSpace in thread local storage

In cases where it can be assumed the PSpace has been set in thread local storage, the following free functions can be used instead:


$function+ ptr<IPersistable> GetPSpaceRoot(ConstStringZ name)
{
    return GetRoot(GetThreadPtr<PSpace>(), name);
}
$function+ bool AddPSpaceRoot(ConstStringZ name, ptr<IPersistable> root)
{
    return AddRoot(GetThreadPtr<PSpace>(), name, root);
}
$function+ bool RemovePSpaceRoot(ConstStringZ name)
{
    return RemoveRoot(GetThreadPtr<PSpace>(), name);
}

$function+ ptr<IPersistable> GetPSpaceRoot(ConstStringZ name)

Assumes a PSpace is set in thread local storage. Returns GetRoot(name) on the PSpace in thread local storage.


$function+ bool AddPSpaceRoot(ConstStringZ name, ptr<IPersistable> root)

Assumes a PSpace is set in thread local storage. Calls AddRoot(name,root) on the PSpace in thread local storage.


$function+ bool RemovePSpaceRoot(ConstStringZ name)

Assumes a PSpace is set in thread local storage Calls RemoveRoot(name) on the PSpace in thread local storage.

Bootstrap PSpace root functions

Typically we want to get a named root object in the PSpace, and if it doesn't already exist create it. We call that a bootstrap of a PSpace root. The following template functions are available for bootstrapping PSpace roots of a given concrete type.


template<class T> T* BootstrapPSpaceRoot(ConstStringZ rootName)

Find or create a PSpace root named rootName of concrete class T, which must support the IPersistable interface.

The calling thread must have a PSpace set in thread local storage.

This function defines its own ECSpaceLockMode::Exclusive transaction on the PSpace in order to load or create the root.

This function adds the root (whether created or loaded from disk) as a GC root to protect it from garbage collection.

Returns a pointer to the instance, or nullptr if an instance was found but wasn't of the appropriate type.


template<class T> T* BootstrapPSpaceRoot2(ConstStringZ rootName)

Alternative version that assumes the caller has already got an exclusive lock on the PSpace, and doesn't add the object as a GC root.