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
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.
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.