00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef __BERKELEY_TABLE_STORE_H__
00040 #define __BERKELEY_TABLE_STORE_H__
00041
00042 #include "config.h"
00043 #include <map>
00044 #include <db.h>
00045
00046 #if DB_VERSION_MAJOR != 4
00047 #error "must use Berkeley DB major version 4"
00048 #endif
00049
00050 #include "../debug/Logger.h"
00051 #include "../thread/Mutex.h"
00052 #include "../thread/SpinLock.h"
00053 #include "../thread/Timer.h"
00054
00055 #include "DurableStore.h"
00056
00057 namespace oasys {
00058
00059
00060 class BerkeleyDBStore;
00061 class BerkeleyDBTable;
00062 class BerkeleyDBIterator;
00063 class StorageConfig;
00064
00068 class BerkeleyDBStore : public DurableStoreImpl {
00069 friend class BerkeleyDBTable;
00070
00071 public:
00072 BerkeleyDBStore(const char* logpath);
00073
00074
00075 BerkeleyDBStore& operator=(const BerkeleyDBStore&);
00076 BerkeleyDBStore(const BerkeleyDBStore&);
00077
00078 ~BerkeleyDBStore();
00079
00082 int init(const StorageConfig& cfg);
00083
00084 int get_table(DurableTableImpl** table,
00085 const std::string& name,
00086 int flags,
00087 PrototypeVector& prototypes);
00088
00089 int del_table(const std::string& name);
00090 int get_table_names(StringVector* names);
00091
00093
00094 private:
00095 bool init_;
00096 std::string db_name_;
00097 DB_ENV* dbenv_;
00098 bool sharefile_;
00099
00100 SpinLock ref_count_lock_;
00101 RefCountMap ref_count_;
00102
00104 static const std::string META_TABLE_NAME;
00105
00107 int get_meta_table(BerkeleyDBTable** table);
00108
00111 int acquire_table(const std::string& table);
00112 int release_table(const std::string& table);
00114
00117
00118 #if DB_VERSION_MINOR >= 3
00119 static void db_errcall(const DB_ENV* dbenv,
00120 const char* errpfx,
00121 const char* msg);
00122 #else
00123 static void db_errcall(const char* errpfx, char* msg);
00124 #endif
00125
00127 static void db_panic(DB_ENV* dbenv, int errval);
00128
00132 class DeadlockTimer : public oasys::Timer, public oasys::Logger {
00133 public:
00134 DeadlockTimer(const char* logbase, DB_ENV* dbenv, int frequency)
00135 : Logger("BerkeleyDBStore::DeadlockTimer",
00136 "%s/%s", logbase, "deadlock_timer"),
00137 dbenv_(dbenv), frequency_(frequency) {}
00138
00139 void reschedule();
00140 virtual void timeout(const struct timeval& now);
00141
00142 protected:
00143 DB_ENV* dbenv_;
00144 int frequency_;
00145 };
00146
00147 DeadlockTimer* deadlock_timer_;
00148 };
00149
00154 class BerkeleyDBTable : public DurableTableImpl, public Logger {
00155 friend class BerkeleyDBStore;
00156 friend class BerkeleyDBIterator;
00157
00158 public:
00159 ~BerkeleyDBTable();
00160
00162 int get(const SerializableObject& key,
00163 SerializableObject* data);
00164
00165 int get(const SerializableObject& key,
00166 SerializableObject** data,
00167 TypeCollection::Allocator_t allocator);
00168
00169 int put(const SerializableObject& key,
00170 TypeCollection::TypeCode_t typecode,
00171 const SerializableObject* data,
00172 int flags);
00173
00174 int del(const SerializableObject& key);
00175
00176 size_t size() const;
00177
00178 DurableIterator* itr();
00180
00181 private:
00182 DB* db_;
00183 DBTYPE db_type_;
00184 BerkeleyDBStore* store_;
00185
00187 BerkeleyDBTable(const char* logpath,
00188 BerkeleyDBStore* store,
00189 const std::string& table_name,
00190 bool multitype,
00191 DB* db, DBTYPE type);
00192
00194 int key_exists(const void* key, size_t key_len);
00195 };
00196
00200 class DBTRef {
00201 public:
00203 DBTRef()
00204 {
00205 bzero(&dbt_, sizeof(dbt_));
00206 dbt_.flags = DB_DBT_REALLOC;
00207 }
00208
00211 DBTRef(void* data, size_t size)
00212 {
00213 bzero(&dbt_, sizeof(dbt_));
00214 dbt_.data = data;
00215 dbt_.size = size;
00216 dbt_.flags = DB_DBT_USERMEM;
00217 }
00218
00220 ~DBTRef()
00221 {
00222 if (dbt_.flags == DB_DBT_MALLOC ||
00223 dbt_.flags == DB_DBT_REALLOC)
00224 {
00225 if (dbt_.data != NULL) {
00226 free(dbt_.data);
00227 dbt_.data = NULL;
00228 }
00229 }
00230 }
00231
00233 DBT* dbt() { return &dbt_; }
00234
00236 DBT* operator->() { return &dbt_; }
00237
00238 protected:
00239 DBT dbt_;
00240 };
00241
00245 class BerkeleyDBIterator : public DurableIterator, public Logger {
00246 friend class BerkeleyDBTable;
00247
00248 private:
00253 BerkeleyDBIterator(BerkeleyDBTable* t);
00254
00255 public:
00256 virtual ~BerkeleyDBIterator();
00257
00259
00260
00261 int raw_key(void** key, size_t* len);
00262 int raw_data(void** data, size_t* len);
00264
00266 int next();
00267 int get_key(SerializableObject* key);
00269
00270 protected:
00271 DBC* cur_;
00272 bool valid_;
00273
00274 DBTRef key_;
00275 DBTRef data_;
00276 };
00277
00278 };
00279
00280 #endif //__BERKELEY_TABLE_STORE_H__