On 18 July 2011 11:07, Pedro Ferreira <jose.pedro.ferre...@cern.ch> wrote:
> Hello,
> I have an OOTreeSet in my DB that is behaving a bit funny (seems to be
> corrupted). I thought I could get some more information by performing a
> sanity check, but that doesn't seem to help a lot:
> """
>>>> c in s
> False
>>>> c in list(s)
> True
>>>> s._check()
> """
> Shouldn't there be an error in this case?

TreeSets are essentially BTrees with only keys. This means that the
members of a TreeSet must have a stable ordering. I suspect that that
c's class does not define the comparison methods (such as __lt__)
which means under Python 2 it falls back to the default ordering based
on object id (Python 3 will raise a TypeError instead, avoiding this
problem.) With ZODB an object's Python id (the memory address of the
object) will change whenever it is reloaded, i.e. across restarts,
after invalidation or removal from the cache.

A TreeSet is ordered, so the contains comparison only needs to perform
a lookup to see whether an object is a member of the TreeSet, as the
id of the object has changed, its expected position has changed and it
is not found. A list is not ordered, so it has to check against every
object in the list to test for containment.

The _check() method only confirms that the BTree/TreeSets's internal
data structure is consistent. It does not check every item. So it does
not show an error in this case.

You will need to add comparison methods for the class of the objects
you are storing in the TreeSet and then rebuild the TreeSets.

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -  ZODB-Dev@zope.org

Reply via email to