Caffe 源码阅读笔记 [DB] 存储Caffe数据的LevelDB类

概述

上一篇文章 描述Caffe如何从DB读取训练集数据。这篇要研究DB的具体实现是什么样子的。Caffe目前支持从LevelDB和lmdb两种key-value store读取和存储数据。我个人认为rocksdb(leveldb的改进版)比lmdb性能会更好。因此我只对Caffe如何使用leveldb感兴趣,lmdb的部分因为时间关系略过。

三个基本类Cursor, Transaction, DB

Caffe建立了三个基本类DB, Transaction, Cursor,如果开发者要引进新的数据库,只需要继承并实现这三个基本类的函数即可,非常方便。DB::GetDB(backend) 函数会根据backend的值初始化相应的数据库类型,比如如果backend=”leveldb”,GetDB会返回new LevelDb();

enum Mode { READ, WRITE, NEW }; // 打开数据库的三种模式:只读,写,新建数据库
// 类似于map的iterator
class Cursor { 
  virtual void SeekToFirst() = 0;
  virtual void Next() = 0;
  virtual string key() = 0;
  virtual string value() = 0;
  virtual bool valid() = 0;
};
// 批量写操作。
class Transaction {
  virtual void Put(const string& key, const string& value) = 0;
  virtual void Commit() = 0;
};
// 数据库定义
class DB {
  virtual void Open(const string& source, Mode mode) = 0;   // 用指定模式打开数据库
  virtual void Close() = 0; // 关闭数据库
  virtual Cursor* NewCursor() = 0; // 新建一个遍历指针
  virtual Transaction* NewTransaction() = 0; //新建一个写事务
};

LevelDBCursor

只有一个iter_变量,Cursor内对应函数浅显易懂分别是
iter_->SeekToFirst(),iter_->Next(),iter_->key().ToString(),iter_->value().ToString(),iter_->Valid()

LevelDBTransaction

void Put(const string& key, const string& value) {
  // leveldb::WriteBatch 类型,缓存更新db[key] = value;
  batch_.Put(key, value);
}
void Commit() {
  // 持久化batch_内缓存的数据
  leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_);
}

LevelDB

void LevelDB::Open(const string& source, Mode mode) {
  leveldb::Options options;
  options.block_size = 65536; // leveldb最小读取单位,即每读取一对key-value,需要把64KB的数据读入内存
  options.write_buffer_size = 268435456; // leveldb的memtable大小是256MB,一旦memtable超过256MB,它会变成只读的memtable并持久化
  options.max_open_files = 100; // leveldb把打开的文件fd缓存在table cache里,读操作会去table cache里面找要读的文件进行读取。Caffe只允许缓存最多100个文件的fd
  options.error_if_exists = mode == NEW;
  options.create_if_missing = mode != READ; // 如果不存在而且不是只读模式,建立新数据库
  leveldb::Status status = leveldb::DB::Open(options, source, &db_);
  CHECK(status.ok()) << "Failed to open leveldb " << source
                     << std::endl << status.ToString();
}
NewCursor() : return new LevelDBCursor(db_->NewIterator(leveldb::ReadOptions()));
NewTransaction(): return new LevelDBTransaction(db_);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值