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

NVActiveDB.cc

Go to the documentation of this file.
00001 #include <time.h>
00002 #include <utime.h>
00003 #include <unistd.h>
00004 #include <fcntl.h>
00005 
00006 #include <iostream>
00007 #include <fstream>
00008 #include <string>
00009 
00010 #include "util.h"
00011 #include "NSError.h"
00012 #include "NVActiveDB.h"
00013 #include "readline.h"
00014 
00015 using namespace std;
00016 
00017 // protected:
00018 unsigned long NVActiveDB::hash(const char *strg)
00019 {
00020         unsigned long h = 1;
00021         const char *p = strg;
00022         while (p[0]) {
00023                 h = (h * (p[0]) + p[1]) % NVActiveDB_HASHSIZE;
00024                 if (!p[1])
00025                         break;
00026                 p += 2;
00027         }
00028         return h;
00029 }
00030 
00031 void NVActiveDB::sset(GroupInfo & gi, int flags)
00032 {
00033         //   GroupInfo cg;
00034         const char *gidata;
00035         unsigned int gisz;
00036         Record *head = o2r(hashtab[hash(gi.name())]);
00037         Record *r = head;
00038 
00039         while (r) {
00040                 r = o2r(r->next);
00041 
00042                 // The first approach is the cleaner one since it uses 
00043                 // GroupInfo's setraw function. However, this involves 
00044                 // a copy operation
00045 //     cg.setraw(r->datap(),r->szdata);
00046 //     if(strcmp(gi.name(),cg.name())==0) {
00047 //       gi.setctime(cg.ctime());
00048                 // The second approach assumes that the GroupInfo
00049                 // data is stored in the same layout in the file.
00050                 // The last (sizeof(GroupInfo)-r->szdata) bytes don't
00051                 // matter. These are junk anyways.
00052                 if (strcmp(((GroupInfo *) r->datap())->name(), gi.name())
00053                     == 0) {
00054                         gi.setctime(((GroupInfo *) r->datap())->ctime());
00055                         gi.getraw(&gidata, &gisz);
00056                         if (gisz != r->szdata) {
00057                                 VERB(slog.
00058                                      p(Logger::
00059                                        Error) <<
00060                                      "NVActiveDB::set: Size of new record not equal original record size. Should have been impossible.\n");
00061                         } else {
00062                                 memcpy(r->datap(), gidata, gisz);
00063                         }
00064                         break;
00065                 }
00066                 if (r == head)
00067                         r = NULL;
00068         }
00069 
00070         if (!r) {
00071                 if (flags & update_only) {
00072                         // Should we throw an exception here?!?
00073                         VERB(slog.
00074                              p(Logger::
00075                                Error) <<
00076                              "NVActiveDB::set: Cannot find requested record\n");
00077                 } else {
00078                         const char *buf;
00079                         unsigned int bufsz;
00080                         nvtime_t now;
00081                         nvtime(&now);
00082                         gi.setctime(now);
00083                         gi.getraw(&buf, &bufsz);
00084                         NVHash::add(hash(gi.name()), buf, bufsz);
00085                 }
00086         }
00087 }
00088 
00089 void NVActiveDB::add(GroupInfo & gi)
00090 {
00091         VERB(slog.p(Logger::Debug) << "NVActiveDB::add(GroupInfo &gi)\n)");
00092         const char *buf;
00093         unsigned int bufsz;
00094         gi.getraw(&buf, &bufsz);
00095         NVHash::add(hash(gi.name()), buf, bufsz);
00096 }
00097 
00098 int NVActiveDB::get(const char *group, GroupInfo * gi)
00099 {
00100         VERB(slog.
00101              p(Logger::Debug) << "NVActiveDB::get(" << group << ",&gi)\n");
00102         lock(ShrdLock);
00103         Record *head = o2r(hashtab[hash(group)]);
00104         Record *r = head;
00105 
00106         while (r) {
00107                 r = o2r(r->next);
00108 
00109                 // The first approach is the cleaner one since it uses 
00110                 // GroupInfo's setraw function. However, this involves 
00111                 // a copy operation
00112 //     gi->setraw(r->datap(),r->szdata);
00113 //     if(strcmp(gi->name(),group)==0) break;
00114 
00115                 // The second approach assumes that the GroupInfo
00116                 // data is stored in the same layout in the file.
00117                 // The last (sizeof(GroupInfo)-r->szdata) bytes don't
00118                 // matter. These are junk anyways.
00119                 if (strcmp(((GroupInfo *) r->datap())->name(), group) == 0) {
00120                         gi->setraw(r->datap(), r->szdata);
00121                         break;
00122                 }
00123                 if (r == head)
00124                         r = NULL;
00125         }
00126         lock(UnLock);
00127 
00128         if (!r)
00129                 return -1;
00130         return 0;
00131 }
00132 
00133 int NVActiveDB::hasgroup(const char *group)
00134 {
00135         VERB(slog.
00136              p(Logger::Info) << "NVActiveDB::hasgroup(" << group << ")\n");
00137         lock(ShrdLock);
00138         Record *head = o2r(hashtab[hash(group)]);
00139         Record *r = head;
00140 
00141         while (r) {
00142                 r = o2r(r->next);
00143 
00144                 // The first approach is the cleaner one since it uses 
00145                 // GroupInfo's setraw function. However, this involves 
00146                 // a copy operation
00147 //     gi->setraw(r->datap(),r->szdata);
00148 //     if(strcmp(gi->name(),group)==0) break;
00149 
00150                 // The second approach assumes that the GroupInfo
00151                 // data is stored in the same layout in the file.
00152                 // The last (sizeof(GroupInfo)-r->szdata) bytes don't
00153                 // matter. These are junk anyways.
00154                 if (strcmp(((GroupInfo *) r->datap())->name(), group) == 0) {
00155                         break;
00156                 }
00157                 if (r == head)
00158                         r = NULL;
00159         }
00160         lock(UnLock);
00161 
00162         if (!r)
00163                 return 0;
00164         return 1;
00165 }
00166 
00167 void NVActiveDB::read(istream & is, const char *filter, int flags)
00168 {
00169         VERB(slog.
00170              p(Logger::Debug) << "NVActiveDB::read(&is,*filter,flags)\n");
00171 
00172         GroupInfo gd;
00173         string line;
00174         time_t now;
00175 
00176         lock(NVcontainer::ExclLock);
00177         if (flags & F_CLEAR)
00178                 clear();
00179         while (!is.eof()) {
00180                 // Each line has the following form
00181                 // GroupName Last First Flags
00182                 nlreadline(is, line, 0);
00183                 if (line == ".")
00184                         break;
00185 
00186                 if (!filter || matchgroup(filter, line.c_str()) > 0) {
00187                         // Add group
00188                         gd.set(line.c_str());
00189                         if (flags & F_STORE_READONLY)
00190                                 gd.setflag('n');
00191                         sset(gd);
00192                 }
00193         }
00194         time(&now);
00195         setmtime(now);
00196         lock(NVcontainer::UnLock);
00197 }
00198 
00199 void NVActiveDB::write(ostream & os,
00200                        nvtime_t ctime, int mode, const char *filter)
00201 {
00202         VERB(slog.
00203              p(Logger::Debug) << "NVActiveDB::write(&os,ctime,...)\n");
00204 
00205         NVHashIter nvhi(*this);
00206         GroupInfo gd;
00207         const char *buf;
00208         unsigned int bufsz;
00209 
00210         for (nvhi.first(); nvhi.valid(); nvhi.next()) {
00211                 nvhi.data(&buf, &bufsz);
00212                 gd.setraw(buf, bufsz);
00213                 if (((!filter) ||
00214                      ((matchgroup(filter, gd.name()) > 0))) &&
00215                     ctime < gd.ctime()) {
00216                         if (mode == m_active)
00217                                 os << gd << "\r\n";
00218                         else
00219                                 os << gd.name() << " " << gd.
00220                                     ctime() << " news\r\n";
00221                         if (!os.good()) {
00222                                 throw SystemError("Cannot write GroupList",
00223                                                   errno, ERROR_LOCATION);
00224                         }
00225                 }
00226         }                       /* for */
00227 }

Generated on Sun Oct 24 21:08:18 2004 for NewsCache by doxygen 1.3.6-20040222