zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    JVM-堆内存
    生产者消费者模式-基于线程池
    nginx 499错误
    thrift入门
    RPC-基于原生java实现
    rocketMQ入门
    跟着刚哥深入学maven(通俗易懂)
    跟着刚哥学习Spring框架--AOP(五)
    跟着刚哥学习Spring框架--通过注解方式配置Bean(四)
    跟着刚哥学习Spring框架--Spring容器(二)
  • 原文地址:https://www.cnblogs.com/yinheyi/p/5988158.html
Copyright © 2011-2022 走看看