lux/storage/depot_hash.h

00001 #ifndef LUX_STORAGE_DEPOTHASH_H
00002 #define LUX_STORAGE_DEPOTHASH_H
00003 
00004 #include "lux/lux.h"
00005 #include "lux/util.h"
00006 #include "data_unit.h"
00007 #include <depot.h>
00008 #include <cassert>
00009 #include <iostream>
00010 
00011 namespace Lux {
00012 
00013     class DepotHash {
00014         
00015     public:
00016         DepotHash()
00017         {}
00018 
00019         DepotHash(const char *filename, db_flags_t open_flags)
00020         {
00021             this->open(filename, open_flags);
00022         }
00023 
00024         DepotHash(std::string filename, db_flags_t open_flags)
00025         {
00026             this->open(filename.c_str(), open_flags);
00027         } 
00028 
00029         bool open(const char *filename, db_flags_t open_flags)
00030         {
00031             assert(filename);
00032             int oflags = 0;
00033 
00034             // when giving char * from c_str() to dpopen, valgrind gives an error. 
00035             // I'm not sure whether or not it's a bug in QDBM or valgrind for now or
00036             // it's my fault.
00037             // [workaround]
00038             // copy the filename to a temporary buffer and pass the buffer to dpopen.
00039             char filename_buf[255];
00040             memset(filename_buf, 0, 255);
00041             strncpy(filename_buf, filename, strlen(filename));
00042 
00043             if (open_flags & DB_RDONLY) {
00044                 oflags = DP_OREADER;
00045             }
00046             if (open_flags & DB_RDWR) {
00047                 oflags = DP_OWRITER;
00048             }
00049             if (open_flags & DB_CREAT) {
00050                 oflags = DP_OWRITER | DP_OCREAT;
00051                 mkdir(filename);
00052             }
00053             if (open_flags & DB_TRUNC) {
00054                 oflags |= DP_OTRUNC;
00055             }
00056             if (!(depot_ = dpopen(filename_buf, oflags, -1))) {
00057                 return false;
00058             }
00059             return true;
00060         }
00061 
00062         bool close()
00063         {
00064             if (!dpclose(depot_)) {
00065                 return false;
00066             }
00067             depot_ = NULL;
00068             return true;
00069         }
00070 
00071         bool put(LuxDataUnit &key, LuxDataUnit &val)
00072         {
00073             return __put(key, val, DP_DOVER);
00074         }
00075 
00076         bool put(LuxDataUnit *key, LuxDataUnit *val)
00077         {
00078             return put(*key, *val);
00079         }
00080 
00081         bool append(LuxDataUnit &key, LuxDataUnit &val)
00082         {
00083             return __put(key, val, DP_DCAT);
00084         }
00085 
00086         bool append(LuxDataUnit *key, LuxDataUnit *val)
00087         {
00088             return append(*key, *val);
00089         }
00090 
00091         bool get(LuxDataUnit &key, LuxDataUnit &val)
00092         {
00093             assert(key.get_data());
00094             int val_size;
00095             void *val_data;
00096 
00097             val_data = dpget(depot_, static_cast<const char *>(key.get_data()),
00098                              key.get_size(), 0, -1, &(val_size));
00099 
00100             if (val_data == NULL) {
00101                 return false;
00102             }
00103 
00104             /*
00105              * LuxDataUnit val must be cleaned up because qdbm returns 
00106              * dynamically allocated date in the library.
00107              */
00108             val.set_cleanup_needed(true);
00109             val.set_data(val_data);
00110             val.set_size(static_cast<unsigned int>(val_size));
00111 
00112             return true;
00113         }
00114 
00115         bool get(LuxDataUnit *key, LuxDataUnit *val)
00116         {
00117             return get(*key, *val);
00118         }
00119 
00120         bool del(LuxDataUnit &key)
00121         {
00122             assert(key.get_data());
00123             if (dpout(depot_, static_cast<const char *>(key.get_data()),
00124                       key.get_size())) {
00125                 return true;
00126             }
00127             return false;
00128         }
00129 
00130         bool del(LuxDataUnit *key)
00131         {
00132             return del(*key);
00133         }
00134 
00135     protected:
00136         ~DepotHash()
00137         {
00138             if (depot_ != NULL) {
00139                 if (dpclose(depot_)) {
00140                     depot_ = NULL;
00141                 }
00142             }
00143         }
00144 
00145     private:
00146         DEPOT *depot_;
00147 
00148         bool __put(LuxDataUnit &key, LuxDataUnit &val, int mode)
00149         {
00150             assert(key.get_data() && val.get_data());
00151             if (dpput(depot_,
00152                       static_cast<const char *>(key.get_data()), key.get_size(),
00153                       static_cast<const char *>(val.get_data()), val.get_size(),
00154                       mode)) {
00155                 return true;
00156             }
00157             return false;
00158         }
00159 
00160     };
00161 }
00162 
00163 #endif

Generated on Fri Feb 5 15:50:30 2010 for Lux by  doxygen 1.4.7