BerkeleyDBStore.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 // forward decls
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     // Can't copy or =, don't implement these
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     // Buffers are only valid until the next invocation of the
00260     // iterator.
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 }; // namespace oasys
00279 
00280 #endif //__BERKELEY_TABLE_STORE_H__

Generated on Fri Dec 22 14:47:57 2006 for DTN Reference Implementation by  doxygen 1.5.1