durusmail: durus-users: Durus Change Preview
Durus Change Preview
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-25
2006-10-31
2006-10-31
Durus Change Preview
David Binger
2006-10-25
The recent discussion here (initiated by Patrick K. O'Brien)
about slots and RAM requirements
motivated me to try some changes in the durus development
tree.  I'm wondering what people will think about them, so
I'll describe them here.

1) The Persistent class is split into two classes, so that
Persistent inherits from a new PersistentObject class.
Instances of Persistent do have a __dict__, just like before.
Direct instances of PersistentObject, like direct instances of
"object",  don't have __dict__ attributes.

2) __setstate__() now clears all data attribute values before
it sets the new values using the argument it is given, which
may be a dict or None.

3) The base class of PersistentDict, PersistentList,
PersistentSet, and BTree, and BNode classes is changed from
Persistent to PersistentObject, and __slots__ attributes
are put on those classes, so that direct instances of
these classes don't have __dict__ values.

Before this change, you could set arbitrary attributes on
direct instances of these container classes.  After the
change, you can't do that.  If you want arbitrary attributes
on a PersistentDict, you will now be required to use a
subclass of PersistentDict instead.  If you have existing
stored PersistentDict instances with other attributes, you'll
need to write and run an update script to convert those
to your PersistentDictWithDict subclass.  And the same
applies to the other container classes.

In the new arrangement, applications that access __dict__
directly, or that use vars(), should instead use __getstate__().
__getstate__() will be expected to return either
a dict or None.

This arrangement allows you to define persistent classes
that use slots instead of a __dict__ (for the purpose of
reducing the RAM required to hold those objects in RAM).
To do that, make your class a subclass of PersistentObject
instead of Persistent, and add a __slots__ attribute
to your class.

My experiments indicate a savings of something like 140 bytes
per instance.  It doesn't seem like much, but when you have
hundreds of thousands of instances and multiple clients, it
does seem to be worth the effort.

This change does not change anything about object records,
so it has no impact at all on storage file size.

reply