User Defined Indexes
User-defined indexes for the eXtremeDB native API are explained in the Indexes and Cursors page. As with native User-defined Functions (
udf
) the UDA API requires that the application supply two compare functions fortree
indexes and two additionalhash
functions for hash indexes. Fortree
indexes, provide one custom function that compares two objects and one that compares an object to an external key value. Forhash
indexes, provide two pairs of functions: two returning a hash code and two compare functions (if a user-defined tree index is also defined then these compare functions are used for thehash
index as well).These functions must then be registered with the runtime before cursor functions can be called on these indexes by passing a parameter of the following type:
typedef struct mco_uda_userdef_funcs_t_ { mco_uda_compare_userdef_f fcomp; mco_uda_compare_extkey_userdef_f fcomp_ext; mco_uda_hash_userdef_f fhash; mco_uda_hash_extkey_userdef_f fhash_ext; } mco_uda_userdef_funcs_t, *mco_uda_userdef_funcs_h;The application implements these compare functions with the following function signatures:
/* Object - Object */ typedef int2(*mco_uda_compare_userdef_f)( mco_uda_object_handle_p obj1, unsigned short index1, mco_uda_object_handle_p obj2, unsigned short index2, void *user_context); /* Object - external key(s) */ typedef int2(*mco_uda_compare_extkey_userdef_f)( mco_uda_object_handle_p obj, unsigned short index, mco_uda_value_t *keys, uint2 keys_count, void *user_context);These compare functions must return <0, =, or >0 depending on whether the object value is less than, equal to or greater than the external key value.
In addition, for hash indexes, two custom functions need be implemented with the following function signatures:
/* Hash - Object */ typedef uint4 (*mco_uda_hash_userdef_f)( mco_uda_object_handle_p obj, unsigned short index, void *user_context); /* Hash – external key(s) */ typedef uint4 (*mco_uda_hash_extkey_userdef_f)( mco_uda_value_t *keys, uint2 keys_count, void *user_context);Note that
hash
index compare functions return0
if and only if two objects (or object and external key) are equal from the index point of view. This is necessary forhash
index operations because hash codes may be equal yet the objects (keys) are not. Whenmco_uda_lookup()
is called with ahash
index, it will call the user-defined compare function to assure that any matching hash code actually exactly matches the indexed database field value.Notice also that the compare functions receive application specific data passed from the caller via the
user_context
parameter.In addition to the compare functions, the UDA API requires a
udf
map for the internal implementation of index navigation. Thisudf
map must be allocated and passed to the runtime when theudfs
are registered.The following function queries the database dictionary to determine the amount of memory to be allocated for the
udf
map:MCO_RET mco_uda_get_udfmap_size( const mco_metadict_header_t * metadict, unsigned short dict_no, /* out */ unsigned int * size);Once the compare functions are defined, the
mco_uda_userdef_funcs_t
structure initialized, and theudf
map allocated and its size determined, use the following API to register theudfs
with the runtime:MCO_RET mco_uda_register_udf( const mco_metadict_header_t * metadict, unsigned short dict_no, unsigned short struct_no, unsigned short index_no, mco_userdef_funcs_h udf_map, mco_uda_userdef_funcs_h udf_entry, void *user_context);The following code snippet demonstrates how to register
udf
compare functions:/* allocate udfmap */ mco_uda_get_udfmap_size(metadict, 0, &udf_map_size); udf_map = (mco_userdef_funcs_h) malloc(udf_map_size); /* register user-defined compare & hash functions */ udf_entry.fcomp = cmp_obj_obj; /* Object – object compare */ udf_entry.fcomp_ext = cmp_obj_ext; /* Object – key compare */ udf_entry.fhash = hash_obj; /* Hash – object compare */ udf_entry.fhash_ext = hash_ext; /* Hash – key compare */ param.fld_no = name_no; /* will pass name_no to compare/hash functions */ rc = mco_uda_register_udf( metadict, 0, Record_no, tudf_no, udf_map, &udf_entry, (void*) ¶m); if ( MCO_S_OK != rc) { printf("Error in mco_uda_register_udf() : %s\n", mco_ret_string(rc, 0)); exit(0); }
Note that the user-context parameter
param
is used by the external key compare functions to callmco_uda_get()
to retrieve the database field value to be compared to the external key value.
The registration API must be called for all user-defined indexes, before the application makes a call to
mco_db_connect()
.
Note that for shared-memory databases, the
udf
functions must be registered in each process separately.