实现了一个简单的key-value存储系统
实现了一个简单的key-value存储系统
源码下载:

正文:
所谓的Key-Value就是每次存储一个数据时,是根据Key进行索引存储的。为了实现Key的快速查找功能,我使用了B-tree存储结构。B-tree被大量用于数据库的索引中,所以选用B-tree想必不会有太大的问题。Value是对应该Key的值,他的长度是未知的,所以要实现这样一个存储系统,必须要解决从Key值到文件位置的映射关系。
问题一:实现文件的"自由"读写
问题二:实现BTree
问题一:实现文件的"自由"读写。
基本思想:所有内容被存储到一个文件中,文件被划分成同一大小的粒度,可以自由的申请不同的大小空间,可以释放已经申请的空间。使得文件操作可以和内存操作接口一致。
基于上述的需求,我的文件存储结构如下图所示:


1 typedef struct _diskatom{
2 int64 self; //自身索引
3 int64 next; //下一索引
4 int64 pre; //前一索引
5 int64 ext; //扩展索引
6 int size; //大小
7 unsigned char info; //信息[1:HEAD|1:USED|0|0|0|0|0|0]
8 unsigned char dirty;
9 unsigned char data[DISK_ALLO_SIZE];
10 }diskatom_t;
11
12 typedef struct _diskctx{
13 int64 ctxtop;
14 int64 num_used;
15 int64 num_free;
16 diskatom_t list_used;
17 diskatom_t list_free;
18 }diskctx_t;

申请空间:
1. 计算申请大小需要几块空间。
2. 检查空闲列表中是否有足够的空间。
3. 存在足够的空闲块,将空闲块移动至"使用列表"。
4. 空闲空间不足,扩充文件大小,将新增块插入"使用列表"。
释放空间:
正好和申请空间相反。
1. 将使用块移动至"空闲列表"。使得该块可以被重新申请。
处理申请空间和释放空间外,还实现了读,写,重新申请空间功能。
问题二:实现BTree
摘录百科百科对BTree的描述:
B-tree(多路搜索树,并不是二叉的)是一种常见的数据结构。使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。按照翻译,B通常认为是Balance的简称。这个数据结构一般用于数据库的索引,综合效率较高。
http://baike.baidu.com/view/363832.htm
我们有了上面(问题一)的读写文件的功能,那么将B-tree建立到文件中去,和将之建立到内存,其实是一样的。B-tree的内容在网上都可以找到。只不过在操作节点的内容时,我们可能要去读写文件。原来在内存中的指针,现在变成了在文件中的位置。
测试功能:
现在软件实现了以下的功能,用于操作Key-value数据库。在效率方面,写1万个数据大致在350ms吧,查找读取的速度比写快一倍左右;由于是直接写硬盘,没有缓存机制,效率也只能这样。先把功能实现了再优化吧。
open( dbpath ) 打开一个数据库
set( container, key, value ) 增加/设置一个Key
get( container, key ) 获取一个Key的内容
del( container, key ) 删除一个Key
close( ) 关闭一个数据库
实现了一个简单的key-value存储系统的更多相关文章
- 一个简单需求:HashMap实现相同key存入数据后不被覆盖
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 看似是一个简单的问题,其实里面包含很多的东西! 需求: 实现一个在HashMap中存入(任意类型)相同的key值后,key ...
- Key/Value存储系统etcd的特性
etcd 是一个高可用的Key/Value存储系统,和其他KV存储系统不同的是,它的灵感来自于 ZooKeeper 和 Doozer,主要用于分享配置和服务发现.利用 etcd 的特性,应用程序可以在 ...
- perl 引用(数组和hash引用) --- perlreftut - Mark 的一个简单的'引用'教程 ---Understand References Today. --Mark Jason Dominus, Plover Systems (mjd-perl-ref+@plover.com)
https://blog.csdn.net/fangwei1235/article/details/8570886 首页 博客 学院 下载 论坛 APP 问答 商城 活动 VIP会员 招聘 ITeye ...
- 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
- 使用MongoDB和JSP实现一个简单的购物车系统
目录 1 问题描述 2 解决方案 2.1 实现功能 2.2 最终运行效果图 2.3 系统功能框架示意图 2.4 有关MongoDB简介及系统环境配置 2.5 核心功能代码讲解 ...
- IDA的脚本IDC的一个简单使用
目的:主要是想学习一下IDA的IDC的脚本的使用.这里做了一个小的测试. 这里使用的是VS2015Community来生成文件的. 一.编写测试程序: 这里先生成我们的目标数据. 然后编写测试程序.得 ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 使用lua实现一个简单的事件派发器
设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lu ...
- 一个简单的 MVVM 实现
简介 一个简单的带有双向绑定的 MVVM 实现. 例子 使用 新建一个 ViewModel 对象, 参数分别为 DOM 元素以及绑定的数据即可. 指令 本 MVVM 的指令使用 data 数据, 即 ...
随机推荐
- [Phonegap+Sencha Touch] 移动开发34 gem安装compass,不编译scss,怎么办?
很多人已经发现,今天,该命令 "gem install compass" 安装compass,正在使用 "compass compile" 编scss的时间将报 ...
- [CLR via C#]1.6 Framework类库~1.9与非托管代码的互操作性
原文:[CLR via C#]1.6 Framework类库~1.9与非托管代码的互操作性 1.6 Framework类库 1. .NET Framework中包含了Framework类库(Frame ...
- cfs
转自:http://www.cnblogs.com/openix/p/3254394.html 下文中对于红黑树或链表组织的就绪队列,统称为用队列组织的就绪队列. ...
- ExtJs--15--Ext.is*各种类型推断的方法,简单看源代码就能够明确了
/** * Returns true if the passed value is empty, false otherwise. The value is deemed to be empty if ...
- JavaScript随记汇总
1.<script>标签嵌套,浏览器无法正常解析的问题: 百度知道回答 <script>FTAPI_slotid = 1007894;FTAPI_sync = true< ...
- PDF.NET SOD Ver 5.1完全开源
PDF.NET SOD Ver 5.1完全开源 前言: 自从我2014年下半年到现在的某电商公司工作后,工作太忙,一直没有写过一篇博客,甚至连14年股票市场的牛市都错过了,现在马上要过年了,而今天又是 ...
- 多线程学习之三生产者消费者模式Guarded Suspension
Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者 1.1该 ...
- ASP.NET Web Service中使用Session 及 Session丢失解决方法 续
原文:ASP.NET Web Service中使用Session 及 Session丢失解决方法 续 1.关于Session丢失问题的说明汇总,参考这里 2.在Web Servcie中使用Sessio ...
- java设计模式之七装饰器模式(Decorator)
顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...
- JS获取渲染后的样式
一般我们利用element.style.属性来获取CSS的样式,而此方法只能获取标签内的样式,无法获取头部或引入的样式,因此,而我们又需要获取其样式,则我们可以使用:(其中element为标签,pro ...