当前位置:Gxlcms > 数据库问题 > caffe的db_lmdb.hpp文件

caffe的db_lmdb.hpp文件

时间:2021-07-01 10:21:17 帮助过:16人阅读

#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

caffe的db_lmdb.hpp文件

标签:char   files   key   clear   nbsp   class   failed   入参   div   

人气教程排行