00001
00002
00003
00004
00005
00006
00007
00008
#ifndef __WVBDBHASH_H
00009
#define __WVBDBHASH_H
00010
00011
#include "wvautoconf.h"
00012
00013
#ifndef WITH_BDB
00014
# error "Sorry, no Berkeley DB support in WvStreams!"
00015
#endif
00016
00017
#include "wvhashtable.h"
00018
#include "wvserialize.h"
00019
#include "wverror.h"
00020
00021
00022 class WvBdbHashBase :
public WvError
00023 {
00024
WvString dbfile;
00025
bool persist_dbfile;
00026
00027
public:
00028
00029
00030 struct datum
00031 {
00032 void *
dptr;
00033 size_t
dsize;
00034 };
00035
00036
WvBdbHashBase(
WvStringParm _dbfile,
bool persist_dbfile =
true);
00037
~WvBdbHashBase();
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
void opendb(
WvStringParm _dbfile,
bool persist_dbfile =
true);
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
void closedb();
00064
00065
void add(
const datum &key,
const datum &data,
bool replace);
00066
void remove(
const datum &key);
00067
datum find(
const datum &key);
00068
bool exists(
const datum &key);
00069
00070
00071
00072
00073
00074
void zap();
00075
00076 class IterBase
00077 {
00078
public:
00079
IterBase(
WvBdbHashBase &_bdbhash);
00080
~IterBase();
00081
00082
void rewind();
00083
void rewind(
const datum &firstkey,
datum &key,
datum &data);
00084
void next(
datum &key,
datum &data);
00085
void xunlink(
const datum &key);
00086
void update(
const datum &key,
const datum &data);
00087
00088
protected:
00089 WvBdbHashBase &
bdbhash;
00090 datum rewindto;
00091 };
00092
00093
private:
00094
friend class IterBase;
00095
struct __db *dbf;
00096 };
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
template <
class K,
class D>
00115 class WvBdbHash :
public WvBdbHashBase
00116 {
00117
public:
00118
00119
00120
00121
template <
typename T>
00122 class datumize :
public datum
00123 {
00124
datumize(
datumize &);
00125
00126
void init(
const T &t)
00127 {
00128
wv_serialize(
buf, t);
00129 dsize =
buf.
used();
00130 dptr = (
char *)
buf.
peek(0,
buf.
used());
00131 }
00132
00133
public:
00134 WvDynBuf buf;
00135
00136 datumize(
const T &t)
00137 { init(t); }
00138
00139 datumize(
const T *t)
00140 {
00141
if (t) { init(*t); }
00142
else { dsize = 0; dptr = 0; }
00143 }
00144 };
00145
00146
template <
typename T>
00147 static T undatumize(datum &data)
00148 {
00149
WvConstInPlaceBuf buf(data.dptr, data.dsize);
00150
return wv_deserialize<T>(buf);
00151 }
00152
00153
protected:
00154 D *
saveddata;
00155
00156
public:
00157 WvBdbHash(
WvStringParm dbfile = WvString::null,
bool persist =
true) :
00158
WvBdbHashBase(dbfile, persist) {
saveddata = NULL; }
00159
00160 void add(
const K &key,
const D &data,
bool replace =
false)
00161 {
00162 WvBdbHashBase::add(
datumize<K>(key),
00163
datumize<D>(data), replace);
00164 }
00165
00166 void remove(
const K &key)
00167 { WvBdbHashBase::remove(
datumize<K>(key)); }
00168
00169 D &
find(
const K &key)
00170 {
00171
if (
saveddata)
00172
delete saveddata;
00173 datum s = WvBdbHashBase::find(
datumize<K>(key));
00174
saveddata = undatumize<D *>(s);
00175
return *
saveddata;
00176 }
00177
00178 D &operator[] (
const K &key)
00179 {
return find(key); }
00180
00181 bool exists(
const K &key)
00182 {
return WvBdbHashBase::exists(
datumize<K>(key)); }
00183
00184 int count()
00185 {
00186
int res = 0;
00187
Iter i(*
this);
00188
for (i.
rewind(); i.
next(); )
00189 res++;
00190
return res;
00191 }
00192
00193 bool isempty()
00194 {
00195
Iter i(*
this);
00196 i.
rewind();
00197
return !i.
next();
00198 }
00199
00200 D &
first()
00201 {
00202
Iter i(*
this);
00203 i.
rewind(); i.
next();
00204
return i();
00205 }
00206
00207 class Iter :
public WvBdbHashBase::IterBase
00208 {
00209 K *k;
00210 D *d;
00211
00212
public:
00213 Iter(
WvBdbHash &_bdbhash) : IterBase(_bdbhash)
00214 { k = NULL; d = NULL; }
00215 ~Iter()
00216 {
00217
delete k;
00218
delete d;
00219 }
00220
00221 void rewind()
00222 {
00223 IterBase::rewind();
00224
delete k; k = NULL;
00225
delete d; d = NULL;
00226 }
00227
00228 void rewind(
const K &firstkey)
00229 {
00230
WvBdbHash::datumize<K> key(k);
00231
WvBdbHash::datumize<D> data(d);
00232
00233 IterBase::rewind(
WvBdbHash::datumize<K>(firstkey), key, data);
00234
delete k;
00235
delete d;
00236
if (data.dptr)
00237 {
00238 k = undatumize<K *>(key);
00239 d = undatumize<D *>(data);
00240 }
00241
else
00242 {
00243 k = NULL;
00244 d = NULL;
00245 }
00246 }
00247
00248 bool next()
00249 {
00250
WvBdbHash::datumize<K> key(k);
00251 datum data = { 0, 0 };
00252 IterBase::next(key, data);
00253
delete k;
00254
delete d;
00255
if (bdbhash.
isok() && data.dptr)
00256 {
00257 k = undatumize<K *>(key);
00258 d = undatumize<D *>(data);
00259
return true;
00260 }
00261 k = NULL;
00262 d = NULL;
00263
return false;
00264 }
00265
00266 void unlink()
00267 {
xunlink();
next(); }
00268
00269 void xunlink()
00270 { IterBase::xunlink(
WvBdbHash::datumize<K>(k)); }
00271
00272 void save()
00273 { IterBase::update(
WvBdbHash::datumize<K>(k),
00274
WvBdbHash::datumize<D>(d)); }
00275
00276 bool cur()
00277 {
return d; }
00278
00279 K &
key()
const
00280
{ assert(k);
return *k; }
00281
00282 D *
ptr()
const
00283
{
return d; }
00284
00285
WvIterStuff(D);
00286
00287 };
00288
00289 };
00290
00291
#endif // __WVBDBHASH_H