[ZODB-Dev] OOBTree: Persistent Objects as keys

Toby Dickenson tdickenson@geminidataloggers.com
Wed, 6 Feb 2002 13:53:27 +0000


On Wednesday 06 February 2002 12:27 pm, you wrote:

>The problem occurs when Python falls back to comparing addresses.
>If we could raise an error when this happens, we could avoid building
>meaningless BTrees. (Note that a similar problem occurs when hashes
>based
>on addresses of persistenct objects are uses in has tables.)

I think its bigger than that. Using __cmp__ comparison also has problems when 
mixing unicode string and 8-bit-wide strings.

Even worse, Python reserves the right to change the order of the default 
cross-type comparison. If I remember correctly, the relative sort order of 
None and integers changed in Python 2.2. I wonder how many databases out 
there contain this mix of keys, and will break after upgrading to 2.2.

>Hm, maybe BTrees should use their own comparison algorithm
>that never compares addresses. This would be a bit of a pain, since
>given the complexity of Python's internal comparison logic. Perhaps
>the Python logic could just be copied and the bit that falls back to
>address comparison could be hacked out.

I like the C++ solution to this problem:

The comparison operators (>, >=, ==, etc) define the natural sort order. 
Cross-comparing objects for which there is no natural order (such as
comparing strings to ints, or comparing a complex number to another complex 
number) will cause a failure at compile.

However, it is also possible to define a template function less<> 
which defines a total ordering, and is used by default by the set<> and map<> 
containers (which have the same requirements as our BTrees). There is no 
requirement that this ordering be a sensible one since it is only used by 
data structures, not humans. 

Im not sure how this maps onto a Python solution for BTrees.....

The easiest solution would be to change no code, and attach a big warning to 
the documentation saying that BTree keys must have a stable strict order. 
This would require changes to broken applications: Zope would need a user 
interface for choosing the type of objects for ZCatalog FieldIndex. Thomas' 
application would need to use fatter keys which include a type code (example 
below). However, C++ experience shows that many developers will take a long 
time to fully understand this requirement placed on them.

Im not sure Jims solution (defining a BTree-specific comparison function) can 
work without breaking nice characteristics such as the equivalence of:
* btree[1]
* btree[1.0]
* btree[MyCustomLongIntegerType(1)]


Thomas: your application could use keys which are 2-tuples. The first element 
is a code (string, integer, whatever) defining object classifications. You 
must then ensure that all objects within each classification have a stable 
total order. For example, keys could be ("FooClassification",FooObject(x))