سؤال

I know that in ZODB you can use a BTree to store large amounts of data and have lookups based on a key with total ordering be logarithmic to the size of the tree.

The problem is, I have some Persistent object Foo, and some other Persistent object Bar and I'd like to store a bi-directional mapping between them, in the sense of bidict.

i.e. it should be efficient (logarithmic time) to perform the two accesses:

# foo is a Foo; bar is a Bar; foos is a collection of persisted Foos; bar is a collection of persisted Bars

baz = foos[foo]
quux = bars[bar]

# baz is a Bar that foo is mapped to
# quux is the Foo that bar is mapped to

The only convenient way I can think of right now is to simply double my storage requirements and maintain two BTrees: one stores mappings from A to B and the other for mappings from B to A. Of course, at all times, the BTrees will contain the same elements, as additions and deletions of mappings are performed on both in tandem.

My concern about this is that the trees may become decoupled with the absence of database constraints. Do you think this is workable?

هل كانت مفيدة؟

المحلول

This is workable, if you enclose them in a class that checks the constraints, that is

from ZODB.PersistentMapping import PersistentMapping (for example)

class Bidict(Persistent):
    def __init__(self):
        self._forward = PersistentMapping()
        self._reverse = PersistentMapping()

    def add(self, from, to):
        self._forward[from] = to
        self._reverse[to] = from

    def getFrom(...)
    def getTo(...)

If there's only one way to add data (not deliberately breaking the abstraction), you have reasonnable insurance that your data stays consistent.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top