00001 #ifndef _NVActiveDB_h_
00002 #define _NVActiveDB_h_
00003
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <errno.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <ctype.h>
00010
00011 #include <iostream>
00012 #include <NVHash.h>
00013
00014 #include "config.h"
00015 #include "Debug.h"
00016 #include "NSError.h"
00017 #include "MPList.h"
00018 #include "ActiveDB.h"
00019
00020
00021
00022
00023
00024
00025 #define CONF_NVActiveDB_HASHSIZE 15013
00026
00027 #ifdef CONF_NVActiveDB_HASHSIZE
00028 #define NVActiveDB_HASHSIZE CONF_NVActiveDB_HASHSIZE
00029 #else
00030 #define NVActiveDB_HASHSIZE 9001
00031 #endif
00032
00033 class NVActiveDB_Iter;
00034
00041 class NVActiveDB:public ActiveDB, protected NVHash {
00042 protected:
00043 friend class NVActiveDB_Iter;
00044
00045 unsigned long hash(const char *strg);
00046
00055 void sset(GroupInfo & gi, int flags = 0);
00056
00057 public:
00058 NVActiveDB():NVHash() {
00059 } NVActiveDB(char *dbname):NVHash(dbname, NVActiveDB_HASHSIZE) {
00060 }
00061
00062 int lock(int command, int block = Block) {
00063 return NVHash::lock(command, block);
00064 }
00065 int get_lock(void) {
00066 return NVHash::get_lock();
00067 }
00068
00069 void open(const char *dbname) {
00070 NVHash::open(dbname, NVActiveDB_HASHSIZE);
00071 }
00072 int is_open(void) {
00073 return NVHash::is_open();
00074 }
00075 void close(void) {
00076 NVHash::close();
00077 }
00078
00079 void setmtime(unsigned long tm, int force = 0) {
00080 NVHash::setmtime(tm, force);
00081 }
00082 void getmtime(unsigned long *tm) {
00083 NVHash::getmtime(tm);
00084 }
00085
00086 void clear(void) {
00087 NVHash::clear();
00088 }
00089 int is_empty(void) {
00090 return NVHash::is_empty();
00091 }
00092
00098 void add(GroupInfo & gi);
00099 void set(GroupInfo & gi, int flags = 0) {
00100 lock(ExclLock);
00101 sset(gi, flags);
00102 lock(UnLock);
00103 }
00104
00109 int get(const char *group, GroupInfo * gi);
00110
00118 int hasgroup(const char *group);
00119
00126 void read(std::istream & is, const char *filter, int flags = 0);
00127 void write(std::ostream & os, nvtime_t ctime = 0, int mode =
00128 m_active, const char *filter = NULL);
00129
00130 Iter < GroupInfo > begin();
00131
00132 Iter < GroupInfo > end();
00133
00134 friend std::ostream & operator<<(std::ostream & os,
00135 NVActiveDB & adb) {
00136 adb.write(os);
00137 return os;
00138 }
00139 };
00140
00141
00142
00143 class NVActiveDB_Iter:public _Iter < GroupInfo > {
00144 private:
00145 friend class NVActiveDB;
00146
00147 NVActiveDB *active_database;
00148
00149 unsigned long hash_val;
00150 NVActiveDB::Record * pos;
00151 NVActiveDB::Record * tail;
00152
00153 GroupInfo newsgroup;
00154
00155
00156 void _skip_nulls() {
00157 while (hash_val < active_database->hashsz) {
00158 if (active_database->hashtab[hash_val]) {
00159 tail =
00160 active_database->o2r(active_database->
00161 hashtab
00162 [hash_val]);
00163 pos = active_database->o2r(tail->next);
00164 break;
00165 }
00166 hash_val++;
00167 }
00168 }
00169
00170 NVActiveDB_Iter(NVActiveDB * db, bool begin):active_database(db)
00171 {
00172 _type = 1;
00173
00174 pos = NULL;
00175 hash_val = begin ? 0 : active_database->hashsz;
00176 _skip_nulls();
00177 }
00178
00179 public:
00180 _Iter < GroupInfo > *clone() {
00181 return new NVActiveDB_Iter(*this);
00182 }
00183
00184 GroupInfo *get() {
00185 char *data;
00186 int datasz;
00187
00188 data = active_database->mem_p +
00189 active_database->r2o(pos) + sizeof(NVActiveDB::Record);
00190 datasz = pos->szdata;
00191
00192 newsgroup.setraw(data, datasz);
00193 return &newsgroup;
00194 }
00195
00196 void next() {
00197 ASSERT(if (hash_val == active_database->hashsz) {
00198 slog.p(Logger::Critical) << "iterator past end\n";
00199 return;}
00200 );
00201
00202 if (pos == tail) {
00203 pos = NULL;
00204 hash_val++;
00205 _skip_nulls();
00206 } else {
00207 pos = active_database->o2r(pos->next);
00208 }
00209 }
00210
00211 bool equals(_Iter < GroupInfo > *iter) {
00212 NVActiveDB_Iter *active_iter = (NVActiveDB_Iter *) iter;
00213
00214 return active_iter->_type == 1 &&
00215 active_iter->active_database == this->active_database
00216 && active_iter->pos == this->pos;
00217 }
00218 };
00219
00220
00221
00222 inline Iter < GroupInfo > NVActiveDB::begin()
00223 {
00224 return Iter < GroupInfo > (new NVActiveDB_Iter(this, true));
00225 }
00226
00227 inline Iter < GroupInfo > NVActiveDB::end()
00228 {
00229 return Iter < GroupInfo > (new NVActiveDB_Iter(this, false));
00230 }
00231
00232 #endif