Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvgdbmhash.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2003 Net Integration Technologies, Inc.
00004  *
00005  * A hash table container backed by a gdbm database.
00006  */
00007 #ifndef __WVGDBMHASH_H
00008 #define __WVGDBMHASH_H
00009 
00010 #include "wvautoconf.h"
00011 
00012 #ifndef HAVE_GDBM_H
00013 # error "Sorry, no gdbm support in wvstreams!"
00014 #endif
00015 
00016 #include "wvhashtable.h"
00017 #include "wvserialize.h"
00018 
00019 #include <gdbm.h>
00020 
00021 
00022 // Base class for the template to save space
00023 class WvGdbmHashBase
00024 {
00025 public:
00026     WvGdbmHashBase(WvStringParm dbfile);
00027     ~WvGdbmHashBase();
00028 
00029     int add(const datum &key, const datum &data, bool replace);
00030     int remove(const datum &key);
00031     datum find(const datum &key);
00032     bool exists(const datum &key);
00033     void zap();
00034     
00035     class IterBase
00036     {
00037     public:
00038         IterBase(WvGdbmHashBase &_gdbmhash);
00039         ~IterBase();
00040         void rewind();
00041         void next();
00042         
00043     protected:
00044         WvGdbmHashBase &gdbmhash;
00045         datum curkey, nextkey;
00046         datum curdata;
00047     };
00048 private:
00049     friend class IterBase;
00050     GDBM_FILE dbf;
00051 };
00052 
00053 
00054 /**
00055  * This hashtable is different from normal WvStreams hashtables in that it
00056  * stores the data on disk.
00057  * 
00058  * This affects memory management for objects stored in it.
00059  * 
00060  * For find and operator[], the returned object is only guaranteed to be
00061  * around until the next find/or next() for iterators. 
00062  */
00063 template <class K, class D>
00064 class WvGdbmHash : public WvGdbmHashBase
00065 {
00066 public:
00067     // this class is interchangeable with datum, but includes a WvDynBuf
00068     // object that datum.dptr points to.  So when this object goes away,
00069     // it frees its dptr automatically.
00070     template <typename T>
00071     class datumize : public datum
00072     {
00073         datumize(datumize &); // not defined
00074     public:
00075         WvDynBuf buf;
00076         
00077         datumize(const T &t)
00078         {
00079             wv_serialize(buf, t);
00080             dsize = buf.used();
00081             dptr = (char *)buf.peek(0, buf.used());
00082         }
00083     };
00084     
00085     template <typename T>
00086     static T undatumize(datum &data)
00087     {
00088         WvConstInPlaceBuf buf(data.dptr, data.dsize);
00089         return wv_deserialize<T>(buf);
00090     }
00091 
00092 protected:
00093     D *saveddata;
00094     
00095 public:
00096     WvGdbmHash(WvStringParm dbfile) : WvGdbmHashBase(dbfile)
00097         { saveddata = NULL; }
00098 
00099     void add(const K &key, const D &data, bool replace = false)
00100     {
00101         int r = WvGdbmHashBase::add(datumize<K>(key),
00102                                     datumize<D>(data), replace);
00103         assert(!r && "Set the replace flag to replace existing elements.");
00104     }
00105 
00106     void remove(const K &key)
00107         { WvGdbmHashBase::remove(datumize<K>(key)); }
00108 
00109     D &find(const K &key)
00110     {   
00111         if (saveddata)
00112             delete saveddata;
00113         datum s = WvGdbmHashBase::find(datumize<K>(key));
00114         saveddata = undatumize<D *>(s);
00115         free(s.dptr);
00116         return *saveddata;
00117     }
00118 
00119     D &operator[] (const K &key)
00120         { return find(key); }
00121         
00122     bool exists(const K &key)
00123         { return WvGdbmHashBase::exists(datumize<K>(key)); }
00124     
00125     class Iter : public WvGdbmHashBase::IterBase
00126     {
00127         K *k;
00128         D *d;
00129     public:
00130         Iter(WvGdbmHash &_gdbmhash) : IterBase(_gdbmhash) 
00131             { k = NULL; d = NULL; }
00132         ~Iter()
00133         {
00134             if (k) delete k;
00135             if (d) delete d;
00136         }
00137 
00138         bool next()
00139         {
00140             if (!nextkey.dptr)
00141                 return false;
00142             if (k) delete k;
00143             if (d) delete d;
00144             IterBase::next();
00145             if (curdata.dptr)
00146             {
00147                 k = undatumize<K *>(curkey);
00148                 d = undatumize<D *>(curdata);
00149                 return true;
00150             }
00151             else
00152             {
00153                 k = NULL;
00154                 d = NULL;
00155                 return false;
00156             }
00157         }
00158         
00159         bool cur()
00160             { return curdata.dptr; }
00161         
00162         K &key() const
00163             { return *k; }
00164         
00165         D *ptr() const
00166             { return d; }
00167         WvIterStuff(D);
00168     };
00169 };
00170 
00171 #endif // __WVGDBMHASH_H

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1