00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __BERKELEY_TABLE_STORE_H__
00019 #define __BERKELEY_TABLE_STORE_H__
00020
00021 #include "config.h"
00022 #include <map>
00023 #include <db.h>
00024
00025 #if DB_VERSION_MAJOR != 4
00026 #error "must use Berkeley DB major version 4"
00027 #endif
00028
00029 #include "../debug/Logger.h"
00030 #include "../thread/Mutex.h"
00031 #include "../thread/SpinLock.h"
00032 #include "../thread/Timer.h"
00033
00034 #include "DurableStore.h"
00035
00036 namespace oasys {
00037
00038
00039 class BerkeleyDBStore;
00040 class BerkeleyDBTable;
00041 class BerkeleyDBIterator;
00042 class StorageConfig;
00043
00047 class BerkeleyDBStore : public DurableStoreImpl {
00048 friend class BerkeleyDBTable;
00049
00050 public:
00051 BerkeleyDBStore(const char* logpath);
00052
00053
00054 BerkeleyDBStore& operator=(const BerkeleyDBStore&);
00055 BerkeleyDBStore(const BerkeleyDBStore&);
00056
00057 ~BerkeleyDBStore();
00058
00061 int init(const StorageConfig& cfg);
00062
00063 int get_table(DurableTableImpl** table,
00064 const std::string& name,
00065 int flags,
00066 PrototypeVector& prototypes);
00067
00068 int del_table(const std::string& name);
00069 int get_table_names(StringVector* names);
00070 std::string get_info() const;
00072
00073 private:
00074 bool init_;
00075 std::string db_name_;
00076 DB_ENV* dbenv_;
00077 bool sharefile_;
00078
00079 SpinLock ref_count_lock_;
00080 RefCountMap ref_count_;
00081
00083 static const std::string META_TABLE_NAME;
00084
00086 int get_meta_table(BerkeleyDBTable** table);
00087
00090 int acquire_table(const std::string& table);
00091 int release_table(const std::string& table);
00093
00096
00097 #if DB_VERSION_MINOR >= 3
00098 static void db_errcall(const DB_ENV* dbenv,
00099 const char* errpfx,
00100 const char* msg);
00101 #else
00102 static void db_errcall(const char* errpfx, char* msg);
00103 #endif
00104
00106 static void db_panic(DB_ENV* dbenv, int errval);
00107
00111 class DeadlockTimer : public oasys::Timer, public oasys::Logger {
00112 public:
00113 DeadlockTimer(const char* logbase, DB_ENV* dbenv, int frequency)
00114 : Logger("BerkeleyDBStore::DeadlockTimer",
00115 "%s/%s", logbase, "deadlock_timer"),
00116 dbenv_(dbenv), frequency_(frequency) {}
00117
00118 void reschedule();
00119 virtual void timeout(const struct timeval& now);
00120
00121 protected:
00122 DB_ENV* dbenv_;
00123 int frequency_;
00124 };
00125
00126 DeadlockTimer* deadlock_timer_;
00127 };
00128
00133 class BerkeleyDBTable : public DurableTableImpl, public Logger {
00134 friend class BerkeleyDBStore;
00135 friend class BerkeleyDBIterator;
00136
00137 public:
00138 ~BerkeleyDBTable();
00139
00141 int get(const SerializableObject& key,
00142 SerializableObject* data);
00143
00144 int get(const SerializableObject& key,
00145 SerializableObject** data,
00146 TypeCollection::Allocator_t allocator);
00147
00148 int put(const SerializableObject& key,
00149 TypeCollection::TypeCode_t typecode,
00150 const SerializableObject* data,
00151 int flags);
00152
00153 int del(const SerializableObject& key);
00154
00155 size_t size() const;
00156
00157 DurableIterator* itr();
00159
00160 private:
00161 DB* db_;
00162 DBTYPE db_type_;
00163 BerkeleyDBStore* store_;
00164
00166 BerkeleyDBTable(const char* logpath,
00167 BerkeleyDBStore* store,
00168 const std::string& table_name,
00169 bool multitype,
00170 DB* db, DBTYPE type);
00171
00173 int key_exists(const void* key, size_t key_len);
00174 };
00175
00179 class DBTRef {
00180 public:
00182 DBTRef()
00183 {
00184 bzero(&dbt_, sizeof(dbt_));
00185 dbt_.flags = DB_DBT_REALLOC;
00186 }
00187
00190 DBTRef(void* data, size_t size)
00191 {
00192 bzero(&dbt_, sizeof(dbt_));
00193 dbt_.data = data;
00194 dbt_.size = size;
00195 dbt_.flags = DB_DBT_USERMEM;
00196 }
00197
00199 ~DBTRef()
00200 {
00201 if (dbt_.flags == DB_DBT_MALLOC ||
00202 dbt_.flags == DB_DBT_REALLOC)
00203 {
00204 if (dbt_.data != NULL) {
00205 free(dbt_.data);
00206 dbt_.data = NULL;
00207 }
00208 }
00209 }
00210
00212 DBT* dbt() { return &dbt_; }
00213
00215 DBT* operator->() { return &dbt_; }
00216
00217 protected:
00218 DBT dbt_;
00219 };
00220
00224 class BerkeleyDBIterator : public DurableIterator, public Logger {
00225 friend class BerkeleyDBTable;
00226
00227 private:
00232 BerkeleyDBIterator(BerkeleyDBTable* t);
00233
00234 public:
00235 virtual ~BerkeleyDBIterator();
00236
00238
00239
00240 int raw_key(void** key, size_t* len);
00241 int raw_data(void** data, size_t* len);
00243
00245 int next();
00246 int get_key(SerializableObject* key);
00248
00249 protected:
00250 DBC* cur_;
00251 bool valid_;
00252
00253 DBTRef key_;
00254 DBTRef data_;
00255 };
00256
00257 };
00258
00259 #endif //__BERKELEY_TABLE_STORE_H__