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 接口相关推荐

  1. Rocksdb Iterator实现:从DBIter 到 TwoLevelIter 的漫长链路

    文章目录 1. 迭代器简单介绍 2. 迭代器用户态相关接口 3. 迭代器内部架构 4. 迭代器的入口实现 4.1 DBIter 4.2 MergingIterator 4.3 Memtable系列It ...

  2. java--迭代(一)Iterator和Iterable接口

    摘自:http://www.cnblogs.com/redcoatjk/articles/4863340.html Iterable:顾名思义,实现了这个接口的对象支持迭代,是可迭代的. Iterat ...

  3. Iterator和ListIterator接口的使用和区别

    1.Iterator接口 1.1.Iterator接口概述 java.util.Iterator 接口提供遍历任何 Collection 的接口.我们可以从一个 Collection 中使用迭代器方法 ...

  4. Rocksdb iterator 的 Forward-scan 和 Reverse-scan 的性能差异

    前言 最近在读 MyRocks 存储引擎2020年的论文,因为这个存储引擎是在Rocksdb之上进行封装的,并且作为Facebook 内部MySQL的底层引擎,用来解决Innodb的空间利用率低下 和 ...

  5. Iterator、Iterable接口的使用及详解

    Java集合类库将集合的接口与实现分离.同样的接口,可以有不同的实现. Java集合类的基本接口是Collection接口.而Collection接口必须实现Iterator接口. 以下图表示集合框架 ...

  6. java 中iterator 和 collection接口源码

    iterator接口和具体的容器中实现的iterator 对象(以ArrayList为例) iterator: public interface Iterator<E> {boolean ...

  7. php iterator,PHP遍历接口Iterator详解

    从手册中查到的解释是: Iterator extends Traversable { /* Methods */ abstract public mixed current ( void ) abst ...

  8. collection集合 多少钱_Java 集合(2)-- Iterator接口源码超级详细解析

    一.iterator接口介绍 iterator接口,也是集合大家庭中的一员.和其他的Map和Collection接口不同,iterator 主要是为了方便遍历集合中的所有元素,用于迭代访问集合中的元素 ...

  9. Java Enumeration接口与Iterator接口

    一.Enumeration接口 Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素. 这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃, ...

最新文章

  1. web前端知识点太多_web前端入门必学的16个知识点,都来看一下吧
  2. 安徽大学计算机考研失败,回馈:2014年安徽大学计算机初试回忆题,我是雷锋,低调...
  3. Qt--在.pro文件中添加链接库的写法
  4. 一个程序员的逗逼瞬间(三)
  5. 信息学奥赛一本通(1043:整数大小比较)
  6. Node.js开发框架Express4.x
  7. python处理出租车轨迹数据_基于出租车GPS轨迹数据的研究:出租车行程的数据分析...
  8. 几个支持SCORM的免费平台
  9. C#list转JSON(Newtonsoft.Json.dll)(仅做记录)
  10. 菜刀php教程,中国菜刀(chopper)功能介绍及使用教程
  11. 小马激活报错:已停止工作
  12. 新猿木子李:0基础学python培训教程 Python操作Excel之写入数据
  13. App Tamer for Mac v2.6 应用CPU使用率管理
  14. YML(YAML)语法(文件后缀为.yml格式)
  15. 【成长经历】----陪女朋友拔智齿
  16. ORACLE 角色授权
  17. 信号的基本概念及分类
  18. MySQL 设计与开发规范
  19. SpringBoot - SpringBoot配置说明
  20. 计算机网络日志查询,如何查看电脑浏览记录 通过电脑日志查看浏览记录方法...

热门文章

  1. svn官方备份hot-backup.py强烈推荐
  2. Android 高清加载巨图方案 拒绝压缩图片
  3. jquery checkbox勾选/取消勾选的诡异问题
  4. 关于SpringMVC和Struts2的区别
  5. Access应用日志一
  6. 使用Newtonsoft.Json
  7. note-在VisualStudio中使用正则表达式
  8. PHP设置禁止目录索引,/var/www/html目录索引禁止
  9. java显示链表在jtable上输出_jtable的使用精华
  10. php ad 管理工具,打开AD管理工具连接到指定DC