`
febird
  • 浏览: 254241 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

持久化的多键映射,使用BerkeleyDB

阅读更多

项目地址:http://code.google.com/p/febird

 

 如前介绍,相当于 std::map<Key1,std::map<Key2,Data> >,但接口也不完全相同,这里只贴代码:

 

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_bdb_kmapdset_h__
  3. #define __febird_bdb_kmapdset_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include <db_cxx.h>
  8. #include "native_compare.h"
  9. #include "../io/DataIO.h"
  10. #include "../io/MemStream.h"
  11. #include "../refcount.h"
  12. namespace febird {
  13. class FEBIRD_DLL_EXPORT kmapdset_iterator_impl_base : public RefCounter
  14. {
  15. public:
  16.     class kmapdset_base* m_owner;
  17.     DBC* m_curp;
  18.     int  m_ret;
  19.     DBT  m_bulk;
  20. public:
  21.     kmapdset_iterator_impl_base(class kmapdset_base* owner);
  22.     void init(DB* dbp, DB_TXN* txn, const char* func);
  23.     virtual ~kmapdset_iterator_impl_base();
  24.     virtual void clear_vec() = 0;
  25.     virtual void push_back(void* data, size_t size) = 0;
  26.     virtual void load_key1(void* data, size_t size) = 0;
  27.     virtual void save_key1(PortableDataOutput<AutoGrownMemIO>& oKey) = 0;
  28.     bool next_key(size_t* cnt, const char* func);
  29.     void bulk_load(DBT* tk1);
  30.     void increment(const char* func);
  31.     void decrement(const char* func);
  32.     bool find_pos(const void* k1, const void* k2, bool bulk, const char* func);
  33.     bool insert(const void* d, const char* func);
  34.     bool update(const void* d, const char* func);
  35.     bool replace(const void* d, const char* func);
  36.     bool remove(const void* k2, const char* func);
  37.     bool remove(const char* func);
  38. };
  39. class FEBIRD_DLL_EXPORT kmapdset_base
  40. {
  41.     DECLARE_NONE_COPYABLE_CLASS(kmapdset_base)
  42. public:
  43.     DB*    m_db;
  44.     size_t m_bulkSize;
  45.     bt_compare_fcn_type m_bt_comp, m_dup_comp;
  46.     kmapdset_base(DB_ENV* env, const char* dbname
  47.         , DB_TXN* txn
  48.         , bt_compare_fcn_type bt_comp
  49.         , bt_compare_fcn_type dup_comp
  50.         , const char* func
  51.         );
  52.     virtual ~kmapdset_base();
  53.     virtual void save_key1(PortableDataOutput<AutoGrownMemIO>& dio, const void* key1) const = 0;
  54.     virtual void save_key2(PortableDataOutput<AutoGrownMemIO>& dio, const void* key2) const = 0;
  55.     virtual void save_data(PortableDataOutput<AutoGrownMemIO>& dio, const void* data) const = 0;
  56.     virtual kmapdset_iterator_impl_base* make_iter() = 0;
  57.     kmapdset_iterator_impl_base* begin_impl(DB_TXN* txn, const char* func);
  58.     kmapdset_iterator_impl_base* end_impl(DB_TXN* txn, const char* func);
  59.     kmapdset_iterator_impl_base* find_impl(const void* k1, DB_TXN* txn, u_int32_t flags, const char* func);
  60.     kmapdset_iterator_impl_base* find_impl(const void* k1, const void* k2, DB_TXN* txn, bool bulk, const char* func);
  61.     kmapdset_iterator_impl_base* upper_bound_impl(const void* k1, DB_TXN* txn, const char* func);
  62.     size_t count_impl(const void* k1, DB_TXN* txn, const char* func);
  63.     bool insert_impl(const void* k1, const void* d, DB_TXN* txn, const char* func);
  64.     bool replace_impl(const void* k1, const void* d, DB_TXN* txn, const char* func);
  65.     bool remove_impl(const void* k1, const void* k2, DB_TXN* txn, const char* func);
  66.     bool remove_impl(const void* k1, DB_TXN* txn, const char* func);
  67.     void clear_impl(DB_TXN* txn, const char* func);
  68.     void flush_impl(const char* func);
  69. };
  70. template<class Data>
  71. struct kmapdset_select_key2
  72. {
  73.     typedef typename Data::key_type type;
  74. };
  75. template<class Key2, class NonKeyData>
  76. struct kmapdset_select_key2<std::pair<Key2, NonKeyData> >
  77. {
  78.     typedef Key2 type;
  79. };
  80. template<class Key1, class Key2, class Data, class Value, class Impl>
  81. class kmapdset_iterator :
  82.     public std::iterator<std::bidirectional_iterator_tag, Value, ptrdiff_tconst Value*, const Value&>
  83. {
  84.     boost::intrusive_ptr<Impl> m_impl;
  85.     void copy_on_write()
  86.     {
  87.         if (m_impl->getRefCount() > 1)
  88.         {
  89.             Impl* p = new Impl(m_impl->m_owner);
  90.             m_impl->m_ret = m_impl->m_curp->dup(m_impl->m_curp, &p->m_curp, DB_POSITION);
  91.             FEBIRD_RT_assert(0 == m_impl->m_ret, std::runtime_error);
  92.             m_impl.reset(p);
  93.         }
  94.     }
  95. private:
  96. #ifdef _MSC_VER
  97. //# pragma warning(disable: 4661) // declaration but not definition
  98. //! MSVC will warning C4661 "declaration but not definition"
  99. void operator++(int) { assert(0); }
  100. void operator--(int) { assert(0); }
  101. #else
  102. //! disable, because clone iterator will cause very much time and resource
  103. void operator++(int);// { assert(0); }
  104. void operator--(int);// { assert(0); }
  105. #endif
  106. public:
  107.     kmapdset_iterator() {}
  108.     explicit kmapdset_iterator(kmapdset_iterator_impl_base* impl)
  109.         : m_impl(static_cast<Impl*>(impl))
  110.     {
  111.         assert(impl);
  112.         assert(dynamic_cast<Impl*>(impl));
  113.     }
  114. //  bool exist() const { return DB_NOTFOUND != m_impl->m_ret && DB_KEYEMPTY != m_impl->m_ret; }
  115.     bool exist() const { return 0 == m_impl->m_ret; }
  116.     // increment and get key/data-cnt
  117.     bool next_key(size_t& cnt) { return m_impl->next_key(&cnt,BOOST_CURRENT_FUNCTION); }
  118.     bool insert(const Data& d) { return m_impl->insert(&d,BOOST_CURRENT_FUNCTION); }
  119.     bool update(const Data& d) { return m_impl->update(&d,BOOST_CURRENT_FUNCTION); }
  120.     bool replace(const Data& d) { return m_impl->replace(&d,BOOST_CURRENT_FUNCTION); }
  121.     bool remove() const { return m_impl->remove(BOOST_CURRENT_FUNCTION); }
  122.     bool remove(const Key2& k2) const { return m_impl->remove(&k2,BOOST_CURRENT_FUNCTION); }
  123.     kmapdset_iterator& operator++()
  124.     {
  125.         assert(0 == m_impl->m_ret);
  126.         copy_on_write();
  127.         m_impl->increment(BOOST_CURRENT_FUNCTION);
  128.         return *this;
  129.     }
  130.     kmapdset_iterator& operator--()
  131.     {
  132.         assert(0 == m_impl->m_ret);
  133.         copy_on_write();
  134.         m_impl->decrement(BOOST_CURRENT_FUNCTION);
  135.         return *this;
  136.     }
  137.     const Value& operator*() const
  138.     {
  139.         assert(0 == m_impl->m_ret);
  140.         return m_impl->m_kdv;
  141.     }
  142.     const Value* operator->() const
  143.     {
  144.         assert(0 == m_impl->m_ret);
  145.         return &m_impl->m_kdv;
  146.     }
  147.     Value& get_mutable() const
  148.     {
  149.         assert(0 == m_impl->m_ret);
  150.         return m_impl->m_kdv;
  151.     }
  152. };
  153. //! @param Data Key2 is embeded in Data
  154. template<class Key1, class Data>
  155. class kmapdset : protected kmapdset_base
  156. {
  157.     DECLARE_NONE_COPYABLE_CLASS(kmapdset)
  158. public:
  159.     typedef Key1
  160.             key1_t, key_type;
  161.     typedef typename kmapdset_select_key2<Data>::type
  162.             key2_t;
  163.     typedef Data
  164.             data_type, data_t;
  165.     typedef std::pair<Key1, std::vector<Data> >
  166.             value_type;
  167.     typedef std::vector<Data>
  168.             data_vec_t;
  169.     typedef typename std::vector<Data>::const_iterator
  170.             data_iter_t;
  171. protected:
  172.     class kmapdset_iterator_impl : public kmapdset_iterator_impl_base
  173.     {
  174.     public:
  175.         value_type m_kdv;
  176.         kmapdset_iterator_impl(kmapdset_base* owner)
  177.             : kmapdset_iterator_impl_base(owner)
  178.         {}
  179.         virtual void clear_vec()
  180.         {
  181.             m_kdv.second.resize(0);
  182.         }
  183.         virtual void push_back(void* data, size_t size)
  184.         {
  185.             Data x;
  186.             PortableDataInput<MinMemIO> iData;
  187.             iData.set(data);
  188.             iData >> x;
  189.             FEBIRD_RT_assert(iData.diff(data) == size, std::logic_error);
  190.             m_kdv.second.push_back(x);
  191.         }
  192.         virtual void load_key1(void* data, size_t size)
  193.         {
  194.             PortableDataInput<MemIO> iKey1;
  195.             iKey1.set(data, size);
  196.             iKey1 >> m_kdv.first;
  197.             FEBIRD_RT_assert(iKey1.diff(data) == size, std::logic_error);
  198.         }
  199.         virtual void save_key1(PortableDataOutput<AutoGrownMemIO>& oKey1)
  200.         {
  201.             oKey1 << m_kdv.first;
  202.         }
  203.     };
  204.     //! overrides
  205.     void save_key1(PortableDataOutput<AutoGrownMemIO>& dio, const void* key1) const { dio << *(const key1_t*)key1; }
  206.     void save_key2(PortableDataOutput<AutoGrownMemIO>& dio, const void* key2) const { dio << *(const key2_t*)key2; }
  207.     void save_data(PortableDataOutput<AutoGrownMemIO>& dio, const void* data) const { dio << *(const data_t*)data; }
  208.     kmapdset_iterator_impl_base* make_iter() { return new kmapdset_iterator_impl(this); }
  209. public:
  210.     typedef kmapdset_iterator<Key1, key2_t, Data, value_type, kmapdset_iterator_impl>
  211.             iterator, const_iterator;
  212.     kmapdset(DB_ENV* env, const char* dbname
  213.         , DB_TXN* txn = NULL
  214.         , bt_compare_fcn_type bt_comp = bdb_auto_bt_compare((key1_t*)(0))
  215.         , bt_compare_fcn_type dup_comp = bdb_auto_bt_compare((key2_t*)(0))
  216.         )
  217.         : kmapdset_base(env, dbname, txn, bt_comp, dup_comp, BOOST_CURRENT_FUNCTION)
  218.     {
  219.     }
  220.     kmapdset(DbEnv* env, const char* dbname
  221.         , DbTxn* txn = NULL
  222.         , bt_compare_fcn_type bt_comp = bdb_auto_bt_compare((key1_t*)(0))
  223.         , bt_compare_fcn_type dup_comp = bdb_auto_bt_compare((key2_t*)(0))
  224.         )
  225.         : kmapdset_base(env->get_DB_ENV(), dbname, txn ? txn->get_DB_TXN() : NULL, bt_comp, dup_comp, BOOST_CURRENT_FUNCTION)
  226.     {
  227.     }
  228.     iterator begin(DB_TXN* txn = NULL) { return iterator(begin_impl(txn, BOOST_CURRENT_FUNCTION)); }
  229.     iterator end  (DB_TXN* txn = NULL) { return iterator(end_impl  (txn, BOOST_CURRENT_FUNCTION)); }
  230.     iterator begin(DbTxn* txn) { return iterator(begin_impl(txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION)); }
  231.     iterator end  (DbTxn* txn) { return iterator(end_impl  (txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION)); }
  232.     iterator find(const Key1& k1, DB_TXN* txn = NULL)
  233.     {
  234.         return iterator(find_impl(&k1, txn, DB_SET|DB_MULTIPLE, BOOST_CURRENT_FUNCTION));
  235.     }
  236.     iterator find(const Key1& k1, DbTxn* txn)
  237.     {
  238.         return iterator(find_impl(&k1, txn->get_DB_TXN(), DB_SET|DB_MULTIPLE, BOOST_CURRENT_FUNCTION));
  239.     }
  240.     iterator find(const Key1& k1, const key2_t& k2, DB_TXN* txn = NULL)
  241.     {
  242.         return iterator(find_impl(&k1, &k2, txn, false, BOOST_CURRENT_FUNCTION));
  243.     }
  244.     iterator find(const Key1& k1, const key2_t& k2, DbTxn* txn)
  245.     {
  246.         return iterator(find_impl(&k1, &k2, txn->get_DB_TXN(), false, BOOST_CURRENT_FUNCTION));
  247.     }
  248.     iterator find_md(const Key1& k1, const key2_t& k2, DB_TXN* txn = NULL)
  249.     {
  250.         return iterator(find_impl(&k1, &k2, txn, true, BOOST_CURRENT_FUNCTION));
  251.     }
  252.     iterator find_md(const Key1& k1, const key2_t& k2, DbTxn* txn)
  253.     {
  254.         return iterator(find_impl(&k1, &k2, txn->get_DB_TXN(), true, BOOST_CURRENT_FUNCTION));
  255.     }
  256.     iterator lower_bound(const Key1& k1, DB_TXN* txn = NULL)
  257.     {
  258.         return iterator(find_impl(&k1, txn, DB_SET_RANGE|DB_MULTIPLE, BOOST_CURRENT_FUNCTION));
  259.     }
  260.     iterator lower_bound(const Key1& k1, DbTxn* txn)
  261.     {
  262.         return iterator(find_impl(&k1, txn->get_DB_TXN(), DB_SET_RANGE|DB_MULTIPLE, BOOST_CURRENT_FUNCTION));
  263.     }
  264.     iterator upper_bound(const Key1& k1, DB_TXN* txn = NULL)
  265.     {
  266.         return iterator(upper_bound_impl(&k1, txn, BOOST_CURRENT_FUNCTION));
  267.     }
  268.     bool insert(const Key1& k1, const Data& d, DB_TXN* txn = NULL)
  269.     {
  270.         return insert_impl(&k1, &d, txn, BOOST_CURRENT_FUNCTION);
  271.     }
  272.     bool insert(const Key1& k1, const Data& d, DbTxn* txn)
  273.     {
  274.         return insert_impl(&k1, &d, txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION);
  275.     }
  276.     bool replace(const Key1& k1, const Data& d, DB_TXN* txn = NULL)
  277.     {
  278.         return replace_impl(&k1, &d, txn, BOOST_CURRENT_FUNCTION);
  279.     }
  280.     bool replace(const Key1& k1, const Data& d, DbTxn* txn)
  281.     {
  282.         return replace_impl(&k1, &d, txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION);
  283.     }
  284.     bool remove(const Key1& k1, const key2_t& k2, DB_TXN* txn = NULL)
  285.     {
  286.         return remove_impl(&k1, &k2, txn, BOOST_CURRENT_FUNCTION);
  287.     }
  288.     bool remove(const Key1& k1, const key2_t& k2, DbTxn* txn)
  289.     {
  290.         return remove_impl(&k1, &k2, txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION);
  291.     }
  292.     bool remove(const Key1& k1, DB_TXN* txn = NULL)
  293.     {
  294.         return remove_impl(&k1, txn, BOOST_CURRENT_FUNCTION);
  295.     }
  296.     bool remove(const Key1& k1, DbTxn* txn)
  297.     {
  298.         return remove_impl(&k1, txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION);
  299.     }
  300.     bool erase(const iterator& iter)
  301.     {
  302.         return iter.remove();
  303.     }
  304.     void clear(DB_TXN* txn = NULL)
  305.     {
  306.         clear_impl(txn, BOOST_CURRENT_FUNCTION);
  307.     }
  308.     void clear(DbTxn* txn)
  309.     {
  310.         return clear_impl(txn->get_DB_TXN(), BOOST_CURRENT_FUNCTION);
  311.     }
  312.     void flush()
  313.     {
  314.         return flush_impl(BOOST_CURRENT_FUNCTION);
  315.     }
  316.     size_t count(const Key1& k1, DB_TXN* txn = NULL)
  317.     {
  318.         return count_impl(&k1, txn, BOOST_CURRENT_FUNCTION);
  319.     }
  320.     size_t count(const Key1& k1, DbTxn* txn)
  321.     {
  322.         return count_impl(&k1, txn ? txn->get_DB_TXN() : NULL, BOOST_CURRENT_FUNCTION);
  323.     }
  324.     DB* getDB() { return m_db; }
  325.     const DB* getDB() const { return m_db; }
  326. };
  327. // namespace febird
  328. #endif // __febird_bdb_kmapdset_h__

 

  1. /* vim: set tabstop=4 : */
  2. #include "kmapdset.h"
  3. //#include "../DataBuffer.h"
  4. #include <sstream>
  5. namespace febird {
  6. kmapdset_iterator_impl_base::kmapdset_iterator_impl_base(class kmapdset_base* owner)
  7.     : m_owner(owner)
  8.     , m_curp(0), m_ret(-1)
  9. {
  10.     memset(&m_bulk, 0, sizeof(DBT));
  11.     m_bulk.size = (owner->m_bulkSize);
  12.     m_bulk.data = (::malloc(owner->m_bulkSize));
  13.     m_bulk.flags = (DB_DBT_USERMEM);
  14.     m_bulk.ulen = (owner->m_bulkSize);
  15. }
  16. void kmapdset_iterator_impl_base::init(DB* dbp, DB_TXN* txn, const char* func)
  17. {
  18.     int ret = dbp->cursor(dbp, txn, &m_curp, 0);
  19.     if (0 != ret)
  20.     {
  21.         delete this;
  22.         std::ostringstream oss;
  23.         oss << db_strerror(ret) << "... at: " << func;
  24.         throw std::runtime_error(oss.str());
  25.     }
  26.     m_ret = 0;
  27. }
  28. kmapdset_iterator_impl_base::~kmapdset_iterator_impl_base()
  29. {
  30.     if (m_bulk.data)
  31.         ::free(m_bulk.data);
  32.     if (m_curp)
  33.         m_curp->close(m_curp);
  34. }
  35. bool kmapdset_iterator_impl_base::next_key(size_t* cnt, const char* func)
  36. {
  37.     FEBIRD_RT_assert(0 == m_ret, std::logic_error);
  38.     DBT tk1; memset(&tk1, 0, sizeof(DBT));
  39.     m_ret = m_curp->get(m_curp, &tk1, &m_bulk, DB_NEXT_NODUP);
  40.     if (0 == m_ret)
  41.     {
  42.         load_key1(tk1.data, tk1.size);
  43.         db_recno_t cnt0 = 0;
  44.         int ret = m_curp->count(m_curp, &cnt0, 0);
  45.         if (0 != ret)
  46.         {
  47.             std::ostringstream oss;
  48.             oss << db_strerror(ret) << "... at: " << func;
  49.             throw std::runtime_error(oss.str());
  50.         }
  51.         *cnt = cnt0;
  52.         return true;
  53.     }
  54.     else if (DB_NOTFOUND == m_ret)
  55.     {
  56.         return false;
  57.     }
  58.     else
  59.     {
  60.         std::ostringstream oss;
  61.         oss << db_strerror(m_ret) << "... at: " << func;
  62.         throw std::runtime_error(oss.str());
  63.     }
  64. }
  65. void kmapdset_iterator_impl_base::bulk_load(DBT* tk1)
  66. {
  67.     FEBIRD_RT_assert(0 == m_ret, std::logic_error);
  68.     load_key1(tk1->data, tk1->size);
  69.     clear_vec();
  70.     int ret;
  71.     do {
  72.         void  *bptr, *data;
  73.         size_t size;
  74.         DB_MULTIPLE_INIT(bptr, &m_bulk);
  75.         assert(NULL != bptr);
  76.         for (;;)
  77.         {
  78.             DB_MULTIPLE_NEXT(bptr, &m_bulk, data, size);
  79.             if (bptr)
  80.                 this->push_back(data, size);
  81.             else
  82.                 break;
  83.         }
  84.         ret = m_curp->get(m_curp, tk1, &m_bulk, DB_MULTIPLE|DB_NEXT_DUP);
  85.     } while (0 == ret);
  86. }
  87. void kmapdset_iterator_impl_base::increment(const char* func)
  88. {
  89.     FEBIRD_RT_assert(0 == m_ret, std::logic_error);
  90.     DBT tk1; memset(&tk1, 0, sizeof(DBT));
  91.     m_ret = m_curp->get(m_curp, &tk1, &m_bulk, DB_NEXT_NODUP|DB_MULTIPLE);
  92.     if (0 == m_ret)
  93.     {
  94.         bulk_load(&tk1);
  95.     }
  96.     else if (DB_NOTFOUND != m_ret)
  97.     {
  98.         std::ostringstream oss;
  99.         oss << db_strerror(m_ret) << "... at: " << func;
  100.         throw std::runtime_error(oss.str());
  101.     }
  102. }
  103. void kmapdset_iterator_impl_base::decrement(const char* func)
  104. {
  105.     FEBIRD_RT_assert(0 == m_ret, std::logic_error);
  106.     DBT tk1; memset(&tk1, 0, sizeof(DBT));
  107.     m_ret = m_curp->get(m_curp, &tk1, &m_bulk, DB_PREV_NODUP);
  108.     if (0 == m_ret)
  109.     {
  110.         m_ret = m_curp->get(m_curp, &tk1, &m_bulk, DB_CURRENT|DB_MULTIPLE);
  111.         if (0 == m_ret)
  112.         {
  113.             bulk_load(&tk1);
  114.         }
  115.         else if (DB_KEYEMPTY == m_ret)
  116.         {
  117.             std::ostringstream oss;
  118.             oss << db_strerror(m_ret)
  119.                 << "... at: " << func;
  120.             throw std::runtime_error(oss.str());
  121.         }
  122.     }
  123.     else if (DB_NOTFOUND != m_ret)
  124.     {
  125.         std::ostringstream oss;
  126.         oss << db_strerror(m_ret) << "... at: " << func;
  127.         throw std::runtime_error(oss.str());
  128.     }
  129. }
  130. bool kmapdset_iterator_impl_base::find_pos(const void* k1, const void* k2, bool bulk, const char* func)
  131. {
  132.     PortableDataOutput<AutoGrownMemIO> oKey1, oKey2;
  133.     m_owner->save_key1(oKey1, k1);
  134.     m_owner->save_key2(oKey2, k2);
  135.     DBT tk1; memset(&tk1, 0, sizeof(DBT)); tk1.data = oKey1.begin(); tk1.size = oKey1.tell();
  136.     DBT tk2; memset(&tk2, 0, sizeof(DBT)); tk2.data = oKey2.begin(); tk2.size = oKey2.tell();
  137.     m_ret = m_curp->get(m_curp, &tk1, &tk2, DB_GET_BOTH);
  138.     if (0 == m_ret)
  139.     {
  140.         if (bulk) {
  141.             m_ret = m_curp->get(m_curp, &tk1, &m_bulk, DB_CURRENT|DB_MULTIPLE);
  142.             if (0 == m_ret) {
  143.                 bulk_load(&tk1);
  144.                 return true;
  145.             }
  146.         } else {
  147.             clear_vec();
  148.             load_key1(tk1.data, tk1.size);
  149.             push_back(tk2.data, tk2.size);
  150.             return true;
  151.         }
  152.     }
  153.     else if (DB_NOTFOUND == m_ret)
  154.     {
  155.         return false;
  156.     }
  157.     std::ostringstream oss;
  158.     oss << db_strerror(m_ret)
  159.         << "... at: " << func
  160.         << "\n"
  161.         ;
  162.     throw std::runtime_error(oss.str());
  163. }
  164. /**
  165.  @brief 
  166.  @return true successful inserted
  167.         false fail, (key1, d) existed, and not inserted
  168.  @throw other errors
  169.  */
  170. bool kmapdset_iterator_impl_base::insert(const void* d, const char* func)
  171. {
  172.     FEBIRD_RT_assert(0 == m_ret || DB_NOTFOUND == m_ret || DB_KEYEXIST == m_ret, std::logic_error);
  173.     PortableDataOutput<AutoGrownMemIO> oKey1, oData;
  174.     this->save_key1(oKey1);
  175.     m_owner->save_data(oData, d);
  176.     DBT tk1; memset(&tk1, 0, sizeof(DBT)); tk1.data = oKey1.begin(); tk1.size = oKey1.tell();
  177.     DBT tdd; memset(&tdd, 0, sizeof(DBT)); tdd.data = oData.begin(); tdd.size = oData.tell();
  178.     int ret = m_curp->put(m_curp, &tk1, &tdd, DB_NODUPDATA);
  179.     if (DB_KEYEXIST == ret)
  180.         return false;
  181.     if (0 == ret)
  182.         return true;
  183.     std::ostringstream oss;
  184.     oss << db_strerror(m_ret)
  185.         << "... at: " << func;
  186.     throw std::runtime_error(oss.str());
  187. }
  188. /**
  189.  @brief 
  190.  @return true successful updated
  191.         false (key1, d.key2) did not exist, not updated
  192.  @throw other errors
  193.  */
  194. bool kmapdset_iterator_impl_base::update(const void* d, const char* func)
  195. {
  196.     FEBIRD_RT_assert(0 == m_ret, std::logic_error);
  197.     PortableDataOutput<AutoGrownMemIO> oKey1, oData;
  198.     this->save_key1(oKey1);
  199.     m_owner->save_data(oData, d);
  200.     DBT tk1; memset(&tk1, 0, sizeof(DBT)); tk1.data = oKey1.begin(); tk1.size = oKey1.tell();
  201.     DBT tdd; memset(&tdd, 0, sizeof(DBT)); tdd.data = oData.begin(); tdd.size = oData.tell();
  202.     int ret = m_curp->get(m_curp, &tk1, &tdd, DB_GET_BOTH);
  203.     if (0 == ret)
  204.     {
  205.         tk1.data = oKey1.begin(); tk1.size = oKey1.tell();
  206.         tdd.data = oData.begin(); tdd.size = oData.tell();
  207.         ret = m_curp->put(m_curp, &tk1, &tdd, DB_CURRENT);
  208.         if (0 == ret)
  209.             return true;
  210.     }
  211.     else if (DB_NOTFOUND == ret)
  212.     {
  213.         return false;
  214.     }
  215.     std::ostringstream oss;
  216.     oss << db_strerror(ret)
  217.         << "... at: " << func;
  218.     throw std::runtime_error(oss.str());
  219. }
  220. /**
  221.  @brief 
  222.  @return true  item was replaced by (key1,d)
  223.          false item was inserted
  224.  @throw  other errors
  225.  */
  226. bool kmapdset_iterator_impl_base::replace(const void* d, const char* func)
  227. {
  228.     PortableDataOutput<AutoGrownMemIO> oKey1, oData;
  229.     this->save_key1(oKey1);
  230.     m_owner->save_data(oData, d);
  231.     DBT tk1; memset(&tk1, 0, sizeof(DBT)); tk1.data = oKey1.begin(); tk1.size = oKey1.tell();
  232.     DBT tdd; memset(&tdd, 0, sizeof(DBT)); tdd.data = oData.begin(); tdd.size = oData.tell();
  233.     int ret = m_curp->get(m_curp, &tk1, &tdd, DB_GET_BOTH);
  234.     if (0 == ret)
  235.  
分享到:
评论

相关推荐

    Berkeley DB

    4. **内存映射**:Berkeley DB支持将数据库文件映射到进程的内存空间,提高了数据访问速度,降低了I/O操作。 5. **跨平台兼容**:Berkeley DB可在多种操作系统上运行,包括Linux、Windows、Unix以及各种嵌入式系统...

    lmdb_c++使用代码

    LMDB(Lightning Memory-Mapped Database)是一种轻量级、高性能、嵌入式的键值对存储数据库,由Berkeley DB作者开发。它使用内存映射文件技术,将数据存储在磁盘上,但通过内存映射使得访问速度接近于内存。这种...

    Oracle中BDB数据库的使用方法

    Oracle中的BDB(Berkeley DB)数据库是一种轻量级、高性能的数据存储解决方案,尤其适合用于对数据快速存取和小型项目的需求。BDB是Oracle公司收购Sleepycat Software后得到的一种开源、嵌入式数据库系统,它以键/值...

    基于Java的磁盘的KV存储 JDBM2.zip

    Java中的磁盘KV存储是指将键值对(Key-Value pairs)的数据结构持久化到硬盘上,以便在程序运行期间可以高效地进行读写操作。JDBM2是一个开源的、基于Java实现的磁盘KV存储系统,它提供了一种在Java应用程序中实现...

    boltdb源码解析.pptx

    BoltDB 是一款轻量级、嵌入式的键值对数据库,主要应用于Go语言环境。它的设计灵感来自于 Berkeley DB,但简化...在实际开发中,BoltDB因其简洁和高效,常被用于需要本地持久化存储的场景,例如配置管理、缓存服务等。

    Python库 | lmdb-0.97-cp34-cp34m-win32.whl

    `lmdb`在Python中的应用主要涉及到数据持久化、高速查找和低延迟的数据访问场景。 **1. LMDB的特点** - **内存映射**:LMDB使用内存映射文件技术,将数据库存储直接映射到进程地址空间,极大地提高了读取速度。 - ...

    lmdb-mdb.master.rar

    LMDB(Lightning Memory-Mapped Database)是一种高效、小巧、基于内存映射的键值存储系统,由Berkeley DB的作者之一Jeffrey Stedfast开发。这个“lmdb-mdb.master.rar”压缩包包含了LMDB数据库在Windows平台上的...

    Python库 | lmdb-1.1.1-cp27-cp27m-manylinux2010_x86_64.whl

    - **数据持久化**:即使在程序崩溃或系统断电后,也能确保数据不丢失,因为所有更改都会被立即持久化到磁盘上。 - **空间效率**:自动进行数据压缩,有效节省存储空间。 2. **lmdb的使用** - **安装**:在Python...

    The origin of Bitcask is tied to the history of the Riak distributed database

    例如,BerkeleyDB、Tokyo Cabinet 和 Innostore 等系统在某些方面表现良好,但在其他方面则不尽如人意。这些系统的局限性激发了Riak团队寻找更好的解决方案。 #### 关键洞见 在讨论这个问题时,Eric Brewer 提出了...

    Python Cookbook

    第7章 持久化和数据库 273 引言 273 7.1 使用marshal模块序列化数据 275 7.2 使用pickle和cPickle模块序列化数据 277 7.3 在Pickling的时候压缩 280 7.4 对类和实例使用cPickle模块 281 7.5 Pickling被绑定...

Global site tag (gtag.js) - Google Analytics