如何做一个国产数据库(二)
如果做一个国产数据库一链接
承接上文,继续
1、重新定义数据结构
typedef struct sdata
{uint32_t index;char vardata[128];
}sdata;typedef struct sdata_index
{uint32_t index;uint32_t offset;
}sdata_index;
sdata_index 是我们要读到一个内存里面去的,同时,我们会使用内存查找的方式,拿到数据的索引值,在内存里面使用二分查找算法
int binSearch(uint32_t x, sdata_index *a, int n)
{int low, high, mid;low = 0;high = n - 1;while (low <= high){mid = (low + high) / 2;if (x < a[mid].index)high = mid - 1;else if (x > a[mid].index)low = mid + 1;elsereturn mid;}return -1;
}
2、写入数据
修改上一文章中的写函数,数据结构,偏移量计算正确,写入文件,写入的数据在进入函数之间一定要排序
//sdata 必须是排序后数据
//2M 的索引,一半的空间为索引号码,一半的空间为数据偏移地址
// 1024*1024/sizeof(int)
int bfile_write(const char * file,/*uint32_t index_num,*/ sdata data[],int n)
{#define INDEX_BYTES 2 * 1024 * 1024int index_num = INDEX_BYTES / sizeof(int)*2; //max index number is 162144if (n > index_num)return -1;FILE * fp = fopen(file, "wb");if (fp == NULL)return -1;fpos_t pos_start = 0;fpos_t pos_index = 8;fpos_t pos_data = pos_index + INDEX_BYTES;fpos_t position = 4 + 4 + INDEX_BYTES + sizeof(data[0].vardata) * n;fsetpos(fp, &position);fsetpos(fp, &pos_start);//写入总索引量fwrite(&index_num, sizeof(int), 1, fp);//写入目前索引量fwrite(&n, sizeof(int), 1, fp);//排序写入文件,已经排好了序号//std::sort(&data[0], &data[n], Rule());int offsetsum = 4+4+INDEX_BYTES;int len = sizeof(data[0].vardata);for (int i = 0; i < index_num; i++){//wnum++;if (i < n){fwrite(&data[i].index, sizeof(int), 1, fp);fwrite(&offsetsum, sizeof(int), 1, fp);offsetsum += len;}else{uint64_t flag = 0;fwrite(&flag, sizeof(uint64_t), 1, fp);}}offsetsum = 4 + 4 + INDEX_BYTES;fpos_t pos = offsetsum;for (int i = 0; i < n; i++){fsetpos(fp,&pos);fwrite(&data[i].vardata, strlen(data[i].vardata), 1, fp);pos += sizeof(data[0].vardata);}fclose(fp);return 0;
}
读取数据
定义读的函数,流程为
1 、读出数据最大索引量
2 、读出数据当前记录索引量
3 、读出索引放入内存
这里并不读数据集,后面第三篇再修正读数据,放一部分数据到内存里面。
//2M的空间做索引
sdata_index* bfile_read_index(const char * file,uint32_t &num)
{size_t nr;num = 0;uint32_t indext;//索引总长度uint32_t indexn;//索引长度,内容为x个索引 indexn <= indextFILE * fp = fopen(file, "rb");if (fp == NULL)return NULL;//读取最大的index值容量nr = fread(&indext, sizeof(uint32_t), 1, fp);if (nr == 0){fclose(fp);return NULL;}//读取存储的索引值nr = fread(&indexn, sizeof(uint32_t), 1, fp);if (nr == 0){fclose(fp);return NULL;}num = indexn;//4字节索引号 4字节偏移地址uint8_t * index = (uint8_t*)malloc(indexn * sizeof(uint32_t)*2);nr = fread(index, indexn * sizeof(uint32_t) * 2, 1, fp);if (nr == 0){fclose(fp);free(index);return NULL;}return (sdata_index*)index;
}
定义从数据库中读取某一个索引值到内存中
int bfile_read(const char * file,uint32_t offset, char *buffer,size_t len)
{FILE * fp = fopen(file, "rb");fpos_t pos_start = offset;fsetpos(fp, &pos_start);size_t n =fread(buffer, sizeof(char)*len, 1, fp);fclose(fp);if (n != len)return -1;return 0;
}
4、定义主函数执行
int main()
{sdata data[100];//srand(1000);for (int i = 0; i < 100; i++){//模拟收集到的数据data[i].index = i;sprintf(data[i].vardata, "the data is %ld", data[i].index);}//std::sort(&data[0], &data[100], Rule());for (int i = 0; i < 100; i++){cout<<data[i].index<<"-->"<<data[i].vardata << endl;}bfile_write("./test.db", data, 100);uint32_t num;sdata_index *rdata =bfile_read_index("./test.db",num);cout << "the index number is " << num << endl;cout << "now read the value of index x" << endl;string s;cin>>s;int v = atoi(s.c_str());int ret = binSearch(v, rdata, num);sdata_index *p = rdata;p += ret;uint32_t offset = p->offset;char buffer[128];bfile_read("./test.db", offset, buffer, 128);cout << buffer << endl;return 0;
}
5、执行插入数据函数结果打印
查看文件已经写入
6、数据查询
输入数据查询值,如89,意思是查询第89索引的值,
首先获取内存索引中偏移量的值offset,查询的时候使用binSearch 二分查找
最后打开文件,偏移到offset处,取出拷贝里面的值,打印出 the data is 89
一个小型的数据库就这样出来了,简陋,暂时是示例,会慢慢补充起来。等待我的第三篇吧
如何做一个国产数据库(二)相关推荐
- 如何做一个国产数据库(七) 网络传输 java做订阅客户端
如何做一个国产数据库一 如何做一个国产数据库二 如何做一个国产数据库三 如何做一个国产数据库四 如何做一个国产数据库五 如何做一个国产数据库六 server端协议定义 再次强调一下我们的protoco ...
- 如何做一个国产数据库(六) 网络传输 nodejs做测试客户端
如何做一个国产数据库一 如何做一个国产数据库二 如何做一个国产数据库三 如何做一个国产数据库四 如何做一个国产数据库五 网络实战服务器 我们再四中说过使用tcp进行协议的链接,对我们所定义的协议如果有 ...
- 如何做一个国产数据库(三)
一和二 如何做一个国产数据库一 如何做一个国产数据库二 1.数据结构重新定义 再次重新定义数据结构 typedef struct sdata {uint32_t index;char vardata[ ...
- 如何做一个国产数据库(四)
网络 这次要用到网络了,存储的时候我们都使用网络来输入输出,当然,像本机是可以使用进程间通信的,不过为了简单,我们此次都使用tcp协议. 协议 此次使用libuv来做网络的传输,我们首先定一个协议,做 ...
- 如何做一个国产数据库系统(一)
做国产数据库之二 做一个国产数据库 做一个数据库系统真的是要懂的是基础,各种基础,网络,文件系统,操作系统,性能,测试,各方面都要懂 使用基本方法 索引文件+数据文件+ B+ 树 ,hash空间 如图 ...
- 用python制作二维码_用python做一个可视化生成二维码的工具
用python做一个可视化生成二维码的工具 环境 pip install gooey pip install MyQR 源代码 from gooey import GooeyParser,Gooey ...
- 练习mvc做一个知识库(二)
上周发表了练习"mvc做一个知识库(一)".首先谢谢大家的关注,这两天有时间就看一下园子里小燕的走向ASP.NET架构设计.写的不错,对于像我这样想提高设计能力的菜鸟来说受益匪浅. ...
- 如何用Excel做一个战斗模拟器(二)属性表
如何用Excel做一个战斗模拟器(一)升级经验表 如何用Excel做一个战斗模拟器(三)战斗过程模拟 目录索引 属性表 属性表 首先确定人物的生命.攻击.防御.暴击值与闪避值属性.用公式将其设定为与等 ...
- 如何做一个mysql数据库_如何创建一个简单的mysql数据库
这篇文章主要介绍了操作MySQL日志的一些方法,对日志的删除操作做了重点讲解,需要的朋友可以参考下. 一.创建数据库 注:已经安装好mysql. windows下运行cmd进入命令窗口,本人用的是wi ...
最新文章
- 单点登录(SSO)—简介
- C#关于MSMQ通过HTTP远程发送专有队列消息的问题
- 使用sqoop将HIVE中的数据输出带Mysql中
- iptables端口转发命令
- 前端学习(2603):跨域请求的原因
- 简述java的线程_Java多线程的简述
- 收到字节 Offer,月薪 45k,揭秘面试流程及考点
- 13.字符串,结构,联合
- matmul torch 详解_python基础教程详解torch.Tensor的4种乘法
- 阿里云运行python_阿里云运行python代码
- ArcGis-学习笔记6-4 空间插值简介
- Windows正在配置Xftp6在下面的框输入包含安装程序包“Xftp 6.msi“的文件夹的路径
- Android View 获取焦点
- 【调剂】中科院天津工业生物技术所与天津科技大学联合培养硕士招生2023
- 橙色优学:互联网对传统行业说是机会,对年轻人来说更是风口
- 区块链10年兴衰录:中国是最好的发展土壤
- Linux的起源:从一个故事说起
- css div水平垂直居中
- mac之把打开终端设置快捷键为Ctrl+Alt+T
- 【听】你会杀死那个胖子吗?功利与道德的选择