Rocksdb iterator和snapshot 接口
生活随笔
收集整理的這篇文章主要介紹了
Rocksdb iterator和snapshot 接口
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Rocksdb提供迭代器來來訪問整個db中的數據,就像STL中的迭代器功能一樣,用來訪問容器中的具體的數據。
訪問形式以及訪問接口有如下幾種:
- 遍歷所有的key-value
//打開db,并初始化一個迭代器指針 rocksdb::Iterator* it = db->NewIterator(rocksdb::ReadOptions()); for (it->SeekToFirst(); it->Valid(); it->Next()) {cout << it->key().ToString() << ": " << it->value().ToString() << endl; } assert(it->status().ok()); // Check for any errors found during the scan delete it; - 輸出一個范圍內的key-value,[small, big)
for (it->Seek(small);it->Valid() && it->key().ToString() < big;it->Next()) { ... } assert(it->status().ok()); // Check for any errors found during the scan - 反向遍歷db中的元素
for (it->SeekToLast(); it->Valid(); it->Prev()) { ... } assert(it->status().ok()); // Check for any errors found during the scan - 反向遍歷一個指定范圍的key,如(small, big]
for (it->SeekForPrev(start);it->Valid() && it->key().ToString() > limit;it->Prev()) { ... } assert(it->status().ok()); // Check for any errors found during the scan
迭代器的接口可以算是 rocksdb針對客戶端的核心接口,主要是提供排序以及高效查找的功能。
測試代碼如下:
#include <iostream>
#include <string>
#include <rocksdb/db.h>
#include <rocksdb/iterator.h>
#include <rocksdb/table.h>
#include <rocksdb/options.h>
#include <rocksdb/env.h>using namespace std;static string rand_key(unsigned long long key_range) {char buff[30];unsigned long long n = 1;for (int i =1; i <= 4; ++i) {n *= (unsigned long long ) rand();}sprintf(buff, "%llu", n % key_range);string k(buff);return k;
}int main() {rocksdb::DB *db;rocksdb::Options option;option.create_if_missing = true;option.compression = rocksdb::CompressionType::kNoCompression;rocksdb::Status s = rocksdb::DB::Open(option, "./iterator_db", &db);if (!s.ok()) {cout << "Open failed with " << s.ToString() << endl;exit(1);}rocksdb::DestroyDB("./iterator_db", option);cout << "seek all keys : " << endl;for(int i = 0; i < 5; i ++) {rocksdb::Status s = db->Put(rocksdb::WriteOptions(), rand_key(9), string(10, 'a' + (i % 26)) );if (!s.ok()) {cout << "Put failed with " << s.ToString() << endl;exit(1);}} /* traverse rocksdb key-value */rocksdb::Iterator *it = db->NewIterator(rocksdb::ReadOptions());for (it->SeekToFirst(); it->Valid(); it->Next()) {cout << it->key().ToString() << ": " << it->value().ToString() << endl;}string limit="4";string start="2";cout << "seek from '2' to '4' : " << endl;for(it->Seek(start); it->Valid()&&it->key().ToString() < limit;it->Next()) {cout << it->key().ToString() << ": " << it->value().ToString() << endl;} assert(it->status().ok());cout << "seek from last to start :" << endl;for (it->SeekToLast(); it->Valid(); it->Prev()) {cout << it->key().ToString() << ": " << it->value().ToString() << endl;}assert(it->status().ok());cout << "seek from '4' to '2' :" << endl;for(it->SeekForPrev(limit); it->Valid()&&it->key().ToString() > start;it->Prev()) {cout << it->key().ToString() << ": " << it->value().ToString() << endl;} assert(it->status().ok());delete it;db->Close();delete db;return 0;
}
輸出如下:
seek all keys :
3: cccccccccc
4: dddddddddd
7: bbbbbbbbbb
8: eeeeeeeeee
seek from '2' to '4' :
3: cccccccccc
seek from last to start :
8: eeeeeeeeee
7: bbbbbbbbbb
4: dddddddddd
3: cccccccccc
seek from '4' to '2' :
4: dddddddddd
3: cccccccccc
且上層使用rocksdb迭代器接口時一般會和snapshot接口一同使用,用來實現MVCC的版本控制功能。
關于snapshot的實現,我們在Rocksdb事務:隔離性的實現中有提到,感興趣的可以看看。
關于snapshot的客戶端接口主要有:
sp1 = db->GetSnapshot();在當前db狀態下創建一個snapshot,添加到內部維護的一個全局的snapshotImpl的雙向鏈表中,并返回該snapshot的對象read_option.snapshot = sp1;將獲取到的snapshot 傳給read_option,進行Get操作db->ReleaseSnapshot(sp1);釋放snapshot相關的資源(從雙向鏈表中刪除該節點)
隔離性的測試代碼如下:
#include <iostream>
#include <string>
#include <rocksdb/db.h>
#include <rocksdb/iterator.h>
#include <rocksdb/table.h>
#include <rocksdb/options.h>
#include <rocksdb/env.h>using namespace std;int main() {rocksdb::DB *db;rocksdb::Options option;option.create_if_missing = true;option.compression = rocksdb::CompressionType::kNoCompression;rocksdb::Status s = rocksdb::DB::Open(option, "./iterator_db", &db);if (!s.ok()) {cout << "Open failed with " << s.ToString() << endl;exit(1);}// set a snapshot before putconst rocksdb::Snapshot *sp1 = db->GetSnapshot(); s = db->Put(rocksdb::WriteOptions(), "sp2", "value_sp2");assert(s.ok());// set a snapshot after putconst rocksdb::Snapshot *sp2 = db->GetSnapshot();rocksdb::ReadOptions read_option;read_option.snapshot = sp1;string value = "";//預期獲取不到sp2的value,因為這里用的是sp1的快照s = db->Get(read_option, "sp2", &value); if(value == "") {cout << "Can't get sp2 at sp1!" << endl;}read_option.snapshot = sp2;// 能夠獲取到,使用的是sp2的快照,其是在put之后設置的s = db->Get(read_option, "sp2", &value); assert(s.ok());if(value != "") {cout << "Got sp2's value: " << value << endl;}db->ReleaseSnapshot(sp1);db->ReleaseSnapshot(sp2);
輸出如下:
Can't get sp2 at sp1!
Got sp2's value: value_sp2
當然rocksdb也提供了更為復雜的mvcc特性,來以事務的方式支持不同的隔離級別。
總結
以上是生活随笔為你收集整理的Rocksdb iterator和snapshot 接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中华龙舟大赛可以到现场观看吗
- 下一篇: 面条多少钱啊?