3、KV存储部件对外接口
在文件utils\native\lite\include\kv_store.h中定义了KV存储部件对外接口,如下,支持从键值对缓存里读取键值,设置键值,删除键值,清除缓存等等。
int UtilsGetValue(const char* key, char* value, unsigned int len);
int UtilsSetValue(const char* key, const char* value);
int UtilsDeleteValue(const char* key);
#ifdef FEATURE_KV_CACHE
int ClearKVCache(void);
#endif
在文件utils\native\lite\kv_store\innerkits\kvstore_env.h中定义了如下接口,在使用POSIX接口时,需要首先使用接口需要设置数据文件路径。使用UtilsFile接口时,不需要该接口。
int UtilsSetEnv(const char* path);
4、KV存储部件对应POSIX接口部分的代码
分析下KV存储部件对应POSIX接口部分的代码。我们知道对外接口有设置键值UtilsSetValue、获取键值UtilsGetValue、删除键值UtilsDeleteValue和清除缓存ClearKVCache。我们先看看内部接口。
4.1 内部接口
4.1.1 GetResolvedPath解析路径
函数GetResolvedPath用于解析文件路径,根据键名key组装存放值value的文件路径。需要4个参数,第一个参数char* dataPath为键值对保存的文件路径,在使用KV特性前由UtilsSetEnv函数设置到全局变量里g_dataPath;第二个参数为键char* key;第三个参数char* resolvedPath为解析后的路径,为输出参数;第4个参数unsigned int len为路径长度。看下代码,⑴处为解析的路径申请内存,⑵处拼装键值对的文件路径,格式为"XXX/kvstore/key"。⑶将相对路径转换成绝对路径,如果解析成功,会把文件路径解析到输出参数resolvedPath。⑷处如果执行realpath函数出错,指定的文件不存在,会执行⑸把keyPath复制到输出函数resolvedPath。
static int GetResolvedPath(const char* dataPath, const char* key, char* resolvedPath, unsigned int len)
{
⑴ char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
⑵ if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
free(keyPath);
return EC_FAILURE;
}
⑶ if (realpath(keyPath, resolvedPath) != NULL) {
free(keyPath);
return EC_SUCCESS;
}
⑷ if (errno == ENOENT) {
⑸ if (strncpy_s(resolvedPath, len, keyPath, strlen(keyPath)) == EOK) {
free(keyPath);
return EC_SUCCESS;
}
}
free(keyPath);
return EC_FAILURE;
}
4.1.2 GetValueByFile从文件中读取键值
函数GetValueByFile从文件中读取键对应的值,需要4个参数,第一个参数为键值文件存放的目录路径;第二个参数为键;第三个为输出参数,存放获取的键的值;第4个参数为输出参数的长度。该函数返回值为EC_FAILURE或成功获取的值的长度。⑴处获取对应键名key的文件路径,⑵处读取文件的状态信息。因为文件内容是键对应的值,⑶处表明如果值的大小大于等于参数len,则返回错误码。等于也不行,需要1个字符长度存放null字符用于结尾。⑷处打开文件,然后读取文件,内容会存入输出参数value里。⑸处设置字符串结尾的null字符。
static int GetValueByFile(const char* dataPath, const char* key, char* value, unsigned int len)
{
char* keyPath = (char *)malloc(PATH_MAX + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
⑴ if (GetResolvedPath(dataPath, key, keyPath, PATH_MAX + 1) != EC_SUCCESS) {
free(keyPath);
return EC_FAILURE;
}
struct stat info = {0};
⑵ if (stat(keyPath, &info) != F_OK) {
free(keyPath);