slava项目(2):分数据库操作中的Flush函数

slava是我参与的一个github开源项目,项目的主要的工作是构建一个高性能、K-V云数据库。 slava项目的连接

我们在实现数据库的操作的时候,会首先定义一个数据库结构体,名为DB:

DB数据库
之后在这个数据结构的基础上编写数据库的底层功能实现,比如Put、Get,Remove等。

但是对于数据库中的Flush函数,该函数所实现的功能是清空该数据库,我的编写和其他成员,下文称为成员A,代码存在一定的差异。
成员A实现Flush函数:
其他成员的Flush实现
作者认为,上面的实现是并不完整的,Flush函数要做的是清空数据库,而上面函数的操作,只清空了DB结构体中的并没有清空versionMap。

versionMap是用在Watch命令中的,用来提交事务的时候取出对应key的版本号,然后对比key被watch(监控)时的版本号,如果版本号不一致说明在执行事务的过程中有别的协程对key进行了修改,则事务提交不成功,回滚。如果,版本号前后一致则可以提交事务成功。

作者认为正确的Flush函数的写法应该如下:
slava的Flush
makeDB
论证一:作者认为,最方便的做法就是直接调用makeDB函数,直接返回一个新的DB结构体,旧的DB将被GC自动回收,这样才起到了清空这个数据库的目的。

btw:想更深入的了解Go语言的GC,可以阅读作者的另一篇blog:链接: Go语言GC详解

论证二:同时从另一个角度来看,我们可以假设在一个高并发的场景中,一个协程A正在执行事务,还没有提交,这时候另一个协程B调用了成员A中的FLush函数,清空了data但是并没有清空versionMap。我们假设除了B协程Flush数据库外没有别的协程修改watch的key。在B协程调用成员A的Flush后,A协程提交说了事务,这时候它会对比watch的key的版本号,发现版本号没有发生改变,这时候协程A成功提交事务!这显然是不正确的,因为协程B已经清空了data中的所有key,B协程已经对key进行了修改,所以事实上应该时A协程提交事务失败前后矛盾

论证三:再者,作者查阅了github上redis的源码,链接: 源码地址。在dict.c的包中实现了清空数据库的操作:

redis的源码
在这里插入图片描述

上述的源码中,先清除数据库中的所有元素,然后回收内存,最后重新建立一个空的数据库。这样的想法与作者的想法相吻合,只是Go语言可以自动回收内存,不需要像C语言那样手动回收内存。

所以综上,作者认为自己编写的代码是正确的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值