Back to index

nordugrid-arc-nox  1.1.0~rc6
test.cpp
Go to the documentation of this file.
00001 #include <string>
00002 #include <iostream>
00003 #include <unistd.h>
00004 #include <glibmm.h>
00005 #include <db_cxx.h>
00006 #include <arc/Thread.h>
00007 
00008 #ifdef WIN32
00009 #include <arc/win32.h>
00010 #endif
00011 
00012 class TestDB
00013 {
00014     private:
00015         int counter_;
00016         DbEnv *env_;
00017         Db *db_;
00018     public:
00019         TestDB(void);
00020         ~TestDB(void);
00021         int put(void);
00022         void list(void);
00023 };
00024 
00025 TestDB::TestDB(void)
00026 {
00027     counter_ = 0;
00028     env_ = new DbEnv(0); // Exception will occure
00029     env_->open("db", DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD, 0644);
00030     db_ = new Db(env_, 0);
00031     db_->open(NULL, "test", NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT | DB_THREAD, 0644);
00032 }
00033 
00034 TestDB::~TestDB(void)
00035 {
00036     std::cout << "Close DB" << std::endl;
00037     if (db_ != NULL) {
00038         db_->close(0);
00039         delete db_;
00040         db_ = NULL;
00041     }
00042     if (env_ != NULL) {
00043         env_->close(0);
00044         delete env_;
00045         env_ = NULL;
00046     }
00047 }
00048 
00049 int TestDB::put(void)
00050 {
00051     char foo[] = "foo";
00052     Dbt key(&counter_, sizeof(counter_));
00053     Dbt data(foo, sizeof(foo));
00054     DbTxn *txn = NULL;
00055     try {
00056         unsigned long int id = (unsigned long int)(void*)Glib::Thread::self();
00057         int ret = env_->txn_begin(NULL, &txn, 0);
00058         printf("(%d) put(%d): %p\n", id, ret, txn);
00059     } catch (std::exception &e) {
00060         std::cerr << "Error: " << e.what() << std::endl;
00061         return counter_;
00062     }
00063     try {
00064         db_->put(txn, &key, &data, 0);
00065         txn->commit(0);
00066     } catch (DbException &e) {
00067         std::cerr << "Error in transaction: " << e.what() << std::endl;
00068         txn->abort();
00069     }
00070     txn = NULL;
00071     return (counter_++);
00072 }
00073 
00074 void TestDB::list(void)
00075 {
00076     Dbc *cursor = NULL;
00077     DbTxn *txn = NULL;
00078     env_->txn_begin(NULL, &txn, 0);
00079     printf("list: %p\n", txn);
00080     try {
00081         db_->cursor(txn, &cursor, 0);
00082         Dbt key, value;
00083         key.set_flags(0);
00084         value.set_flags(0);
00085         int ret;
00086         std::cout << "Start loop" << std::endl;
00087         for (;;) {
00088             ret = cursor->get(&key, &value, DB_NEXT);
00089             if (ret == DB_NOTFOUND) {
00090                 break;
00091             }
00092             int k = *(int *)key.get_data();
00093             char *v = (char *)value.get_data();
00094             std::cout << k << " -> " << v << std::endl;  
00095             // free(key.get_data());
00096             // free(value.get_data());
00097             // sleep(1);
00098         }
00099         std::cout << "Endloop" << std::endl;
00100         cursor->close();
00101         txn->commit(0);
00102     } catch (DbException &e) {
00103         std::cerr << "Error in transaction: " << e.what() << std::endl;
00104         if (cursor != NULL) {
00105             cursor->close();
00106         }
00107         txn->abort();
00108     }
00109 }
00110 
00111 class Writer
00112 {
00113     private:
00114         TestDB *db_;
00115     public:
00116         Writer(TestDB &db);
00117         void do_write(void);
00118 };
00119 
00120 void Writer::do_write(void)
00121 {
00122     unsigned long int id = (unsigned long int)(void*)Glib::Thread::self();
00123     std::cout << "(" << id << ") do_write: " << db_->put() << std::endl;
00124 }
00125 
00126 static void writer(void *data)
00127 {
00128     Writer *w = (Writer *)data;
00129     Glib::Rand r;
00130     for (;;) {
00131         sleep(r.get_int_range(0,3));
00132         w->do_write();
00133     }
00134 }
00135 
00136 Writer::Writer(TestDB &db)
00137 {
00138     db_ = &db;
00139     Arc::CreateThreadFunction(&writer, this);
00140 }
00141 
00142 class Reader
00143 {
00144     private:
00145         TestDB *db_;
00146     public:
00147         Reader(TestDB &db);
00148         void do_read(void);
00149 };
00150 
00151 void Reader::do_read(void)
00152 {
00153     std::cout << "do_read" << std::endl;
00154     db_->list();
00155     std::cout << "do_read done" << std::endl;
00156 }
00157 
00158 static void reader(void *data)
00159 {
00160     Reader *r = (Reader *)data;
00161     Glib::Rand rnd;
00162     for (;;) {
00163         sleep(rnd.get_int_range(0,3));
00164         r->do_read();
00165     }
00166 }
00167 
00168 Reader::Reader(TestDB &db)
00169 {
00170     db_ = &db;
00171     Arc::CreateThreadFunction(&reader, this);
00172 }
00173 
00174 int main(void)
00175 {
00176     TestDB db;
00177     Writer w1(db);
00178     Writer w2(db);
00179     Reader r1(db);
00180     Reader r2(db);
00181     sleep(3000);
00182     return 0;
00183 }