日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Rocksdb iterator和snapshot 接口

發(fā)布時(shí)間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rocksdb iterator和snapshot 接口 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Rocksdb提供迭代器來來訪問整個(gè)db中的數(shù)據(jù),就像STL中的迭代器功能一樣,用來訪問容器中的具體的數(shù)據(jù)。

訪問形式以及訪問接口有如下幾種:

  • 遍歷所有的key-value
    //打開db,并初始化一個(gè)迭代器指針
    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;
    
  • 輸出一個(gè)范圍內(nèi)的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
    
  • 反向遍歷一個(gè)指定范圍的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迭代器接口時(shí)一般會(huì)和snapshot接口一同使用,用來實(shí)現(xiàn)MVCC的版本控制功能。
關(guān)于snapshot的實(shí)現(xiàn),我們在Rocksdb事務(wù):隔離性的實(shí)現(xiàn)中有提到,感興趣的可以看看。

關(guān)于snapshot的客戶端接口主要有:

  • sp1 = db->GetSnapshot(); 在當(dāng)前db狀態(tài)下創(chuàng)建一個(gè)snapshot,添加到內(nèi)部維護(hù)的一個(gè)全局的snapshotImpl的雙向鏈表中,并返回該snapshot的對象
  • read_option.snapshot = sp1; 將獲取到的snapshot 傳給read_option,進(jìn)行Get操作
  • db->ReleaseSnapshot(sp1); 釋放snapshot相關(guān)的資源(從雙向鏈表中刪除該節(jié)點(diǎn))

隔離性的測試代碼如下:

#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 = "";//預(yù)期獲取不到sp2的value,因?yàn)檫@里用的是sp1的快照s = db->Get(read_option, "sp2", &value); if(value == "") {cout << "Can't get sp2 at sp1!" << endl;}read_option.snapshot = sp2;// 能夠獲取到,使用的是sp2的快照,其是在put之后設(shè)置的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

當(dāng)然rocksdb也提供了更為復(fù)雜的mvcc特性,來以事務(wù)的方式支持不同的隔離級別。

總結(jié)

以上是生活随笔為你收集整理的Rocksdb iterator和snapshot 接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。