diy数据库(十一)--diydb的运行时模块
来源:互联网 发布:三峡大学网络教育 编辑:程序博客网 时间:2024/06/16 12:33
一、运行时模块(RNT)
运行时模块是真正的业务处理模块,用于处理解析完成后的请求。它主要依赖索引模块(IXM)和数据管理模块(DMS)来处理请求。上层模块不能绕过RNT来调用IXM和DMS中的功能。《diy数据库(一)--概况》中对模块间的关系有比较清楚的说明。
二、RNT的实现
好吧,diydb的RNT实现非常简单,代码是最好的解释
Rtn.hpp
#ifndef RTN_HPP__#define RTN_HPP__#include "bson.h"#include "dms.hpp"#include "ixmBucket.hpp"class rtn{private : dmsFile *_dmsFile ;//数据管理模块(注意:不仅仅是数据文件) ixmBucketManager *_ixmBucketMgr ;//索引public : rtn () ; ~rtn() ; int rtnInitialize () ;//实际上就是初始化数据管理模块和索引 int rtnInsert ( bson::BSONObj &record ) ;//将record对应的记录插入数据库 int rtnFind ( bson::BSONObj &inRecord, bson::BSONObj &outRecord ) ;//根据inRecord中的_id查找数据 int rtnRemove ( bson::BSONObj &record ) ;//将record对应的记录从数据库删除} ;#endif
Rtn.cpp
#include "core.hpp"#include "rtn.hpp"#include "pd.hpp"#include "pmd.hpp"using namespace bson ;rtn::rtn() :_dmsFile(NULL),_ixmBucketMgr(NULL){}rtn::~rtn(){ if ( _ixmBucketMgr ) { delete _ixmBucketMgr ; } if ( _dmsFile ) { delete _dmsFile ; }}int rtn::rtnInitialize (){ int rc = DIY_OK ; _ixmBucketMgr = new ( std::nothrow ) ixmBucketManager () ; if ( !_ixmBucketMgr ) { rc = DIY_OOM ; PD_LOG ( PDERROR, "Failed to new bucket manager" ) ; goto error ; } _dmsFile = new(std::nothrow) dmsFile ( _ixmBucketMgr ) ; //_dmsFile = new(std::nothrow) dmsFile () ; if ( !_dmsFile ) { rc = DIY_OOM ; PD_LOG ( PDERROR, "Failed to new dms file" ) ; goto error ; } rc = _ixmBucketMgr->initialize () ; if ( rc ) { PD_LOG ( PDERROR, "Failed to call bucketMgr initialize, rc = %d", rc ) ; goto error ; } // init dms//dms的初始化 rc = _dmsFile->initialize ( pmdGetKRCB()->getDataFilePath () ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to call dms initialize, rc = %d", rc ) ; goto error ; }done : return rc ;error : goto done ;}int rtn::rtnInsert ( BSONObj &record ){ int rc = DIY_OK ;//本身对rtn的insert,find和remove要加读写锁 dmsRecordID recordID ; BSONObj outRecord ; // check if _id exists rc = _ixmBucketMgr->isIDExist ( record ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call isIDExist, rc = %d", rc ) ; // write data into file rc = _dmsFile->insert ( record, outRecord, recordID ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to call dms insert, rc = %d", rc ) ; goto error ; } rc = _ixmBucketMgr->createIndex ( outRecord, recordID ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call ixmCreateIndex, rc = %d", rc ) ; done : return rc ;error : goto done ;}int rtn::rtnFind ( BSONObj &inRecord, BSONObj &outRecord ){ int rc = DIY_OK ; dmsRecordID recordID ; rc = _ixmBucketMgr->findIndex ( inRecord, recordID ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call ixm findIndex, rc = %d", rc ) ; rc = _dmsFile->find ( recordID, outRecord ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call dms find, rc = %d", rc ) ;done : return rc ;error : goto done ;}int rtn::rtnRemove ( BSONObj &record ){ int rc = DIY_OK ; dmsRecordID recordID ; rc = _ixmBucketMgr->removeIndex ( record, recordID ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call ixm removeIndex, rc = %d", rc ) ; rc = _dmsFile->remove ( recordID ) ; PD_RC_CHECK ( rc, PDERROR, "Failed to call dms remove, rc = %d", rc ) ;done : return rc ;error : goto done ;}注意:看到这里,细心的朋友也许会发现diydb的RNT中有个bug,diydb的索引中,每个桶有个读写锁,而且数据管理模块在往数据文件中增删查数据时会加个全局的读写锁,你以为这样就够了吗?举个例子,假如一个工作线程A在执行rtnFind函数,这个时候他已经在索引中找到了要查的数据在数据文件中的记录id(即数据在数据文件中的页号和槽号),这个时候,他会按照这个记录id去读数据文件中的数据,但是这个时候如果另一个线程B在A读数据之前删除了数据库文件中的那条数据,那么,线程A就出错了。所以,简单粗暴的办法就是在RNT的操作中加读写锁,好吧,这个锁的粒度真是太大了。
三、总结
1、到这里diydb的单机部分总算是看完了,我get到的代码也只有单机部分,后续会将所有单机部分的注释版代码放到我github上。麻雀虽小,五脏俱全嘛。把diydb当做一个C++服务器去学习,还是有很多看点的。
2、另外,我在单机版本基础上增加了基于一致hash的数据分片功能,即基于一致性hash的多机机制,不过目前动态增删服务器节点还没有实现,等实现后也会放到github上。
注释版代码:http://git.oschina.net/superlike/diydb-annotation
0 0
- diy数据库(十一)--diydb的运行时模块
- diy数据库(九)--diydb的数据持久化和存储格式
- diy数据库(十二)--diydb基于一致性hash的集群演示
- diy数据库系列(引言)
- diy数据库(一)--概况
- diy数据库(十)--索引
- diy数据库(三)--客户端框架的搭建
- diy数据库(八)--客户端和服务器之间的通信协议
- JVM(十一) 运行时包
- 十一、BluetoothChat 的运行演示
- Mybase:DIY自己的知识数据库
- 嵌入式数据库(十一 )
- (十一)Mysql数据库
- struts2(十一)运行流程
- diy数据库(二)--网络通信类
- diy数据库(四)--锁和队列
- 【discuzx2】在后台添加自定义DIY模块的方法
- sys 模块:程序运行时的处理
- SOAPUI使用教程-REST请求工作
- poj 2392背包条件限制
- MPLS-2 LDP邻居的建立
- js arguments.caller arguments.callee分析
- RelativeLayout
- diy数据库(十一)--diydb的运行时模块
- [莫比乌斯反演 树状数组] BZOJ 3529 [Sdoi2014]数表
- 石子合并——圆形版
- C++临时变量的生命周期
- 把canvas绘制的图形导出成图片
- 基于openVZ的CentOS6.X安装lamp环境
- MPLS-3 帧mode的MPLS
- @ManyToOne
- FD_CLOEXEC是什么?