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 fortreeindexes and two additionalhashfunctions for hash indexes. Fortreeindexes, provide one custom function that compares two objects and one that compares an object to an external key value. Forhashindexes, 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 thehashindex 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
hashindex compare functions return0if and only if two objects (or object and external key) are equal from the index point of view. This is necessary forhashindex operations because hash codes may be equal yet the objects (keys) are not. Whenmco_uda_lookup()is called with ahashindex, 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_contextparameter.In addition to the compare functions, the UDA API requires a
udfmap for the internal implementation of index navigation. Thisudfmap must be allocated and passed to the runtime when theudfsare registered.The following function queries the database dictionary to determine the amount of memory to be allocated for the
udfmap: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_tstructure initialized, and theudfmap allocated and its size determined, use the following API to register theudfswith 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
udfcompare 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
paramis 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
udffunctions must be registered in each process separately.