DB类
enum Mode { READ, WRITE, NEW };//数据库操作的模式
class Cursor {//这个类实现的是对数据库内数据的读取,这个是一个基础类,根据不同的数据对这个类进行继承
public:
Cursor() { }
virtual ~Cursor() { }
virtual void SeekToFirst() = 0;
virtual void Next() = 0;
virtual string key() = 0;
virtual string value() = 0;
virtual bool valid() = 0;
DISABLE_COPY_AND_ASSIGN(Cursor);
};
class Transaction {//这个类是将数据存储在数据库里面,这个类也是基础类,不同的数据库对这个类进行继承。
public:
Transaction() { }
virtual ~Transaction() { }
virtual void Put(const string& key, const string& value) = 0;
virtual void Commit() = 0;
DISABLE_COPY_AND_ASSIGN(Transaction);
};
class DB {//这个类也是基础类,不同的数据库对这个类进行继承。
public:
DB() { }
virtual ~DB() { }
virtual void Open(const string& source, Mode mode) = 0;
virtual void Close() = 0;
virtual Cursor* NewCursor() = 0;
virtual Transaction* NewTransaction() = 0;
DISABLE_COPY_AND_ASSIGN(DB);
};
接下来我们就介绍caffe 里面 LevelDB 的操作:
//函数的名称说明了它的功能
class LevelDBCursor : public Cursor {
public:
explicit LevelDBCursor(leveldb::Iterator* iter)
: iter_(iter) { SeekToFirst(); }//构造函数,传递进来leveldb::Iterator
~LevelDBCursor() { delete iter_; }
virtual void SeekToFirst() { iter_->SeekToFirst(); }
virtual void Next() { iter_->Next(); }
virtual string key() { return iter_->key().ToString(); }
virtual string value() { return iter_->value().ToString(); }
virtual bool valid() { return iter_->Valid(); }
private:
leveldb::Iterator* iter_;//Iterator进行leveldb数据库读取操作
};
class LevelDBTransaction : public Transaction {
public:
explicit LevelDBTransaction(leveldb::DB* db) : db_(db) { CHECK_NOTNULL(db_); }//传递的是leveldb::DB,这里的DB跟前面自定义的DB不一样哦。这个是leveldb这个库里面定义的。
virtual void Put(const string& key, const string& value) {
batch_.Put(key, value);
}//这个是将数据暂存在在leveldb::WriteBatch,之后调用Commit来实现存入leveldb中。
virtual void Commit() {
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch_);
CHECK(status.ok()) << "Failed to write batch to leveldb "
<< std::endl << status.ToString();
}
private:
leveldb::DB* db_;
leveldb::WriteBatch batch_;
DISABLE_COPY_AND_ASSIGN(LevelDBTransaction);
};
class LevelDB : public DB {
public:
LevelDB() : db_(NULL) { }
virtual ~LevelDB() { Close(); }
virtual void Open(const string& source, Mode mode);
virtual void Close() {
if (db_ != NULL) {
delete db_;
db_ = NULL;
}
}
virtual LevelDBCursor* NewCursor() {
return new LevelDBCursor(db_->NewIterator(leveldb::ReadOptions()));
}
virtual LevelDBTransaction* NewTransaction() {
return new LevelDBTransaction(db_);
}
private:
leveldb::DB* db_;
};
void LevelDB::Open(const string& source, Mode mode) {
leveldb::Options options;//一些设置的选项。
options.block_size = 65536;
options.write_buffer_size = 268435456;
options.max_open_files = 100;
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();
LOG(INFO) << "Opened leveldb " << source;
}
接下来我们就介绍caffe 里面 LMDB 的操作:(略,有空再补充)
//这两个函数的功能是根据不同的backend来初始化不同的类(LeveldDB/LMDB)
DB* GetDB(DataParameter::DB backend) {
switch (backend) {
case DataParameter_DB_LEVELDB:
return new LevelDB();
case DataParameter_DB_LMDB:
return new LMDB();
default:
LOG(FATAL) << "Unknown database backend";
}
}
DB* GetDB(const string& backend) {
if (backend == "leveldb") {
return new LevelDB();
} else if (backend == "lmdb") {
return new LMDB();
} else {
LOG(FATAL) << "Unknown database backend";
}
}