Tutorial

Key Sort Order

If you did not specify a key type (with UPS_PARAM_KEY_TYPE in ups_env_create_db) or you specified the default UPS_TYPE_BINARY type, then upscaledb treats your keys as byte arrays and sorts them in ascending order with the standard memcmp() function of the C/C++ runtime library.

If such a sort order is not feasible for your data, you can overwrite the sort function. You have to select the key type UPS_TYPE_CUSTOM, write a callback function and register this function with ups_db_set_compare_func. Keep in mind that you have to do this whenever you create and open a Database, since the comparison function is not stored in the Database itself. Registering your comparison function has to take place immediately after you created or opened the Database, and before you search, insert or erase keys!

typedef int (*ups_compare_func_t)(ups_db_t *db,
        const uint8_t *lhs, uint32_t lhs_length,
        const uint8_t *rhs, uint32_t rhs_length);

API reference of ups_db_set_compare_func

The callback function receives four parameters: the “left-hand side” and the “right-hand side” of the compare operation. It returns –1 if the left-hand side is smaller than the right-hand side, it returns 0 if both keys are equal, or +1 if right-hand side is smaller than left-hand side.

The following code snippet casts the keys to integer values and compares those integers.

#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <ups/upscaledb.h>
static int
my_int_compare (ups_db_t *db, const uint8_t *lhs, uint32_t lhs_size,
                const uint8_t *rhs, uint32_t rhs_size) {
  int nlhs = *lhs;
  int nrhs = *(int *)rhs;
  if (nlhs < nrhs) return –1;
  if (nlhs > nrhs) return +1;
  return 0;
}

int main()
{
  ups_status_t st;
  ups_db_t *db;
  ups_parameter_t params[] = {
    {UPS_PARAM_KEY_TYPE, UPS_TYPE_CUSTOM},
    {0, 0}
  };

  // … create or open the Environment and the Database.
  // Don’t forget to call ups_env_create_db with the parameter list as
  // created above!
  //
  if ((st = ups_db_set_compare_func (db, my_int_compare)) != UPS_SUCCESS) {
    printf ("error %d: %s\n", st, ups_strerror(st));
    exit (–1);
  }
  // …
}