Skip to content

a simple single thread kv demo, use skiplist and dict as the main store sturctrue. now only support epoll multiplexer and string kv. and support get, set, del scan method check first

Notifications You must be signed in to change notification settings

shuijing198799/simple-kv

Repository files navigation

第一次写大型的C应用,有些地方做的不太完善。说一下基本思路

题目的大意是需要做一个有序的内存应用。中间我实现了三个基本的数据结构
基本字符串类型str,拉链式解决冲突的哈希表hashmap,一个跳表skiplist
每个跳表的node都会用hashmap存储起来,这样加速了查找和删除。这个方法
学习的是redis的zset。因为set还是需要找到对应的点。所以时间复杂度会高一些。
这个数据结构结合成的sortmap时间复杂度如下。
1.GET O(1)
2.SET O(logn) 符合跳表的插入操作的时间复杂度。
3.DEL O(1)
4.SCAN O(n)

为了防止大量的数据输入和输出,解决一个包体无法容纳的情况下我们为每一个connect 到服务器的client建立了一个client结构。内容包括每一个client的fd,输入缓冲inbuf以及 输入缓冲现在的长度inlen,输出缓冲outbuf以及输出缓冲已经消费的长度outlen。 
	
serverinfo是server的主要数据结构。 主要保存了多路复用器的eventloop和主要存储结构
sortmap(skiplist和hashmap的合体)主要监听的fd以及客户端的数量client_channel(暂时未用到)

网络注册流程如下:
在初始化进程时,我们会在eventloop对于listenfd注册一个读监听。
当有连接上来时回调acceptTcpHandler,通过accept函数创建一个新的文件fd。
创建client数据结构。保存这个连接中的读写buf以及基本信息。
针对当前的fd建立一个读监听。并且在server中增加客户端计数器。

网络读取流程如下:
在每一次有socket读请求时,网络模块会回调readQueryFromClient
将读取到的数据放到inbuf中。(针对内核缓存和读取缓存可能不一样大小的情况,我使用了一个while直到这次
缓存中的数据都被读取到为止)并将缓存中数据搬运到inbuf中。所以socket必须是非阻塞的。当返回-1并且设置 errno为eagain时知道已经读完。
启动命令解析模块,对指令(除了正确的get set del scan以外,其他的非法指令返回一个useage,)进行解
析,客户端发上来的指令是以/r/n结束。
执行指令,(调用sortmap中的get set del scan方法)
将调用结果写到outbuf中。并且对于这个fd进行些时间监听。

网络写时间处理流程:
从client的outbuf中获取数据然后写入。如果写满,但是outbuf中的数据未写完,不删除些时间。否则,删除写
时间并且清理掉outbuf,重置outlen。

附:操作和返回
命令解析失败返回
get 如果得到 返回val, 如果没有返回null
set 如果成功返回OK,如果失败返回null
del 如果成功返回OK,如果没有返回null
scan 返回所有的数据。
	
str 是基本的字符串类型,会自动扩容,设定了一个阀值1M,如果现在的字符串大小大于1M.那么增长速度是每次
增加1M否则每次以翻倍的速度扩容。实现了一些str通用的函数以及命令解析函数。
map 是一个哈希表。通过拉链式的方式解决冲突。默认是 1024 * 1024 * 64个哈系桶。通过CRC64哈希算法来进行
索引。实现了增删改查的功能,但是没有进行自动扩容的方法的实现。(时间不足,要实现一个高可用的rehash)
还是有一些工作量。
skiplist 标准的跳表。实现了增删改查。改造了一下,key不能重复。

测试:
对于所有结构的增删改查都进行了测试。
视同telnent测试了大量插入并且scan。
对于str模块和sortmap模块添加了模块测试。分别是str_test()和sortmap_test模块。

客户端:
加了一个客户端模块,通过从stdin读入数据,执行后到stdout输出。

未完成:
多进程调用或者槽点分派,两者选一可以实现多进程
刷盘(可以将set和del全部记录下下来)时间原因没做
hashmap的rehash过程。
所有的数据结构都是唯一实现,比如skiplist只支持str,多路复用器只支持epoll。并没有使用函数指针进行“多态”
malloc和free虽然我已经收集到了一起,但是并没有对已使用内存进行统计。
线程中没有时间事件。

下一步规划:
实现一个线程池,增加系统对多线程的支持 
再多线程调度下,使用乐观锁,进行行级锁定。保证在线程安全。

(线程池完成,进行了初步测试,准备加入一些单元测试) 2018 12 31
(增加了一些对线程池的测试,下一步将线程池加入到存储结构中。并且保证并发安全。因为需要准备一下面试,这两天要看看书,可能需要看两天书。) 2018 1 1
(今天没有忍住补充了一点线程池监控,并且把命令处理的函数移入了线程池。后期加一些乐观锁来保证输入输出buf的安全。)2018 1 2

About

a simple single thread kv demo, use skiplist and dict as the main store sturctrue. now only support epoll multiplexer and string kv. and support get, set, del scan method check first

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published