一、驱动层:SFUD(Serial Flash Universal Driver) 是一款开源的串行 SPI Flash 通用驱动库
二、中间层:FAL(FLASH ABSTRACTION LAYER))FLASH 抽象层
三、应用层:FlashDB(FlashDB 是一款超轻量级的嵌入式数据库)
后记1:FlashDB嵌入式数据库之TSDB数据存储解析


FlashDB之TSDB解析

  • 一、初始化过程记录
  • 二、Flash中的存储格式
  • 三、实际使用率计算
  • 四、查询流程
  • 五、补充:性能测试

写在前面,好久才来写这边文章,读源码还是比较累的,先记录下来后期会议的时候方便一点。

一、初始化过程记录

先看一下帧头结构体

struct sector_hdr_data {uint8_t status[FDB_STORE_STATUS_TABLE_SIZE]; /**< sector store status @see fdb_sector_store_status_t */uint32_t magic;                              /**< magic word(`T`, `S`, `L`, `0`) */fdb_time_t start_time;                       /**< the first start node's timestamp */struct {fdb_time_t time;                         /**< the last end node's timestamp */uint32_t index;                          /**< the last end node's index */uint8_t status[TSL_STATUS_TABLE_SIZE];   /**< end node status, @see fdb_tsl_status_t */} end_info[2];uint32_t reserved;
};

根据计算sizeof(struct sector_hdr_data)= 40bytes
根据注释可以看出来,帧头中存储了扇区的状态、关键字、开始时间、结束时间、和预留了一个32位的数这样就可以实现对单个扇区的快速检索,
只需要读取头部的40个字节,就可以快速判断扇区是否已存满,扇区中的数据的开始时间和结束时间,如果需要检索数据本扇区中的数据是否符合条件,当然前提是时间戳是连续的,这个是默认条件。

二、Flash中的存储格式

源代码调用的层次很多,我们直接讲结果,有兴趣的自己看源码,都是开源的。

可以看到帧头后面紧跟着的是数据头信息,每条数据头信息由16个字节组成

  • 数据头信息 = 数据状态 + 数据时间戳 + 数据长度 + 数据内容起始地址
  • 这样的好处是数据头信息是固定长度和固定位置的,可以方便我们快速根据时间戳检索,数据的内容是可以不定长的。
  • log内容用指针指向特定的地址,长度就不需要固定的
  • 每个扇区单独成块,就是一个最小的数据库单元
扇区头 log1_hdr log2_hdr 剩余空间 剩余空间 log2_data log1_data

可以看到log1的数据头指向的数据内容在扇区的最后面,log2指向的内容再次后面,二边向中间挤压

三、实际使用率计算

每条记录固定占用空间为16字节

如果你的数据内容是16字节
实际使用率 = 16/(16+16) = 50%

一个扇区可以储存数量 = (4096 - 40) / 16 + 16 = 126(条)

1M FLASH有扇区数量 = 1M / 4096 = 256 (个)
1M FLASH可以存储数据 = 126*256 = 32256(条)
如果你的flash是8M的自己算一下。

四、查询流程

原生的api接口只有一个按时间查询的命令

/*** The TSDB iterator for each TSL by timestamp.** @param db database object* @param from starting timestap* @param to ending timestap* @param cb callback* @param arg callback argument*/
void fdb_tsl_iter_by_time(fdb_tsdb_t db, fdb_time_t from, fdb_time_t to, fdb_tsl_cb cb, void *cb_arg)
{struct tsdb_sec_info sector;uint32_t sec_addr, oldest_addr = db->oldest_addr, traversed_len = 0;struct fdb_tsl tsl;bool found_start_tsl = false;if (!db_init_ok(db)) {FDB_INFO("Error: TSL (%s) isn't initialize OK.\n", db_name(db));}//    FDB_INFO("from %s", ctime((const time_t * )&from));
//    FDB_INFO("to %s", ctime((const time_t * )&to));if (cb == NULL) {return;}sec_addr = oldest_addr;/* search all sectors */do {if (read_sector_info(db, sec_addr, §or, false) != FDB_NO_ERR) {continue;}/* sector has TSL */if ((sector.status == FDB_SECTOR_STORE_USING || sector.status == FDB_SECTOR_STORE_FULL)) {if (sector.status == FDB_SECTOR_STORE_USING) {/* copy the current using sector status  */sector = db->cur_sec;}if ((!found_start_tsl && ((from >= sector.start_time && from <= sector.end_time)|| (sec_addr == oldest_addr && from <= sector.start_time))) || (found_start_tsl)) {uint32_t start = sector.addr + SECTOR_HDR_DATA_SIZE, end = sector.end_idx;found_start_tsl = true;/* search start TSL address, using binary search algorithm */while (start <= end) {tsl.addr.index = start + ((end - start) / 2 + 1) / LOG_IDX_DATA_SIZE * LOG_IDX_DATA_SIZE;read_tsl(db, &tsl);if (tsl.time < from) {start = tsl.addr.index + LOG_IDX_DATA_SIZE;} else {end = tsl.addr.index - LOG_IDX_DATA_SIZE;}}tsl.addr.index = start;/* search all TSL */do {read_tsl(db, &tsl);if (tsl.time >= from && tsl.time <= to) {/* iterator is interrupted when callback return true */if (cb(&tsl, cb_arg)) {return;}} else {return;}} while ((tsl.addr.index = get_next_tsl_addr(§or, &tsl)) != FAILED_ADDR);}} else if (sector.status == FDB_SECTOR_STORE_EMPTY) {return;}traversed_len += db_sec_size(db);} while ((sec_addr = get_next_sector_addr(db, §or, traversed_len)) != FAILED_ADDR);
}

就是从起始时间查询到结束时间,提供了一个回调接口,在这个接口中把数据显示在LCD屏上。

五、补充:性能测试

单纯的速度测试我没有做,原文给出了大概的速度,而且也没有实际的使用价值。
原文给的速度

msh />tsl bench
Append 13421 TSL in 5 seconds, average: 2684.20 tsl/S, 0.37 ms/per
Query total spent 1475 (ms) for 13422 TSL, min 0, max 1, average: 0.11 ms/per

我的环境是 STM32F4+TSDB+FATFS+U盘(USB_Host)
导出了10W条速度用时1分35秒(实际工程中测试)

导出至USB ≈ 1052per/s,差距还是挺大的。

FlashDB嵌入式数据库之TSDB数据存储解析相关推荐

  1. FlashDB嵌入式数据库

    一.驱动层:SFUD(Serial Flash Universal Driver) 是一款开源的串行 SPI Flash 通用驱动库 二.中间层:FAL(FLASH ABSTRACTION LAYER ...

  2. tinyFlash:一种超轻量级的嵌入式单片机flash KV 数据存储方案

    tinyFlash 一种超轻量级的flash KV数据存储方案 Github 地址:https://github.com/ospanic/tinyFlash 设计原理 本方案采用两个扇区轮流使用的方法 ...

  3. graphite 数据库_大数据存储和分析-IBM DB2和Graphite

    在本文中,我们将结合IBM™Persistence API使用IBM DB2作为数据源,描述PCC系统中的数据存储. 此外,我们讨论了如何使用Graphite来检测代码库和工作负载. 最后,我们描述了 ...

  4. 数据库技术:数据存储和查询知识笔记

    1.存储管理器 存储管理器作用:负责数据库中数据的存查询和更新.存储管理器负责和文件系统交互,将不同的DML语句翻译成底层文件系统命令,通过这种方式原始数据就通过文件系统存储在磁盘上. 存储管理器是存 ...

  5. flutter可以用 mysql数据库_Flutter 本地数据存储(文件、SharedPreferences 、数据库 sqlite)使用示例...

    Flutter 提供了三种数据持久化方法,即文件.SharedPreferences 与数据库. 文件 Flutter 提供了两种文件存储的目录,即临时(Temporary)目录与文档(Documen ...

  6. Python3,网站搭建之数据库表设计及数据存储!文末的彩蛋,我酸了~

    搭建自己的网站,是作为一个码农成功标志之一, 那其他成功标志有啥呢, 嘿- 左手搂着白富美,右手撸着小烧烤,脚底踩着桑塔纳- 嗯~ 这么潇洒的人生,就从数据库表设计及数据存储开始吧! 数据库表设计及存 ...

  7. 数据存储之 SQLite 数据库操作(三)

    上一讲中我们讲到了SQLite数据库的操作方法 [数据存储之SQLite数据库操作(二)],我们主要是以SQL语句对数据库进行增删改查,这一讲我们来学习一下 Android 建议的对数据库的操作方法 ...

  8. 数据存储之 SQLite 数据库操作(二)

    上一讲我们讲解了SQLite数据库的创建[数据存储之 SQLite 数据库操作(一)],还有更新的操作,这一讲我们来讲解一下数据库的增删改查,这边的程序是对上一个程序进行修改,建议结合上一讲内容进行学 ...

  9. 嵌入式数据库与数据库服务器

    转自:http://blog.csdn.net/gobitan 初次接触嵌入式数据库(Embedded Database)可能对这个概念总不是很清楚,它究竟与数据库服务器(Database Serve ...

最新文章

  1. 打算看的书或正在看的书
  2. 【Tools】cmake 常用变量和常用环境变量查表手册---整理
  3. 联想20年的45条成功法则
  4. nodejs服务端MVC架构介绍
  5. dbgrid的最小高度设置。否则出现滚动条。
  6. Gartner 发布2022年数据分析十二大趋势:数据和分析将成为创新起源
  7. oracle存储过程入门之hello world
  8. PKD-Bert:基于多层网络的Bert知识蒸馏
  9. 学习WPF/Silverligter网站及资源
  10. 如何理解P40采用RYYB比RGGB的感光能力提升40%
  11. 三步教你制作拼多多优惠券cms网站系统的返利功能
  12. Request请求转发
  13. 小米原装系统镜像列表
  14. VirtualBox 磁盘扩容(亲测有效)
  15. ARM嵌入式实验 熟悉PROTEUS电子仿真软件的使用(LPC2138)
  16. oracle数据库rank over用法,Oracle 中rank() over()的用法
  17. 2021-02-17:规定1和A对应、2和B对应、3和C对应...26和Z对应,那么一个数字字符串比如“111”就可以转化为:“AAA“、“KA“和“AK“。给定一个只有数字字符组成的字符串str,请
  18. Fisher's exact test( 费希尔精确检验)
  19. 金山 V8 终端安全系统 默认弱口令漏洞
  20. PCB学习笔记——如何改变图纸大小

热门文章

  1. 广工计算机组成原理实验,广工计算机组成原理实验(一二三四五六七九)
  2. 阿里云解析是什么?有什么用?
  3. 转载 书籍推荐-记这几年看的书
  4. python人脸识别demo
  5. 深度理解GCD线程死锁,队列,同步和异步,串行和并发
  6. 网卡扫盲三:以太网芯片MAC和PHY的关系
  7. vb 运行错误429 mysql_Win7运行VB提示“运行时错误429 ActiveX部件不能创建对象”怎么办...
  8. MySQL8.0安装程序在安装此包时遇到意外错误。这可能表明这个包有问题。错误码是2503。
  9. 2023新华为OD机试题 - 箱子之形摆放(JavaScript)
  10. C语言实现矿井逃生游戏(附完整源码)