leveldb代码阅读(9)——levedb的快照

原文地址:http://www.blogjava.net/sandy/archive/2012/03/13/leveldb5.html

所谓snapshot就是一个快照,我们可以从快照中读到旧的数据。

先写一个测试程序来看看snapshot的使用:

#include  < iostream >
#include 
" leveldb/db.h "

using   namespace  std;
using   namespace  leveldb;


int  main() {
    DB 
* db ;
    Options op;
    op.create_if_missing 
=   true ;
    Status s 
=  DB::Open(op, " /tmp/testdb " , & db);

    
if (s.ok()){
        cout 
<<   " create successfully "   <<  endl;
        s 
=  db -> Put(WriteOptions(), " abcd " , " 1234 " );
        
if (s.ok()){
            cout 
<<   " put successfully "   <<  endl;
            
string  value;
            s 
=  db -> Get(ReadOptions(), " abcd " , & value);
            
if (s.ok()){
                cout 
<<   " get successfully,value: "   <<  value  <<  endl;
            }
        }
        
if (s.ok()){
            
string  value;
            
const  Snapshot  *  ss  = db -> GetSnapshot();
            ReadOptions rop;
            db
-> Put(WriteOptions(), " abcd " , " 123456 " );
            db
-> Get(rop, " abcd " , & value);
            
if (s.ok()){
                    cout 
<<   " get successfully,value: "   <<  value  <<  endl;
            }
            rop.snapshot 
=  ss;
            db
-> Get(rop, " abcd " , & value);
            
if (s.ok()){
                    cout 
<<   " get from snapshot successfully,value: "   <<  value  <<  endl;
            }
            db
-> ReleaseSnapshot(ss);
        }
    }
    delete db;
    
return   0 ;
}

程序运行的输出结果是:
create successfully
put successfully
get  successfully,value: 1234
get  successfully,value: 123456
get  from snapshot successfully,value: 1234

可以看出,即使在数据更新后,我们仍然可以从snapshot中读到旧的数据。

下面我们来分析leveldb中snapshot的实现。

SequenceNumber(db/dbformat.h)
SequenceNumber是leveldb很重要的东西,每次对数据库进行更新操作,都会生成一个新的SequenceNumber,64bits,其中高8位为0,可以跟key的类型(8bits)进行合并成64bits。
typedef uint64_t SequenceNumber;

// We leave eight bits empty at the bottom so a type and sequence#
// can be packed together into 64-bits.
static const SequenceNumber kMaxSequenceNumber =
    ((0x1ull << 56) - 1);

SnapShot(db/snapshot.h),,可以看出snapshot其实就是一个sequence number
class  SnapshotImpl :  public  Snapshot {
 
public :
  
// 创建后保持不变
  SequenceNumber number_;  

 
private :
  friend 
class  SnapshotList; 

  
// 双向循环链表
  SnapshotImpl *  prev_;
  SnapshotImpl
*  next_;

  SnapshotList
*  list_;                  //  just for sanity checks
};

创建snapshot:
const  Snapshot *  DBImpl::GetSnapshot() {
  MutexLock l(
& mutex_);
  
return  snapshots_.New(versions_ -> LastSequence());
}

删除snapshot:
void  DBImpl::ReleaseSnapshot( const  Snapshot *  s) {
  MutexLock l(
& mutex_);
  snapshots_.Delete(reinterpret_cast
< const  SnapshotImpl *> (s));
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值