[ZODB-Dev] OOBTree key requirements?

Magnus Lyckå magnus@thinkware.se
Sun, 03 Mar 2002 01:21:27 +0100


I'm trying out OOBTrees, and I'm puzzled.
I'm using a version of ZODB that I got from
A.M.Kuchling's site last October. (The
BTrees files are all dated 2001-03-31.)

Using the code below, I expect to get several
items in some PersistentLists in the OOBTree.
But instead, it seems I get the same key
value repeated several times. A simplified
image of what I expect to see is:
a1 : [((a1,c),(a2,c)), ((a2,c2),(a1,c2))]
a2 : [((a1,c),(a2,c)), ((a2,c),(a3,c)), ((a2,c2),(a1,c2))]
a3 : [((a2,c),(a3,c))]
c  : [((a1,c),(a2,c)), ((a2,c),(a3,c))]
c2 : [((a2,c2),(a1,c2))]

When I inspect my data using .items() (see __str__ below) I
see the following strange things instead:
a1 : [((a1, c), (a2, c))]
c  : [((a1, c), (a2, c))]
a2 : [((a1, c), (a2, c))]
a3 : [((a2, c), (a3, c))]
a1 : [((a1, c), (a2, c))]
c2 : [((a2, c2), (a1, c2))]
c  : [((a1, c), (a2, c))]
a2 : [(a1, c), (a2, c))]

So, it seems that instead of getting several items in my
list I get the same key in two places in the tree, and
using .items() to view it seems to show the first found
value each time it finds the same key. The inconsistent
thing is that I only get a2 twice...

The __cmp__ method in the objects I use as keys looks like
this. The oid is a time stamp based string. And it doesn't
change over time! ;-)

     def __cmp__(self, other):
         if not h2util.isinstance(other, Entity): return -1 #commenting out 
this changes nothing.
         return cmp(self.__oid, other.__oid)

The storage class looks (partly) like this:

class _Signals(Persistence.Persistent):

     def __init__(self):
         self.__tree = BTrees.OOBTree.OOBTree()

     def add(self, source, destination):
         signal = (source, destination)
         for controlEvent in [source, destination]:
             for element in controlEvent.getElements(): # Returns 
(activity, condition)
                 if not self.__tree.has_key(element):
                     self.__tree[element] = 
ZODB.PersistentList.PersistentList()
                 if signal not in self.__tree[element]:
                     self.__tree[element].append(signal)
     def __str__(self):
         res = []
         for k, v in self.__tree.items():
             res.append("%s : %s" % (str(k),
                                     map(lambda x: (str(x[0]),str(x[1])),v)))
         return '\n'.join(res)

Any ideas?


-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus@thinkware.se