caffe的db_lmdb.hpp文件

先总的说一下:

类:LMDBCursor:  它干了点什么?它需要传入参数为:mdb_txn(传入它是因为用完它,把它absort掉), mdb_cursor;它应该是用来读出数据的;

类:LMDBTransaction:

它主要是用来写入数据的吧,,用put()函数 ,与commit()函数;

最终还是靠类:LMDB应该算是一个对上面两个类的调用吧。它应该算是做了封装吧,,干脆直接上代码啦:

db_lmdb.hpp

1 #ifdef USE_LMDB
2 #ifndef CAFFE_UTIL_DB_LMDB_HPP
3 #define CAFFE_UTIL_DB_LMDB_HPP
4
5 #include <string>
6 #include <vector>
7
8 #include "lmdb.h"
9
10 #include "caffe/util/db.hpp"
11
12 namespace caffe { namespace db {
13 // 下面的MDB_SUCCESS为一个宏定义,为0,表示成功,如果失败则对应不同的数值,表示不同的错误;
14 // mdb_strerror,输出string,它的作用是根据不同的错误输出不同的错误语句;
15 inline void MDB_CHECK(int mdb_status) {
16 CHECK_EQ(mdb_status, MDB_SUCCESS) << mdb_strerror(mdb_status);
17 }
18
19 //注意:MDB_cursor是与一个specific的transaction与database相关联的;
20 class LMDBCursor : public Cursor {
21 public:
22 explicit LMDBCursor(MDB_txn* mdb_txn, MDB_cursor* mdb_cursor) //初始化时,给mdb_txn,与mdb_curcor赋值;
23 : mdb_txn_(mdb_txn), mdb_cursor_(mdb_cursor), valid_(false) {
24 SeekToFirst();
25 }
26 virtual ~LMDBCursor() {
27 mdb_cursor_close(mdb_cursor_); //mdb_cursor_close函数的作用为:关闭一个cursor句柄;
28 mdb_txn_abort(mdb_txn_); //该函数的作用为:用于放弃所有对transaction的操作,并释放掉transaction句柄;
29 }
30 virtual void SeekToFirst() { Seek(MDB_FIRST); } //把database里的第一个key/value的值放入变量:mdb_key_与mdb_value_;
31 virtual void Next() { Seek(MDB_NEXT); } //下一个;;
32 virtual string key() {
33 return string(static_cast<const char*>(mdb_key_.mv_data), mdb_key_.mv_size); //返回mdb_key_里的数据,以字符串形式;
34 }
35 virtual string value() {
36 return string(static_cast<const char*>(mdb_value_.mv_data),
37 mdb_value_.mv_size); //返回mdb_value_里的数据(以字符串的方式;,应该是用了strin的构造函数吧.
38 }
39 virtual bool valid() { return valid_; }
40
41 private:
42 void Seek(MDB_cursor_op op) { //注意,这里的MDB_cursor_op为枚举类型,代表了curcor的相关操作;
43 int mdb_status = mdb_cursor_get(mdb_cursor_, &mdb_key_, &mdb_value_, op); //这个函数用于通过curcor恢复key与data;
44 if (mdb_status == MDB_NOTFOUND) { //当返回的状态为MDB_NOTFOUND时,表明,没有发现匹配的key;
45 valid_ = false;
46 } else {
47 MDB_CHECK(mdb_status);
48 valid_ = true;
49 }
50 }
51
52 MDB_txn* mdb_txn_; //初始化时,给mdb_txn,与mdb_curcor赋值;
53 MDB_cursor* mdb_cursor_;
54 MDB_val mdb_key_, mdb_value_;
55 bool valid_;
56 };
57
58 class LMDBTransaction : public Transaction {
59 public:
60 explicit LMDBTransaction(MDB_env* mdb_env) //给一个环境handle赋值;
61 : mdb_env_(mdb_env) { }
62 virtual void Put(const string& key, const string& value); //把key与value的值分别push到对应的vector里;
63 virtual void Commit(); //它做的时,把keys 与 values里的数据提交 ,并清空它们;
64
65 private:
66 MDB_env* mdb_env_; //环境句柄;
67 vector<string> keys, values; //两个vector容器;
68
69 void DoubleMapSize(); //把环境的mapsize扩大两倍;
70
71 DISABLE_COPY_AND_ASSIGN(LMDBTransaction);
72 };
73
74 class LMDB : public DB {
75 public:
76 LMDB() : mdb_env_(NULL) { }
77 virtual ~LMDB() { Close(); }
78 virtual void Open(const string& source, Mode mode); //它所做的事情就是创建一个操作环境,根据mode,来决定是读还是NEW;
79 virtual void Close() {
80 if (mdb_env_ != NULL) { //它所做的就是:当所创建的环境的handle 不为空时,说明还没有释放掉;
81 mdb_dbi_close(mdb_env_, mdb_dbi_); //于是呢,把相关的如database的handle,以及mdb_env_释放掉,释放先前的内存;
82 mdb_env_close(mdb_env_);
83 mdb_env_ = NULL;
84 }
85 }
86 virtual LMDBCursor* NewCursor(); //根据mdb_env_,mdb_dbi_,创建了一个LMDBCursor的类;
87 virtual LMDBTransaction* NewTransaction(); //返回一个用mdb_env_初始化了的LMDBTransaction类的指针;
88
89 private:
90 MDB_env* mdb_env_;
91 MDB_dbi mdb_dbi_;
92 };
93
94 } // namespace db
95 } // namespace caffe
96
97 #endif // CAFFE_UTIL_DB_LMDB_HPP
98 #endif // USE_LMDB

db_lmdb.cpp

1 #ifdef USE_LMDB
2 #include "caffe/util/db_lmdb.hpp"
3
4 #include <sys/stat.h>
5
6 #include <string>
7
8 namespace caffe { namespace db {
9
10 void LMDB::Open(const string& source, Mode mode) {
11 MDB_CHECK(mdb_env_create(&mdb_env_));
12 if (mode == NEW) {
13 CHECK_EQ(mkdir(source.c_str(), 0744), 0) << "mkdir " << source << " failed"; //如果为NEW, 则创建一个source的路径;
14 }
15 int flags = 0;
16 if (mode == READ) {
17 flags = MDB_RDONLY | MDB_NOTLS; //设置一下它的特别选项,一个是只读,一个是不使用线程本地存储;
18 }
19 int rc = mdb_env_open(mdb_env_, source.c_str(), flags, 0664);
20 #ifndef ALLOW_LMDB_NOLOCK
21 MDB_CHECK(rc);
22 #else
23 if (rc == EACCES) { //表示:the user didn't have permission to access the environment files.
24 LOG(WARNING) << "Permission denied. Trying with MDB_NOLOCK ...";
25 // Close and re-open environment handle
26 mdb_env_close(mdb_env_);
27 MDB_CHECK(mdb_env_create(&mdb_env_));
28 // Try again with MDB_NOLOCK
29 flags |= MDB_NOLOCK; //增加了一个选项,它的意思为不作任何锁操作;
30 MDB_CHECK(mdb_env_open(mdb_env_, source.c_str(), flags, 0664));
31 } else {
32 MDB_CHECK(rc);
33 }
34 #endif
35 LOG(INFO) << "Opened lmdb " << source;
36 }
37
38 LMDBCursor* LMDB::NewCursor() {
39 MDB_txn* mdb_txn;
40 MDB_cursor* mdb_cursor;
41 MDB_CHECK(mdb_txn_begin(mdb_env_, NULL, MDB_RDONLY, &mdb_txn));
42 MDB_CHECK(mdb_dbi_open(mdb_txn, NULL, 0, &mdb_dbi_));
43 MDB_CHECK(mdb_cursor_open(mdb_txn, mdb_dbi_, &mdb_cursor));
44 return new LMDBCursor(mdb_txn, mdb_cursor); //不明白为什么把局部的mdb_txn返回去,在LMDBCursor类里面,也就析构函数用到了mdb_txn,
45 //可以就是为了去用函数mdb_txn_abort把它干掉吧;,似乎明白了呢,等用完它,把它干掉吧;
46 }
47
48 LMDBTransaction* LMDB::NewTransaction() {
49 return new LMDBTransaction(mdb_env_);
50 }
51
52 void LMDBTransaction::Put(const string& key, const string& value) {
53 keys.push_back(key);
54 values.push_back(value);
55 }
56
57 void LMDBTransaction::Commit() {
58 MDB_dbi mdb_dbi;
59 MDB_val mdb_key, mdb_data;
60 MDB_txn *mdb_txn;
61
62 // Initialize MDB variables
63 MDB_CHECK(mdb_txn_begin(mdb_env_, NULL, 0, &mdb_txn));
64 MDB_CHECK(mdb_dbi_open(mdb_txn, NULL, 0, &mdb_dbi));
65
66 for (int i = 0; i < keys.size(); i++) {
67 mdb_key.mv_size = keys[i].size();
68 mdb_key.mv_data = const_cast<char*>(keys[i].data());
69 mdb_data.mv_size = values[i].size();
70 mdb_data.mv_data = const_cast<char*>(values[i].data());
71
72 // Add data to the transaction
73 int put_rc = mdb_put(mdb_txn, mdb_dbi, &mdb_key, &mdb_data, 0); //即把key/data的值放入database里去;
74 if (put_rc == MDB_MAP_FULL) {
75 // Out of memory - double the map size and retry
76 mdb_txn_abort(mdb_txn);
77 mdb_dbi_close(mdb_env_, mdb_dbi);
78 DoubleMapSize();
79 Commit(); //不明白 为什么能调用 Commit(),回去复习一下C++;
80 return;
81 }
82 // May have failed for some other reason
83 MDB_CHECK(put_rc);
84 }
85
86 // Commit the transaction
87 int commit_rc = mdb_txn_commit(mdb_txn);
88 if (commit_rc == MDB_MAP_FULL) {
89 // Out of memory - double the map size and retry
90 mdb_dbi_close(mdb_env_, mdb_dbi);
91 DoubleMapSize();
92 Commit();
93 return;
94 }
95 // May have failed for some other reason
96 MDB_CHECK(commit_rc);
97
98 // Cleanup after successful commit
99 mdb_dbi_close(mdb_env_, mdb_dbi);
100 keys.clear(); //清空keys and values;
101 values.clear();
102 }
103
104 void LMDBTransaction::DoubleMapSize() {
105 struct MDB_envinfo current_info;
106 MDB_CHECK(mdb_env_info(mdb_env_, &current_info));
107 size_t new_size = current_info.me_mapsize * 2;
108 DLOG(INFO) << "Doubling LMDB map size to " << (new_size>>20) << "MB ...";
109 MDB_CHECK(mdb_env_set_mapsize(mdb_env_, new_size));
110 }
111
112 } // namespace db
113 } // namespace caffe
114 #endif // USE_LMDB
上一篇:对opencv.hpp头文件的认识


下一篇:cordova编译报错:Execution failed for task ':processDebugResources'