网站备案填了虚假座机能过吗/济南市最新消息
Utils子系统是OpenHarmony的公共基础库,存放OpenHarmony通用的基础组件。这些基础组件可被OpenHarmony各业务子系统及上层应用所使用。公共基础库在不同平台上提供的能力:
- LiteOS-M内核:KV(key value)存储、文件操作、定时器、Dump系统属性。
- LiteOS-A内核:KV(key value)存储、定时器、JS API(设备查询,数据存储)、Dump系统属性。
本文介绍下移植开发板时如何适配utils子系统之KV存储部件,并介绍下相关的运行机制原理。KV存储部件定义在utils\native\lite\。源代码目录如下:
utils/native/lite/ # 公共基础库根目录
├── file # 文件接口实现
├── hals # HAL目录
│ └── file # 文件操作硬件抽象层头文件
├── include # 公共基础库对外接口文件
├── js # JS API目录
│ └── builtin
│ ├── common
│ ├── deviceinfokit # 设备信息Kit
│ ├── filekit # 文件Kit
│ └── kvstorekit # KV存储Kit
├── kal # KAL目录
│ └── timer # Timer的KAL实现
├── kv_store # KV存储实现
│ ├── innerkits # KV存储内部接口
│ └── src # KV存储源文件
├── memory
│ └── include # 内存池管理接口
├── os_dump # Dump系统属性
└── timer_task # Timer实现
1、KV存储部件适配示例
1.1 配置产品解决方案config.json
utils子系统之KV存储部件的适配示例可以参考vendor\ohemu\qemu_csky_mini_system_demo\config.json,代码片段如下。⑴处用于配置子系统的KV存储部件。⑵处指定在开发板目录中适配目录,这个适配目录下需要创建目录device\qemu\SmartL_E802\adapter\hals\utils\file\,之前的移植案例与原理文章中介绍过vendor_adapter_dir目录。对于KV存储部件,与适配syspara_lite部件类似,适配kv_store部件时,键值对会写到文件中。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。部件文件utils\native\lite\kv_store\src\BUILD.gn中声明了enable_ohos_utils_native_lite_kv_store_use_posix_kv_api配置参数,默认值为true。当使用默认值或主动设置为true时,使用POSIX相关的接口,否则使用HalFiles相关的接口。如果使用HalFiles相关的接口,需要适配UtilsFile部件,参考之前的移植案例与原理文章即可。
{"subsystem": "utils","components": [{ "component": "file", "features":[] },
⑴ { "component": "kv_store", "features":[] }]}],
⑵ "vendor_adapter_dir": "//device/qemu/SmartL_E802/adapter",
1.2 适配后运行示例代码
适配后,编写如下代码,就可以使用KV存储功能。下面是示例代码程序片段,实现保存键值,通过key键获取对应的值,删除键值等等。
// 存储/更新key对应数据项
const char key1[] = "key_sample";
const char defValue[] = "test case of key value store.";
int ret = UtilsSetValue(key1, defValue);// 根据key获取对应数据项
char value1[32] = {0};
ret = UtilsGetValue(key1, value1, 32);// 删除key对应数据项
UtilsDeleteValue(key1);
2、KV存储部件kvstore_common通用代码
2.1 结构体、函数声明、变量
在文件utils\native\lite\kv_store\src\kvstore_common\kvstore_common.h中声明了KV存储的函数,并定义了结构体KvItem。⑴处定义了键值的最大长度,⑵处的FEATURE_KV_CACHE宏开关,定义在utils\native\lite\include\utils_config.h,默认是定义了该宏的。⑶处定义的结构体,成员包含键值,以及前驱后继结构体指针。
⑴ #define MAX_KEY_LEN 32#define MAX_VALUE_LEN 128boolean IsValidChar(const char ch);boolean IsValidValue(const char* value, unsigned int len);boolean IsValidKey(const char* key);⑵ #ifdef FEATURE_KV_CACHE
⑶ typedef struct KvItem_ {char* key;char* value;struct KvItem_* next;struct KvItem_* prev;} KvItem;void DeleteKVCache(const char* key);void AddKVCache(const char* key, const char* value, boolean isNew);int GetValueByCache(const char* key, char* value, unsigned int maxLen);int ClearKVCacheInner(void);#endif
在文件utils\native\lite\kv_store\src\kvstore_common\kvstore_common.c中定义了内部全局变量,g_itemHeader、g_itemTail分别指向键值链表的首尾,g_sum记录键值对数量。
#ifdef FEATURE_KV_CACHE
static KvItem* g_itemHeader = NULL;
static KvItem* g_itemTail = NULL;
static int g_sum = 0;
#endif
2.2 键值有效性判断函数
函数IsValidKey、IsValidValue分别用于判断键、值是否为有效的。⑴处表明键值必须为小写的字符,数值,下划线或者点符号。使用IsValidValue判断值是否有效时,需要传入2个参数,一个是要判断的字符串值的指针,一个是长度len。⑵处获取字符串的个数,包含最后的null;不超过最大长度MAX_VALUE_LEN。然后进一步判断,如果长度为0,长度大于等于最大长度MAX_VALUE_LEN(因为需要末尾的null,等于也不行),或者大于参数中传递的长度时,都会返回FALSE,否则返回TRUE。使用IsValidKey判断键是否有效时,先调用函数IsValidValue确保长度是有效的,然后调用函数IsValidChar判断每一个字符都是有效的,只能是小写字符,数值或者点符号。
boolean IsValidChar(const char ch){
⑴ if (islower(ch) || isdigit(ch) || (ch == '_') || (ch == '.')) {return TRUE;}return FALSE;}boolean IsValidValue(const char* value, unsigned int len){if (value == NULL) {return FALSE;}
⑵ size_t valueLen = strnlen(value, MAX_VALUE_LEN);if ((valueLen == 0) || (valueLen >= MAX_VALUE_LEN) || (valueLen >= len)) {return FALSE;}return TRUE;}boolean IsValidKey(const char* key){if (!IsValidValue(key, MAX_KEY_LEN)) {return FALSE;}size_t keyLen = strnlen(key, MAX_KEY_LEN);for (size_t i = 0; i < keyLen; i++) {if (!IsValidChar(key[i])) {return FALSE;}}return TRUE;}
2.3 根据键删除值DeleteKVCache
⑴处的函数FreeItem释放结构体成员变量指针,结构体占用的内存。函数DeleteKVCache用于删除键参数对应的值。⑵处从键值对头部的第一个键值开始,循环键值链表,比对参数中的键和循环到的键。如果不相等,则循环下一个链表节点。如果一直不相等,并且循环到的节点为NULL,说明链表中不存在相同的键,直接返回不需要执行删除操作。如果执行到⑶,说明键值对中存在匹配的键,键值对总数减去1。⑷处对删键值后的数量的各种情况进行判断,如果键值对数量为0,键值对首尾指针设置为NULL;如果删除的是队首元素,队尾元素,队中元素,分别处理。⑸处释放要删除的结构体占用的内存。
⑴ static void FreeItem(KvItem* item){if (item == NULL) {return;}if (item->key != NULL) {free(item->key);}if (item->value != NULL) {free(item->value);}free(item);}void DeleteKVCache(const char* key){if (key == NULL || g_itemHeader == NULL) {return;}⑵ KvItem* item = g_itemHeader;while (strcmp(key, item->key) != 0) {item = item->next;if (item == NULL) {return;}}
⑶ g_sum--;
⑷ if (g_sum == 0) {g_itemHeader = NULL;g_itemTail = NULL;} else if (item == g_itemHeader) {g_itemHeader = item->next;g_itemHeader->prev = NULL;} else if (item == g_itemTail) {g_itemTail = item->prev;g_itemTail->next = NULL;} else {item->prev->next = item->next;item->next->prev = item->prev;}
⑸ FreeItem(item);}
2.4 添加缓存AddKVCache
函数AddKVCache添加一对键值到缓存里。共三个参数,前两者为键和值;第三个参数boolean isNew为true时,会先尝试删除旧的键值对,只保留最新的键值数据。如果为false,可能存在键值相同的两个键值对,但是值不同。做完必要的参数非空校验后,执行⑴获取键、值的字符长度。⑵处处理是否删除旧的键值对数据。⑶处为键值对结构体申请内存区域,内存区域置空。⑷处为键、值分别申请内存区域,申请的时候多加1个字符长度用于保存null空字符。⑸处把参数传入的键值数据复制到键值对结构体对应的内存区域。⑹处理缓存内没有键值数据的情况。当缓存有键值信息时,新加入的放入键值对链表头部。⑻处当缓存数量大于最大缓存数时,依次从尾部删除。
void AddKVCache(const char* key, const char* value, boolean isNew)
{if (key == NULL || value == NULL) {return;}⑴ size_t keyLen = strnlen(key, MAX_KEY_LEN);size_t valueLen = strnlen(value, MAX_VALUE_LEN);if ((keyLen >= MAX_KEY_LEN) || (valueLen >= MAX_VALUE_LEN)) {return;}
⑵ if (isNew) {DeleteKVCache(key);}
⑶ KvItem* item = (KvItem *)malloc(sizeof(KvItem));if (item == NULL) {return;}(void)memset_s(item, sizeof(KvItem), 0, sizeof(KvItem));
⑷ item->key = (char *)malloc(keyLen + 1);item->value = (char *)malloc(valueLen + 1);if ((item->key == NULL) || (item->value == NULL)) {FreeItem(item);return;}
⑸ if ((strcpy_s(item->key, keyLen + 1, key) != EOK) ||(strcpy_s(item->value, valueLen + 1, value) != EOK)) {FreeItem(item);return;}item->prev = NULL;item->next = NULL;
⑹ if (g_itemHeader == NULL) {g_itemHeader = item;g_itemTail = item;g_sum++;return;}
⑺ item->next = g_itemHeader;g_itemHeader->prev = item;g_itemHeader = item;g_sum++;
⑻ while (g_sum > MAX_CACHE_SIZE) {KvItem* needDel = g_itemTail;g_itemTail = g_itemTail->prev;FreeItem(needDel);g_itemTail->next = NULL;g_sum--;}
}
2.5 从缓存中获取值GetValueByCache
函数GetValueByCache用于从缓存中读取值。共三个参数,前两者为键和值,const char* ke为键,输入参数;char* value为输出参数,用于保存返回的值;第三个参数unsigned int maxLen用于限制获取的值的最大长度。该函数的返回值代表获取成功EC_SUCCESS或失败EC_FAILURE。做完必要的参数非空校验后,执行⑴循环键值对链表,获取对应键的键值结构体。如果获取不到,则返回EC_FAILURE;否则,执行⑵获取值的长度,当这个长度超出值的最大长度时,返回EC_FAILURE。⑶处,如果获取的值的长度超出参数传入的长度,不会截断,而是返回错误。从item->value把值复制到输出参数里,如果失败也会返回错误。
int GetValueByCache(const char* key, char* value, unsigned int maxLen)
{if (key == NULL || value == NULL || g_itemHeader == NULL) {return EC_FAILURE;}KvItem* item = g_itemHeader;
⑴ while (strcmp(key, item->key) != 0) {item = item->next;if (item == NULL) {return EC_FAILURE;}}
⑵ size_t valueLen = strnlen(item->value, MAX_VALUE_LEN);if (valueLen >= MAX_VALUE_LEN) {return EC_FAILURE;}
⑶ if ((valueLen >= maxLen) || (strcpy_s(value, maxLen, item->value) != EOK)) {return EC_FAILURE;}return EC_SUCCESS;
}
2.6 清除缓存ClearKVCacheInner
清除缓存函数ClearKVCacheInner会把缓存的键值对全部清空,返回清除成功或失败的返回值。⑴如果键值对链表头节点为空,返回成功。⑵处循环键值对链表每一个键值对元素,一一删除。每删除一个,执行⑶,把基础缓存的键值对数目减1。
int ClearKVCacheInner(void)
{
⑴ if (g_itemHeader == NULL) {return EC_SUCCESS;}KvItem* item = g_itemHeader;
⑵ while (item != NULL) {KvItem* temp = item;item = item->next;FreeItem(temp);
⑶ g_sum--;}g_itemHeader = NULL;g_itemTail = NULL;return (g_sum != 0) ? EC_FAILURE : EC_SUCCESS;
}
如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:
OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy
《OpenHarmony源码解析》:https://qr18.cn/CgxrRy
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
系统架构分析:https://qr18.cn/CgxrRy
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy
OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy
写在最后
- 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:
https://qr21.cn/FV7h05
相关文章:

移植案例与原理 - utils子系统之KV存储部件 (1)
Utils子系统是OpenHarmony的公共基础库,存放OpenHarmony通用的基础组件。这些基础组件可被OpenHarmony各业务子系统及上层应用所使用。公共基础库在不同平台上提供的能力: LiteOS-M内核:KV(key value)存储、文件操作、定时器、Dump系统属性。…...

数据结构---排序算法
个人介绍 hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的…...

UE4 RPC进行网络同步
说明 基于UE本身提供的RPC同步机制 RPC远程过程调用允许客户端或服务器通过网络连接相互发送消息: 使用时需要注意: 1、必须从 Actor 上调用 2、Actor 必须被复制,注意勾选BP中Replicates,或使变量bReplicates true 3、注意如…...

HTML(6)——表单
目录 input标签基本使用 input标签占位 单选框radio 上传文件file 下拉菜单 文本域 label标签 按钮 input标签基本使用 input标签type属性值不同,则功能不同 <input type"..."> type属性值说明text文本框,用于输入单行文本p…...

Go基础编程 - 08 - 结构体
结构体 1. 自定义类型、类型别名1.1. 自定义类型1.2. 类型别名1.3. 类型定义和类型别名的区别 2. 结构体定义3. 结构体初始化4. 指针类型结构体5. 构造函数6. 方法和接收者6.1. 方法定义6.2. 方法调用6.3. 值方法和指针方法6.4. 指针方法使用场景6.5. 任意类型添加方法 7. 结构…...

基于Verilog表达的FSM状态机
基于Verilog表达的FSM状态机 1 FSM1.1 Intro1.2 Why FSM?1.3 How to do 在这里聚焦基于Verilog的三段式状态机编程; 1 FSM 1.1 Intro 状态机是一种代码实现功能的范式;一切皆可状态机; 状态机编程四要素:– 1.状态State&#…...

给一家银行做的数据中台系统架构方案书(DAMM)招投标用,虽然有内定潜规则,但是方案都是要的,不一定就是价格低就能中标,毕竟是上百万以上的单子
目录 概述需求分析系统架构DAMM设计思路数据治理数据安全实施计划维护和运营 1. 概述 1.1 项目背景 在数字化转型的浪潮中,银行业面临着越来越多的数据挑战与机遇。为了更好地利用数据资产,提升服务质量和运营效率,建立一个高效、灵活的数…...

【设计模式深度剖析】【6】【行为型】【中介者模式】
👈️上一篇:迭代器模式 | 下一篇:观察者模式👉️ 设计模式-专栏👈️ 文章目录 中介者模式定义英文原文直译如何理解? 中介者模式的角色1. 中介者(Mediator)2. 具体中介者(ConcreteMediato…...

金额转换但是接收对象类型未知时,金额转换公共方法囊括当对象为String\Integer\Number三种类型的转换方法
/** * deccription 金额转换方法 * param Object * value * return * return BigDecimal */ public BigDecimal getBigDecimal(Object value) { BigDecimal reValue new BigDecimal(0); if (value ! null) { …...

Commons-Collections篇-CC2链分析
前言 3.1-3.2.1版本中TransformingComparator并没有去实现Serializable接口,是不可以被序列化的,所以我们重新搭建一个4.0的具有漏洞的CC环境 CC2链主要使用的和CC4一样,但是区别在于CC2避免了使用Transformer数组,没有使用Insta…...

LeetCode 48.旋转图像
1.做题要求: 2.从此题我们可以看出规律为第几行要变为倒数第几列,所以我们最好先把二维数组存入一维数组中,然后先从最后一列遍历,把一维数组里的元素,依次等于遍历的元素即可: void rotate(int** matrix, int matrixSize, int*…...

Navicat导入json文件(json文件数据导入到MySQL表中)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

避雷!又6本期刊被On Hold!ELSEVIER旗下影响因子高达10+SSCI上榜
【SciencePub学术】继《INFORMATION SCIENCES》被On Hold 之后,又新增3本SCIE期刊、3本SSCI期刊被列入On Hold名单。其中包含ELSEVIER旗下影响因子高达10的《RESOURCES POLICY》。 官方现在对期刊质量的管控越来越严格了,被标记为On Hold后的期刊中&…...

CSS 列表样式(ul)全面解析
CSS 列表样式是前端开发中常用的一种技术,用于定义无序列表(ul)的外观和行为。无序列表在网页布局和内容展示中扮演着重要角色,从导航菜单到内容清单,无所不在。通过CSS可以对无序列表的各个方面进行自定义,…...

Python 库PySpark,一个超级强大的数据处理引擎
目录 01初识 PySpark 为什么选择 PySpark? 安装 PySpark 配置 PySpark 02基本操作 创建 RDD 基本 RDD 操作 03DataFrame 和 Spark SQL 创建 DataFrame 基本 DataFrame 操作 使用 Spark SQL 04机器学习与流处理 …...

UE4_材质_雨滴涟漪效果ripple effect_ben教程
学习笔记,不喜勿喷!侵权立删,祝愿生活越来越好! 雨水落下时会产生这些非常漂亮的同心环波纹,我们要做的第一件事是创建一个单个的圆环遮罩动画,我们希望环在开始的时候在中心很小,然后放大&…...

mac免费的ntfs软件哪个好 MAC读取NTFS硬盘格式
对于苹果用户来说,Mac电脑和移动硬盘已经成为日常工作中不可缺少的一部分,但有时我发现Mac打开移动硬盘只能读取无法写入,这是由于所连接的移动硬盘为NTFS格式。我们可以通过对硬盘格式化为Mac正常读写格式,或使用数据读写软件对N…...

轻兔推荐 —— who.cx
via:轻兔推荐 - https://app.lighttools.net/ 简介 who.cx是一个域名whois查询工具,界面简洁,可查询域名基本信息,注册续费价格,支持查看一级域名解析记录 - 对于已注册域名可以查看注册商注册时间、 过期时间等基础信…...

建筑幕墙甲级设计资质:申请条件与评分标准
建筑幕墙甲级设计资质的申请条件与评分标准可以清晰归纳如下: 申请条件 一、企业基本情况 独立企业法人资格:企业需具有独立企业法人资格。注册资本:注册资本不少于300万元人民币。 二、技术人员条件 主要技术负责人或总工程师ÿ…...

easy-es Map类型字段序列化问题:Unexpected character (‘n‘ (code 110)):
Data IndexName("demo") public class EasyEsDemo {IndexIdprivate String id;private String name;private int age;// 这个Map字段因为NameFilter过滤器,导致fastjson序列化后为{null:"value"}这种形式,insert报错private Map<…...

[Vue3:组件通信)子组件props接收和watch监听,emit发送父组件 (添加修改设置成绩,添加、删除选课记录)
文章目录 一:系统功能:设置成绩(添加或修改)交互逻辑:涉及页面 Page02.vue,ModalEdit.vue主页面Page.vue注入子页面,使用子页面标签属性主页面对子页面做通信,子页面ModalEdit接收参…...

【网络协议栈】IGMP
IGMP IGMP(Internet Group Management Protocol)是互联网组管理协议的简称,属于TCP/IP协议族中负责IPv4组播成员管理的协议。以下是关于IGMP的详细介绍: 1 定义与作用 定义:IGMP是多播组成员的一种通信协议…...

Python机器学习完整流程:从数据清洗到推理落地
目录 一、引言 二、数据清洗 数据加载与初步探索 缺失值处理 异常值处理 特征编码与转换 数据集划分 三、模型训练 四、模型文件生成 五、模型部署与推理落地 六、总结 一、引言 在当今数据驱动的时代,机器学习已成为解决复杂问题的有力工具。而…...

App上架和推广前的准备
众所周知,App推广的第一步是上架各大应用下载市场,然后才是其他推广渠道。所以本文主要分两部分,第一部分主要介绍的是上架各大应用市场方面的准备,第二部分主要介绍的是其他渠道推广方面的准备。 一、App上架前的准备 1.1 上架…...

一季度直播6000场,同比增长60%,遥望科技透露重要信息
6月17日,经由深圳证券交易所许可,遥望科技(股票代码:002291)正式对《年报问询函》进行公开回复,就经营的多个维度做出解释和回应。 在回复中,遥望科技预测2024年毛利率为14.4%,相比…...

电商API接口是什么意思?有什么作用?
电商API接口是电子商务领域中一种技术解决方案,它允许不同的软件系统之间进行交互和数据交换。 在电商场景下,电商API接口可以实现的功能非常丰富,例如: 商品管理:获取商品列表、商品详情、搜索商品、上下架商品等&a…...

Python爬虫实战案例之——MySql数据入库
Hello大家好,我是你们的南枫学长,咱们今天来学——爬虫之MySql数据入库。 话不多说,导入咱们的老朋友: Pymysql就是我们Python里面的mysql库,主要功能就是用来连接MySql数据库,那么下载还是一样的操作去进…...

游戏中插入音效
一、背景音乐 准备:素材音乐 方法: 1、方法1: (1) 将背景音乐 bgAudio 拖放到Hierarchy面板 (2) 选中 bgAudio,勾选开始运行就播放、循环播放。调节音量(volume) 2、方法2: (1) Create Empty&#x…...

Redis缓存设计之常见问题及解决方案
背景:缓存的常见问题及对应的解决方案进行了整理,给大家分享一下。 1.缓存穿透 缓存穿透是指查询一个根本不存在的数据, 缓存层和存储层都不会命中, 通常出于容错的考虑, 如果从存储 层查不到数据则不写入缓存层。 缓…...

简单的线程池示例
线程池可以有效地管理和重用线程资源,避免频繁创建和销毁线程带来的开销。以下是一个简单的线程池示例。 cpp #include <iostream> #include <vector> #include <thread> #include <queue> #include <mutex> #include <condition…...