UDA 用户自定义索引
有关 SmartEDB 本地 API 的用户自定义索引在“索引和游标”页面中有详细说明。与本地用户自定义函数(udf)一样,UDA API 要求应用程序为树形索引提供两个比较函数,并为哈希索引提供两个额外的哈希函数。对于树形索引,提供一个自定义函数来比较两个对象,以及一个将对象与外部键值进行比较的函数。对于哈希索引,提供两对函数:两对返回哈希码的函数和两对比较函数(如果还定义了用户自定义树形索引,则这些比较函数也将用于哈希索引)。
在可以对这些索引调用游标函数之前,必须先将这些函数向运行时进行注册,为此需要传递以下类型的参数:
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;该应用程序通过以下函数签名实现了这些比较函数:
/* 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);这些比较函数必须根据对象值是否小于、等于或大于外部键值分别返回 <0、= 或 >0。 此外,对于哈希索引,需要实现以下函数签名的两个自定义函数:
/* 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);请注意,哈希索引比较函数仅当两个对象(或对象与外部键)从索引的角度来看相等时才返回 0。这对于哈希索引操作是必要的,因为哈希码可能相等,但对象(键)却不相等。当使用哈希索引调用 mco_uda_lookup() 时,它将调用用户定义的比较函数,以确保任何匹配的哈希码实际上与索引的数据库字段值完全匹配。
还请注意,比较函数会接收由调用方通过 user_context 参数传递的应用程序特定数据。
除了比较函数之外,UDA API 还需要一个 UDF 映射来实现索引导航的内部功能。在注册 UDF 时,必须分配此 UDF 映射并将其传递给运行时。
以下函数查询数据库字典以确定为 udf 映射分配的内存量:
MCO_RET mco_uda_get_udfmap_size(
const mco_metadict_header_t * metadict,
unsigned short dict_no,
/* out */ unsigned int * size
);一旦定义了比较函数,初始化了 mco_uda_userdef_funcs_t 结构,并分配了 UDF 映射且确定了其大小,即可使用以下 API 将 UDF 注册到运行时:
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
);以下代码片段演示了如何注册用户自定义函数(UDF)比较函数:
/* 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);
}请注意,外部键比较函数使用用户上下文参数 param 调用 mco_uda_get() 函数来检索要与外部键值进行比较的数据库字段值。
对于所有用户定义的索引,在应用程序调用 mco_db_connect() 之前,必须调用注册 API。
请注意,对于共享内存数据库,必须在每个进程中分别注册 udf 函数。
