[MUD-Dev] [TECH] Open Source oodb/object persistence toolkit library alpha release

Brian Price brianleeprice at hotmail.com
Sun Jul 1 10:22:06 New Zealand Standard Time 2001

For the past few years I've been working on a variety of lightweight
oodb and object persistence systems for C++.  I have finally created
a portable, template based, C++ toolkit library encapsulating much
of that work.  C++ Common Persistent Objects Library (cpolib for
short) is an Open Source LGPL licensed library that is now in alpha
release v0.10.  Within a few days the project should be hosted on

I'm posting this notice here because the driving force behind much
of the design and development of cpolib and its predecessors has
been to provide object persistence and object streaming network
protocols for MUDs of all types.  While not strictly a part of
cpolib, there are two systems currently under development that are
built on top of cpolib of particular interest to MUD devs: Saga - a
high speed object caching lightweight oodb with zero-stall snapshot
capability built atop cpolib and berkley db; and Valkyrie - a fully
object oriented binary network protocol with rmi capabilities atop
either tcp or udp.

Saga is fully designed and implemented but as yet untested.
Valkyrie is currently under design.  Once the SourceForge cpolib
site is up, I'll be making both available there as 'example' systems
built atop cpolib.  Eventually Java and Python bindings will be
available for cpolib as well as both example systems.  In Saga's
case, the addition of Java and Python bindings will hopefully help
to mitigate the relatively weak dynamic query capabilities present
in many oodb designs.  That note brings me to another issue - design
of oodb models.

A well designed oodb has some significant advantages for MUD server
design - since the db model is identical to your game object model,
accesses to the object data store can be made both transparent and
high speed (particularly in multithreaded server models).  Due to
the direct one to one relationship between game objects and data
store objects, as well as the lightweight nature of an optimized
oodb engine design, an oodb will provide higher performance than the
equivalent rdb in many cases.  The red flag thrown up by rdbms
adherents - weak dynamic query capabilities - is well deserved in
many cases and is grounded in two basic facts: one - since there is
only one object model, the data store cannot be easily accessed
without the corresponding runtime code that implements the objects;
two - many models are naively designed and fail to take advantage of
one of the greatest strengths of well designed oodbs - the ability
to express any relationship as either a net of objects, a
collection, a collection of collections, or some combination of all

The first source of the weak dynamic query capability - the need for
the runtime code corresponding to objects - will be addressed in
Saga and cpolib primary through the addition of Java and Python
bindings.  While the code is still necessary, you will be able to
use scripts to access the code.

The second source of weak dynamic query capability - the failure to
take advantage of object relationships - is harder to address.  The
capability to express these relationships is supported in cpolib -
it has the capability to make any STL container persistent and it
provides the idea of a data proxy - a lightweight persistent stand
in for data objects.  Actually expressing the relationships is a
design issue for the system implementor.  A naive design will be
difficult to maintain - in the worst case a maintenance issue
requires access to objects through a relationship that is not
expressed as any sort of object net or collection - in this case the
only way to access the information is to iterate through the entire
database.  Obviously this is not desireable except for extremely low
priority maintenance tasks.

A much better design is to create data objects which hold
collections of data proxies (references to other data objects).
These collection objects are roughly equivalent to indices in an
rdb.  For example: consider a skill based MUD - provide a collection
object for each skill that holds references to everyone who has that
skill.  Finding the average skill level for a particular skill is
then a relatively easy task - simply obtain the desired skill
collection from the collection of all skills, and then iterate
through the list of characters who have that skill.  At first glance
this would still seem inferior to rdbms solutions, however when
examining this case one must consider the difference in rdb and oodb
engine implementations - the oodb engine operates at a lower layer
and any valid performance comparison must take that into account.

Still, this design can be improved upon if the need is great enough
to justify it - simply create a skillset data object that holds a
reference to the character and use it to hold each character's
skillset.  Now the skill collection should be modified to hold
references to skill set objects.  This 'drill-down' design approach
can be pursued to any desired level depending upon requirements.
The trade off is design complexity and data object overhead - each
data object reference typically requires 4 bytes of storage and each
data object in memory has an overhead of between 24 and 32 bytes
depending upon which layer of the cache it resides in.  The finer
grained the model, the more memory and data store space requirements
increase.  At the finest grain level every attribute is represented
by its own data object.  There is a performance trade off as well,
finer grained models will require more time to access attributes as
there will be an extra object fetch for each attribute.  There are a
number of ways to partially circumvent this performance degradation
but their explanation is rather technical and specific to the oodb

If you are interested in the cpolib project and is unable to find it
on SourceForge within a few days, please email me.

Brian Price
MUD-Dev mailing list
MUD-Dev at kanga.nu

More information about the MUD-Dev mailing list