A PersistStore allows C++ objects to persist on non-volatile storage, such as a hard disk drive or solid state drive.
Within a given PersistStore
each persistent object has a unique 64 bit identifier called an
OID (Object Identifier).
These persistent objects are heap allocated object instances of C++ classes that are reference types, and implement the interface IPersistable which is a sub-interface of IObject.
They form object graphs using pointers ("references"). On non-volatile storage the references are recorded using 64 bit OIDs, and in memory they are represented using C++ object pointers.
A PersistStore
could be regarded as providing an Object Oriented Database (OODB).
It is well suited to being a low level layer on which to implement data structures such as data records, linked
lists, B-Trees, key-value stores, indexes etc. Indeed it is well suited for being a layer on which a
relational database (RDB) is implemented.
The persistable objects in a PersistStore
are partitioned into mutually exclusive
PSpaces.
To open or create a PersistStore
, call the function OpenPersistStore.
All the objects in a PersistStore
are written to a single file, which is opened exclusively by a single process.
In that sense a PersistStore
is an embedded database.
Any number of PersistStores can be opened within a given process.
A PersistStore
is implemented using a CEDA Log Structured Store (LSS) to record
the serialised states of the objects.
An LSS is essentially a key-value store where the keys are 64 bit identifiers called Seids (Serial Element Identifiers) and the values are octet streams called Serial Elements.
Each persistent C++ object in a PersistStore
is represented in the LSS as a (seid,serial-element) pair where the
Seid is the object's OID and the serial element is the serialised state of the object.
A PersistStore
keeps track of the objects which have been updated and not yet written back to disk.
This is called the Dirty Object Set (DOS).
A PersistStore
keeps track of the objects which currently reside in memory. This is called the
Resident Object Table (ROT).
$adt+ PersistStore
{
void Close();
bool CreatedNew() const;
ILogStructuredStore* GetLss();
void StartObjectDeletion();
void WriteAllDirtyObjectsToLss(bool flushToDisk);
PersistStoreTxn* OpenTxn(PSpaceLockMode* L, ssize_t n);
int32 GetDosPeriod() const;
void SetDosPeriod(int32 time);
ssize_t GetNumPSpaces() const;
ssize_t GetNumPersistableObjects() const;
TypeOpsId GetTypeOpsId(const ReflectionByteCodeValue& rbcv, const TypeOps& typeOps);
BcTypeOps GetTypeOps(TypeOpsId tid);
};
void Close()
Close the PersistStore
.
Failing to close the PersistStore
may cause data loss!
Note that all transactions on the store must have been closed, and all its PSpaces must have been closed.
bool CreatedNew() const
Indicates whether PersistStore
was created for the first time, in the call to
OpenPersistStore.
ILogStructuredStore* GetLss()
Get direct access to the associated LSS. Never returns NULL
void StartObjectDeletion()
See PersistStoreSettings. If the store was opened with PersistStoreSettings::startObjectDeletion = false then this function can be called to enable lazy object deletion. This might be useful if object deletion depends on relevant DLLs being loaded in order to avoid ReflectedClassNotFoundException exceptions.
void WriteAllDirtyObjectsToLss(bool flushToDisk)
Ensures that all changes in all PSpaces are written to the LSS. If flushToDisk = true then the LSS transaction(s) are also flushed to disk.
It is inappropriate to call this function midway through a transaction because it can mean objects are written to the store in an intermediate state, breaking transaction atomicity guarantees.
PersistStoreTxn* OpenTxn(PSpaceLockMode* L, ssize_t n)
Open a PersistStoreTxn on this PersistStore
.
L is an array of PSpaceLockMode of size n defining the PSpaces to be accessed
by the transaction, and whether read or write access is required.
Each PSpace specified in L must belong to this PersistStore
.
Note that L can be NULL with n=0.
All the associated CSpaces must have already been locked before calling this function.
Furthermore if L specifies ECSpaceLockMode::Exclusive for a PSpace then the associated CSpace must have also
been locked with the ECSpaceLockMode::Exclusive mode.
The CSpaces must remain locked until after the transaction is closed.
Never returns NULL.
int32 GetDosPeriod() const
Get the time in milliseconds between each processing of the dirty object set.
void SetDosPeriod(int32 time)
Set the time in milliseconds between each processing of the dirty object set.
Wakes up the thread used to process the dirty object set if it's currently asleep.
ssize_t GetNumPSpaces() const
ssize_t GetNumPersistableObjects() const
Get the number of IPersistable objects in the PersistStore
, accounting for the number of serial
elements used for special purposes by the PersistStore
and by each PSpace, and assuming all
remaining serial elements are used for IPersistable objects.
The implementation of this function first calls WriteAllDirtyObjectsToLss(false) to flush all
changes to all PSpaces to the LSS, so that the number of serial elements in the LSS can be used
to determine the number of IPersistable objects.
This function treats pending asynchronous deletions as though the objects haven't been deleted
yet. Therefore repeated calls to GetNumPersistableObjects() can give decreasing values as
IPersistable objects are being asynchronously deleted.
It is inappropriate to call this function midway through a transaction because it can mean objects are written to the store in an intermediate state, breaking transaction atomicity guarantees.
TypeOpsId GetTypeOpsId(const ReflectionByteCodeValue& rbcv, const TypeOps& typeOps)
Get the TypeOpsId for the given ReflectionByteCodeValue. Creates a new entry if required
BcTypeOps GetTypeOps(TypeOpsId tid)
Get the TypeOps and ReflectionByteCodeValue for the given TypeOpsId.
Throws
Never returns a BcTypeOps with NULL values for rbcv or typeOps
The PersistStore
reserves some OIDs for internal purposes. See reserved OIDs.