为了解决大规模数据有序索引查询问题, 并且需要实现删除功能, 而且主要运行在嵌入式系统, 还需要快速索引大量数据, 所以设计这个数据库.
- 添加数据
- 删除数据
- 查询数据
- 循环覆盖写入
typedef enum mpdb_err{
MpdbErr_ERROR = -100, // 通用错误
MpdbErr_VERSION, // 版本错误
MpdbErr_INIT, // 初始化错误
MpdbErr_NULL, // 空错误
MpdbErr_HEAD, // 数据库头错误
MpdbErr_OK = 0, // 无错误
}MpdbErr;移植接口, 需要对接Flash操作 快操作大小4K
// 读取接口
MpdbErr Mpdb_read_port(u32 addr, u8 *data, u32 data_size);
// 写入接口
MpdbErr Mpdb_write_port(u32 addr, u8 *data, u32 data_size);
// 擦除接口
MpdbErr Mpdb_erase_port(u32 addr, u32 data_size);
// 获得Flash的大小
u32 Mpdb_capacity_port();
// 擦除所有块
MpdbErr Mpdb_erase_all_port();
// 数据导出操作, 打开输出
MpdbErr Mpdb_export_open_port();
// 输出数据
MpdbErr Mpdb_export_write_port(u32 addr, u8 *data, u32 data_size);
// 结束, 释放资源
void Mpdb_export_close_port();typedef enum mpdb_query_mode{
MpdbQueryMode_NORMAL, //普通模式
MpdbQueryMode_FAST //快速模式
}MpdbQueryMode;- 普通模式: 全部功能的模式
- 快速模式: 删除功能不生效, 减去查询数据删除标志位的时间, 能将数据查询速度达到算法最快, 数据结构兼容, 普通模式删除的数据在快速模式中查询到.
// 数据库初始化操作
MpdbErr Mpdb_init(Mpdb* mpdb, MpdbQueryMode query_mode);
// 添加数据
MpdbErr Mpdb_add(Mpdb* mpdb, void* data);
// 获得数据库中的数据数量
u32 Mpdb_count(const Mpdb *const mpdb);
// 获得数据能保存多少数据
u32 Mpdb_capacity(const Mpdb *const mpdb);
// 数据库定位
MpdbErr Mpdb_positioning(Mpdb* mpdb, u32 index, MpdbItarContext *context);
// 配合定位操作读取位置的数据, 运行完成后定位会自增一移动, 多次调用实现数据迭代获取
MpdbErr Mpdb_get(Mpdb *const mpdb, MpdbItarContext *context, void *data);
// 删除数据
MpdbErr Mpdb_delete(Mpdb* mpdb, u32 index);
// 数据库复位
MpdbErr Mpdb_reset(Mpdb* mpdb, u32 data_size);
// 数据库导出
MpdbErr Mpdb_export(Mpdb* mpdb);结合Flash块操作的特点来管理数据库
数据库结构:
数据库使用一个块来保存数据库通用状态, 其中比较特别的是 1000个寄存器 它是用来保存下一条数据保存的索引, 提高添加速度, 1000个寄存器只是为了均衡磨损, 延长Flash寿命
每个数据块都有一个头, 保存这个块的状态, 其中保存这块中是否有删除数据, 数据标志寄存器有31byte的空间, 所以在数据块中保存的数据不能太小, 不然数据标志寄存器不够使用. 整个头32byte, 数据库查询只需要查询这个头即可, 不需要扫描数据, 从而提升速度
循环写入的实现方法是有一个数据块标记为数据块头, 在查询中根据这个块的索引偏移查询, 当数据写满时, 数据库会擦除最老的数据块写入数据, 并把第二老的块标记为头