`
febird
  • 浏览: 246867 次
  • 性别: 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 读取样例

    嵌入式数据库Berkeley DB Java Edition Berkeley DB的使用 使用Berkeley DB的一般步骤 创建、打开、操作、关闭数据库环境Environment

    berkeley db使用手册

    berkeley db 使用手册

    Berkeley DB4.8以上各版本

    Berkeley DB4.8以上各版本,已经亲测过哪些版本可与redhat6.5兼容,见附件名称备注。

    Berkeley db使用方法简介(c接口)

    Berkeley db使用方法简介(c接口) 非SQL的高速内存数据库的使用方法,简单明了..

    Berkeley DB Java 版 4.0.92

    Oracle Berkeley DB Java 版是一个开源的、可嵌入的事务存储引擎,是完全用 Java 编写的。与 Oracle Berkeley DB 类似,Oracle Berkeley DB Java 版在应用程序的地址空间中执行,没有客户端/服务器通信的开销,从而...

    Berkeley DB

    Berkeley DB(BDB)是OpenLDAP后台数据库的默认配置,因此在安装OpenLDAP之前应先安装BDB。

    Berkeley DB数据库 6.2.32 64位

    多个进程,或者同一进程的多个线程可同时使用数据库,有如各自单独使用,底层的服务如加锁、事务日志、共享缓冲区管理、内存管理等等都由程序库透明地执行。 轻便灵活:可以运行于几乎所有的UNIX和Linux系统及其变种...

    BerkeleyDB测试程序

    BerkeleyDB测试程序 包含散列文件入库,和读取的速度的测试

    Berkeley DB文章集合

    Berkeley DB文章集合

    Berkeley DB 5.3.21.tar

    Berkeley DB 5.3.21.tar,你也可以去http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html下载最新版

    BerkeleyDB

    BerkeleyDB的java应用jar包

    Berkeley DB数据库最新版

    Berkeley DB6.0.20 Berkeley DB BDB Berkeley DB数据库

    BerkeleyDB-JE je-6.0.11

    Oracle BerkeleyDB-JE je-6.0.11

    sqlite PK Berkeley DB

    sqlite 和Berkeley db各方面 的比较

    BerkeleyDB Java Edition用户手册

    Java版本的Berkeley DB用户手册,找了好久

    BerkeleyDB-0.26

    BerkeleyDB和Sqlite是当前最流行的嵌入式开源数据库。

    Berkeley DB数据库支持事物的C++语言入门教程

    本文描述了如何在Berkeley DB中使用事务(Transaction)。它简要介绍了事务是如何保护你的应用的数据的...本书假设你已经了解BerkeleyDB的基本架构知识(这些知识在&lt;Getting Started with Berkeley DB Guide&gt;一书中。)

    Berkeley DB C++编程入门教

    介绍DB API的设置与使用的快速入门手册,目标是提供一个快速有效地机制,能让你进入Berkeley DB研发的世界。在本文中侧重于C++语言的研发人员,以及研究进城内数据管理解决方案的资深架构师。

    SQL 开发人员 Oracle Berkeley DB 指南

    不是所有的 SQL 应用程序都应该在 Oracle Berkeley DB 实施( Oracle Berkeley DB 是一个开放源的嵌入式数据库引擎,提供了快速、可靠、本地的持久性,无需管理),但如果您有一系列相对固定的查询且很关心性能,...

Global site tag (gtag.js) - Google Analytics