|
The Btree data structure is a sorted, balanced tree structure storing associated key/data pairs. By default, the sort order is lexicographical, with shorter keys collating before longer keys. The user can specify the sort order for the Btree by using the DB->set_bt_compare function.
Sort routines are passed pointers to keys as arguments. The keys are represented as DBT structures. The routine must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second argument. The only fields that the routines may examine in the DBT structures are data and size fields.
An example routine that might be used to sort integer keys in the database is as follows:
int compare_int(dbp, a, b) DB *dbp; const DBT *a, *b; { int ai, bi;/* * Returns: * < 0 if a < b * = 0 if a = b * > 0 if a > b */ memcpy(&ai, a->data, sizeof(int)); memcpy(&bi, b->data, sizeof(int)); return (ai - bi); }
Note that the data must first be copied into memory that is appropriately aligned, as Berkeley DB does not guarantee any kind of alignment of the underlying data, including for comparison routines. When writing comparison routines, remember that databases created on machines of different architectures may have different integer byte orders, for which your code may need to compensate.
An example routine that might be used to sort keys based on the first five bytes of the key (ignoring any subsequent bytes) is as follows:
int compare_dbt(dbp, a, b) DB *dbp; const DBT *a, *b; { int len; u_char *p1, *p2;/* * Returns: * < 0 if a < b * = 0 if a = b * > 0 if a > b */ for (p1 = a->data, p2 = b->data, len = 5; len--; ++p1, ++p2) if (*p1 != *p2) return ((long)*p1 - (long)*p2); return (0); }
All comparison functions must cause the keys in the database to be well-ordered. The most important implication of being well-ordered is that the key relations must be transitive, that is, if key A is less than key B, and key B is less than key C, then the comparison routine must also return that key A is less than key C. In addition, comparisons will only be able to return 0 when comparing full length keys; partial key comparisons must always return a result less than or greater than 0.
It is reasonable for a comparison function to not examine an entire key in some applications, which implies that partial keys may be specified to the Berkeley DB interfaces. When partial keys are specified to Berkeley DB, interfaces which retrieve data items based on a user-specified key (for example, DB->get and DBcursor->c_get with the DB_SET flag), will not modify the user-specified key by returning the actual key stored in the database. The actual key can be retrieved by calling the DBcursor->c_get function with the DB_CURRENT flag.