键值对存储 (KV)

概述

KV存储系统是YOC中一个以Key-Value方式进行持久化存储的轻量级组件,主要为基于nor flash的小型MCU设备提供通用的Key-Value持久化存储接口。该系统采用极小的代码及内存开销,支持断电保护、磨损均衡等功能。

KV存储系统支持只读模式与读写模式共存,只读模式可以用于工厂生产数据,读写模式可用于运行时的数据存储。

断电保护特性

断电保护的设计是为了在修改KV时,能保证KV不会被破坏的事务处理机制,即要写入失败,要么写入成功,对于已经存的KV,写失败后,KV的值仍然为旧值。对于不存在的KV,写失败后,KV不存在。

磨损均衡特性

在通常的应用中,部分KV被经常修改,由于FLASH物理特性,擦写的次数有一定的限制,擦写次数超过次数时,该块会损坏不能使用。磨损均衡的设计是将KV的写入分散到多 block上,避免存储在固定的位置上,达到磨损均衡的效果。磨损均衡主要依赖以下两个策略来实现:

  • 异地更新策略

    Key-Value键值对采用顺序写入、异地更新的方式,即不再在原存储位置擦除重写,而是在其余空闲位置写入新键值并将原键值标记无效等待回收。这样既可以减少flash的擦除操作次数,又可以提高flash的空间利用率,也避免了对“特定”存储区块过度使用的问题。

    示意图如下:

  • 垃圾回收策略

    当free block总数接近gc下限时,会触发gc操作。flash数据在gc前,存在有效键值和无效键值交织的情况;gc后,把有效文件数据归并到free block,原区域则被擦除并置入free block。gc循环向后搬运键值。

    示意图如下:

坏块处理特性

Nor flash有一定的擦写次数限制,如果达到这个限制,或者由于物理方面的损坏,会导致这些block写入有问题。KV系统采用直接片上链式读取,擦除与写入时校验数据正确性,不采用特殊的标识信息来处理坏块,当 block 擦除失败或者写失败后,会重新申请新的数据块,避免坏块被错误使用。

接口定义

初始化kv系统

int aos_kv_init(const char *partname)
  • 参数

    • partname:分区名称
  • 返回值

    • 0:成功
    • -1:失败

初始化kv系统

int aos_kv_flash_init(const char *flashname, int addr, int block_num);
  • 参数

    • flashname:FLASH名称
    • addr:起始地址
    • block_num:块数目(KV项数目)
  • 返回值

    • 0:成功
    • -1:失败

恢复kv初始化值

int aos_kv_reset(void)
  • 参数

  • 返回值

    • 0:成功
    • -1:失败

设置KV数据

若key不存在添加,已经存在进行覆盖

int aos_kv_set(const char *key, char *value, int len, int sync)
  • 参数
    • key:键值
    • value:写入数据的缓存区
    • len:写入数据长度
    • sync:同步标识符,保留参数,请传入1
  • 返回值
    • 0:成功
    • -1:失败

设置KV字符串数据

若key不存在添加,已经存在进行覆盖

int aos_kv_setstring(const char *key, const char *v);
  • 参数
    • key:键值
    • v:写入的字符串
  • 返回值
    • 大于0:成功
    • -1:失败

设置KV浮点数据

若key不存在添加,已经存在进行覆盖

int aos_kv_setfloat(const char *key, float v);
  • 参数
    • key:键值
    • v:写入的浮点数据
  • 返回值
    • 0:成功
    • -1:失败

设置KV整型数据

若key不存在添加,已经存在进行覆盖

int aos_kv_setint(const char *key, int v);
  • 参数
    • key:键值
    • v:写入的整型数据
  • 返回值
    • 0:成功
    • -1:失败

获取KV key键的数据

int aos_kv_get(const char *key, void *buffer, int *buffer_len);
  • 参数
    • key:键值
    • buffer:读取数据的缓存区
    • buffer_len:输入buffer长度,输出实际数据长度
  • 返回值
    • 0:成功
    • -1:失败

获取KV key键的字符串数据

KV系统无类型标志,调用者需要确认读写类型对应

int aos_kv_getstring(const char *key, char *value, int len);
  • 参数
    • key:键值
    • value:读取数据的缓存区
    • len:缓存区长度,若长度小于实际数据长度,截断后返回
  • 返回值
    • 大于0:返回KV中数据的实际长度,若返回值大于等于len,说明数据还有未被读取
    • 小于等于0:失败

获取KV key键的浮点数据

KV系统无类型标志,调用者需要确认读写类型对应

int aos_kv_getfloat(const char *key, float *value);
  • 参数
    • key:键值
    • value:读取数据的缓存区
  • 返回值
    • 0:成功
    • -1:失败

获取KV key键的整型数据

KV系统无类型标志,调用者需要确认读写类型对应

int aos_kv_getint(const char *key, int *value);
  • 参数
    • key:键值
    • value:读取数据的缓存区
  • 返回值
    • 0:成功
    • -1:失败

删除指定的KV数据

int aos_kv_del(const char *key);
  • 参数
    • key:键值
  • 返回值
    • 0:成功
    • -1:失败

results matching ""

    No results matching ""