On Oct 6, 2:10 am, "pbour" <panayiotis.bou... (AT) gmail (DOT) com> wrote:
Quote:
I want to create a primary database according to the relation R:
R(int A, int B, primary key(A,B)) where primary key is a BTREE
so the key field of the database should a complex one, with two
integers. For storing I use marshalling. The value field its empty.
BUT the question is what compare functions either for prefix or general
I should define in order to be able to query the database giving value
only to A integer? |
If your marshalling stores the values in big-endian ("network") byte
order, than the default comparison and prefix functions will work and
no overriding is necessary. IMHO, this is by far the simplest and most
robust solution.
If you aren't marshalling in big-endian order, you'll need to make sure
you comparison function operates sanely when given a key that isn't
long enough to include all the fields. For example, if your integers
are exactly four bytes long giving a total key size of eight bytes,
then the comparison function should treat keys that are only four bytes
long as sorting just before all eight bytes keys with the same first
four bytes.
The ideal handling of keys that include just part of a field is not
clear. I would tend to sort them between keys that lack the field
completely and before keys that include the entire field, sorting among
such partial keys using a pure-lexical sort on the partial field bytes.
Alternatively, you could consider it a fatal data error and simply
abort() if that happens, but that may cause other problems.
Quote:
HAS anybody actually implemented a database like that? |
Yep.
Quote:
I 've tried to use c_get with "DB_SET_RANGE" flag but I think this is
analogous to query with condition A < "..." . |
No, it's comparable to A >= "..." ("the smallest key greater than or
equal to the specified key"). So, you do a DBC->c_get(DB_SET_RANGE).
If it returns DB_NOTFOUND, there are no entries in the entire database
that have a key that compares equal-to or greater-than the supplied
key. If it returns zero, then you unmarshal the returned key; if it's
too large, there are no matches. Otherwise you have your first match
right there. To fetch the next match (if any), you used
DBC->c_get(DB_NEXT) with the same cursor and the same checking of the
return value and returned key to determine whether there was another
match or not.
Philip Guenther