[ZODB-Dev] BTrees and Mutables, was Re: [IndexedCatalog] bug in default indexing

Shane Hathaway shane@zope.com
Tue, 11 Feb 2003 15:24:05 -0500


Casey Duncan wrote:
> An alternative which is perhaps more palatable is to just set the whole 
> mutable object into the btree again. Like:
> 
> l = tree['bar']
> l.append(4)
> tree['bar'] = l # Trigger list persistance

In fact, if you put simple lists in BTrees, you have to use this 
pattern.  Setting tree._p_changed will not get the right object stored. 
  BTrees consist of many objects and you have to notify the right one.

This is a messy problem.  To avoid bugs, it's better to put tuples or 
persistent objects, rather than lists, in BTrees.

[Christian Reis]
>>    - BTrees themselves are mutable objects. However, since they are
>>      first-class Python instances, and because they have "magic"
>>      properties, there is no requirement to set _p_changed=1 with holding
>>      a reference to a changed BTree. I.E.:
>>
>>        tree = BTree()
>>        obj.tree = tree
>>        tree['foo'] = 'foo'
>>        # obj has _p_changed set *magically*

This isn't BTree magic, it's ZODB magic.  Just to clarify. :-)

>>    - If a BTree holds a reference to a non-BTree *mutable* type such as
>>      a list, and that list changes, then the *BTree itself* needs to
>>      have _p_changed set. I.E.:
>>
>>        # Continuing from the above example, with obj.tree = tree
>>        tree['bar'] = [1,2,3]
>>        tree['bar'].append(4)
>>        tree._p_changed = 1

Again, this code snippet isn't quite right.  In general, it is not 
necessary or useful to set _p_changed when working with BTrees.

>>    Now my question is, really, this: does obj, who holds the BTree
>>    reference, also require _p_changed to be set, or does the BTree's
>>    magic notify the ZODB that obj needs to be saved, too? IOW:
>>
>>        # Do we also need this?
>>        obj._p_changed = 1 

No, you don't need to do this.  The obj.tree and obj are in separate 
ZODB records, and ZODB only needs to store the records that have changed.

Shane