FrontPage FindPage TitleIndex RecentChanges UserPreferences E D R S I H C
 
BDB++
FrontPageTitleIndexWordIndexStudyLDAP › BdbPlusPlus
template <Berkley DB>
class bdbplusplus::table_of_contents {
};

1 Announcement

2 About

2.1 What's BDB++?

BDB++ is a C++ Standard Library style API built on top of the Berkeley DB C++ API.
BDB++ allows programmers to utilize Berkeley DB within the C++ Standard Library framework.

2.2 Why BDB++?

If you are a C++ programmer with C++ Standard Library background and you have an experience of Berkeley DB programming, I am sure that you had wished for a cozy C++ Standard Library container/iterator style interface for the Berkeley DB. Conceptually, it is clear that the Berkeley DB database is a container and the cursor to the database is an iterator. However, there weren't such libraries available, as far as I have searched for. As a result, I decied to make one: BDB++. Enjoy!

2.3 Who's in BDB++

Participation Welcomed!

2.4 Supported Platforms

It may work on any platform with Berkeley DB 4.0, 4.1, 4.2, 4.3 and gcc version later than 2.95. Please report me if you have tested with other compilers !

Tested under
  • gcc version 3.3.5 (Debian 1:3.3.5-5) with Berkeley DB 4.0, 4.1, 4.2, 4.3.

/!\ Note:
Only Btree access method is considered because I have never used other access methods. Suggestions and contributions for other access methods are welecomed.


3 Downloads

Version 1.1

Here, you can download the current version;

4 Documentation

4.1 [http]Reference Manual

Powered by [http]Doxygen.

4.2 Design Overview

Berkeley DB C++ API class (option flags)BDB++ class (C++ Standard Library concept)
Db
(DB_BTREE opened without duplicate data)
bdbmap
(almostly, unique/sorted/pair associative container)
Db
(DB_BTREE opened with DB_DUP or DB_DUPSORT)
bdbmultimap
(almostly, unique/sorted/pair associative container)
Dbc
(cursor of DB_BTREE type Db)
bdbmap::iterator, bdbmultimap::iterator
(bidirectional iterator)

The implemented container class for the DB_BTREE access method almostly satisfies the requirements of sorted/pair associative container. That is, it is very similar to the C++ standard library container std::map and std::multimap. See the documentation for more details.

Db class with DB_HASH access method may be modeled as a hash associative container. Db class with DB_RECNO, DB_QUEUE access method may be modeled as sequences. However, there are no plan for these access methods yet. Those who are in need for containers other than DB_BTREE access methods are welcomed as project members.

4.3 Somewhat STRANGE thing that you should be aware of

There are differences between bdbplusplus::bdbmap(or bdbplusplus::bdbmultimap) and std::map(or std::multimap). I will explain why the table above mentions bdbplusplus::bdbmap(or bdbplusplus::bdbmultimap) as "almostly" almostly sorted/pair assiciative container rather than exactly sorted/pair associative container.

For std::map or multimap one can update the values in the container through its iterator as shown below.
std::map<int,int> m;
// ...
std::map::iterator i = m.begin();
// ...
i->second = 3;
   
Howerver, to update the values in the bdbplusplus::map(or bdbplusplus::multimap) through its iterator
bdbplusplus::bdbmap<int,int> m;
// ...
bdbplusplus::bdbmap::iterator i = m.begin();
// ...
i = 3;
   
Assignment operator is overloaded for the container's data_type. . You should not do "i->second = 3;" because the pair is just a memory cache. The real content is in the Berkeley DB. Not in the memory space of ordinary C++ objects. Also, there are no operator [] overloaded for bdbplusplus::map.

There may be some tweeks such as using proxy classes or defining some strange allocators. However, It may complicate the code too much and cause other problems. If you have more elegant approach, please note me or participate in this project. I am not completely satisfied with current design.

While it is possible to do "i->second = 3;" for bdbpulsplus::map::iterator(or bdbpluspuls::multimap::iterator), NEVER do this. It will cause problems. It only update the cache it hodls in the pair object, not the content in the Berkeley DB. This is same for the pkey member also.

5 Example

These are examples inlcluded in the recent distribution.

5.1 bdbmap

#include <iostream>
#include "bdbmap.hpp"

using namespace std;
using namespace bdbplusplus;

typedef bdbmap<int, int> bdbcont;

int main(void)
{
    u_int32_t DBENV_ctor_flag = 0;
    u_int32_t DBENV_open_flag = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE;

    DbEnv dbenv(DBENV_ctor_flag);

    try {
        dbenv.set_error_stream(&cerr);
        dbenv.open("./db_home",DBENV_open_flag,0644);

        try {
            bdbcont cppdb(&dbenv);

            for (int i=0; i<5; i++) cppdb.insert(make_pair(i,i+1));

            for (bdbcont::iterator i=cppdb.begin(); i!=cppdb.end(); ++i)
                cout <<(*i).first <<"," <<i->second <<endl;

            cppdb.insert(make_pair(1,1));
            cppdb.insert(make_pair(1,3));
            cppdb.insert(make_pair(11,4));

//          cppdb.erase(cppdb.end(),cppdb.end());

            for (bdbcont::reverse_iterator i=cppdb.rbegin(); i!=cppdb.rend(); ++i)
                cout <<(*i).first <<"," <<i->second <<endl;

        } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (...)                      { dbenv.errx("Unknown exception!"); }
        dbenv.close(0);
    } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (...)                      { dbenv.errx("Unknown exception!");
    }

    return 0;
}

Output

0,1
1,2
2,3
3,4
4,5
11,4
4,5
3,4
2,3
1,2
0,1

5.2 bdbmultimap

#include <iostream>
#include "bdbmultimap.hpp"

using namespace std;
using namespace bdbplusplus;

typedef bdbmultimap<int, int> bdbcont;

int main(void)
{
    u_int32_t DBENV_ctor_flag = 0;
    u_int32_t DBENV_open_flag = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE;

    DbEnv dbenv(DBENV_ctor_flag);

    try {
        dbenv.set_error_stream(&cerr);
        dbenv.open("./db_home",DBENV_open_flag,0644);

        try {
            bdbcont cppdb(&dbenv,0,
                    DbMultiMapSortConfig<
                        DbtCompareType<int>::less ,
                        DbtCompareType<int>::less >()
                    );

            for (int i=0; i<5; i++) cppdb.insert(make_pair(i,i+1));

            for (bdbcont::iterator i=cppdb.begin(); i!=cppdb.end(); ++i)
                cout <<(*i).first <<"," <<i->second <<endl;

            cppdb.insert(make_pair(1,1));
            cppdb.insert(make_pair(1,3));
            cppdb.insert(make_pair(11,4));

//          cppdb.erase(cppdb.end(),cppdb.end());

            for (bdbcont::reverse_iterator i=cppdb.rbegin(); i!=cppdb.rend(); ++i)
                cout <<(*i).first <<"," <<i->second <<endl;

        } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (...)                      { dbenv.errx("Unknown exception!");
        }
        dbenv.close(0);
    } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (...)                      { dbenv.errx("Unknown exception!");
    }

    return 0;
}

Output

0,1
1,2
2,3
3,4
4,5
11,4
4,5
3,4
2,3
1,3
1,2
1,1
0,1

5.3 secondary index

#include <iostream>

#include "bdbmap.hpp"
#include "bdbmultimap.hpp"

using namespace std;
using namespace bdbplusplus;

struct Data
{
    int company;
    int salary;
    Data(int c=0, int s=0) : company(c), salary(s) { }
};

typedef bdbmap<int, Data> bdbcont;
typedef IndexTypeDef<int, Data, int>::bdbmultimap bdbindex;

template <>
const int& MakeIndex<int, Data, int>::operator()(const int& k, const Data& d)
{ return *(const int*)(&d); }

int main(void)
{
    u_int32_t DBENV_ctor_flag = 0;
    u_int32_t DBENV_open_flag = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE;

    DbEnv dbenv(DBENV_ctor_flag);

    try {
        dbenv.set_error_stream(&cerr);
        dbenv.open("./db_home",DBENV_open_flag,0644);

        try {
            bdbcont cppdb(&dbenv);
            bdbindex cppidx(&dbenv, 0,
                            IndexConfig <
                                DbMultiMapConfig<bdbindex::comp_type,
                                                bdbindex::cast_type>,
                                bdbcont >(cppdb) );

            for (int i=0; i<10; i++) cppdb.insert(make_pair(i,Data(i%3,i+100)));
            for (bdbcont::iterator i=cppdb.begin(); i!=cppdb.end(); ++i)
                cout <<(*i).first <<","
                    <<i->second.company <<',' <<i->second.salary <<endl;
            cout <<endl;
            for (bdbindex::iterator i=cppidx.begin(); i!=cppidx.end(); ++i)
                cout <<(*i).first <<"," <<i->pkey <<','
                    <<i->second.company <<',' <<i->second.salary <<endl;
            cout <<endl;
            pair<bdbindex::iterator,bdbindex::iterator> p=cppidx.equal_range(2);
            for (bdbindex::iterator i=p.first; i!=p.second; ++i)
                cout <<(*i).first <<"," <<i->pkey <<','
                    <<i->second.company <<',' <<i->second.salary <<endl;

        } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
        } catch (...)                      { dbenv.errx("Unknown exception!");
        }
        dbenv.close(0);
    } catch (DbMemoryException& dbexn) { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (DbException& dbexn)       { dbenv.err(dbexn.get_errno(),"prefix");
    } catch (...)                      { dbenv.errx("Unknown exception!");
    }

    return 0;
}

Output

0,0,100
1,1,101
2,2,102
3,0,103
4,1,104
5,2,105
6,0,106
7,1,107
8,2,108
9,0,109

0,0,0,100
0,3,0,103
0,6,0,106
0,9,0,109
1,1,1,101
1,4,1,104
1,7,1,107
2,2,2,102
2,5,2,105
2,8,2,108

2,2,2,102
2,5,2,105
2,8,2,108

6 Links

6.1 References

6.2 Related Projects

7 TODO

  • Currently, there are only breif documentation for clases and some important members only. Needs more documentation.
  • Provide control for flags used in cursor creation, insertion, etc.
  • Supporting for unique write cursor restriction for shared memory database. To do or not?
  • Support for hash, queue, recno access methods; currently I have no plan for this yet. Currently, only Btree access method is considered because I have never used other access methods. Suggestions and contributions for other access methods are welecomed.
last modified 2009-03-09 12:46:34
EditTextFindPageDeletePageLikePages