您的位置:首页 > 编程语言

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

2016-01-15 11:05 316 查看
原文地址: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));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: