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

NVArray.cc

Go to the documentation of this file.
00001 #include "NVArray.h"
00002 #include "Error.h"
00003 
00004 #include <fcntl.h>
00005 #include <sys/stat.h>
00006 #include <sys/types.h>
00007 #include <signal.h>
00008 #include <stdio.h>
00009 
00010 using namespace std;
00011 
00012 void NVArray::make_current()
00013 {
00014         nvoff_t adata;
00015 
00016         if (!mem_p || !is_current())
00017                 NVcontainer::make_current();
00018         if ((adata = getdata()) == 0) {
00019                 arrtab = NULL;
00020                 arrfst = 1;
00021                 arrlst = 0;
00022         } else {
00023                 arrtab =
00024                     (nvoff_t *) (mem_p + adata +
00025                                  2 * sizeof(unsigned long));
00026                 arrfst = *(unsigned long *) (mem_p + adata);
00027                 arrlst = *((unsigned long *) (mem_p + adata) + 1);
00028         }
00029 }
00030 
00031 void NVArray::sclear(void)
00032 {
00033         unsigned long i, n;
00034 
00035         if (arrfst > arrlst)
00036                 return;
00037         n = arrlst - arrfst + 1;
00038         for (i = 0; i < n; i++)
00039                 if (arrtab[i])
00040                         nvfree(arrtab[i]);
00041 }
00042 
00043 void NVArray::sset(unsigned long i, const char *data, size_t szdata)
00044 {
00045         nvoff_t x;
00046 
00047         if (arrtab[i])
00048                 nvfree(arrtab[i]);
00049         x = nvalloc(szdata + sizeof(unsigned long));
00050         arrtab[i] = x;
00051         *((unsigned long *) (mem_p + x)) = szdata;
00052         memcpy(mem_p + x + sizeof(unsigned long), data, szdata);
00053 }
00054 
00055 void NVArray::sdel(unsigned long i)
00056 {
00057         if (arrtab[i]) {
00058                 nvfree(arrtab[i]);
00059                 arrtab[i] = 0;
00060         }
00061 }
00062 
00063 int NVArray::sis_empty(void)
00064 {
00065         unsigned long i, n;
00066 
00067         if (arrfst > arrlst)
00068                 return 1;
00069         n = arrlst - arrfst + 1;
00070         for (i = 0; i < n; i++)
00071                 if (arrtab[i])
00072                         return 0;
00073         return 1;
00074 }
00075 
00076 int NVArray::shas_element(unsigned long i)
00077 {
00078         if (i < arrfst || i > arrlst)
00079                 return 0;
00080         return arrtab[i - arrfst];
00081 }
00082 
00083 void NVArray::sget(unsigned long i, char **data, size_t * szdata)
00084 {
00085         if (arrfst <= i && i <= arrlst && arrtab[i = i - arrfst]) {
00086                 *szdata = *(unsigned long *) (mem_p + arrtab[i]);
00087                 *data = mem_p + arrtab[i] + sizeof(unsigned long);
00088         } else {
00089                 *szdata = 0;
00090                 *data = NULL;
00091         }
00092 }
00093 
00094 void NVArray::sprint(ostream & os)
00095 {
00096         unsigned long i, n;
00097 
00098         if (arrfst > arrlst)
00099                 return;
00100         n = arrlst - arrfst + 1;
00101         for (i = 0; i < n; i++) {
00102                 if (arrtab[i]) {
00103                         os << arrfst +
00104                             i << "/" << *(unsigned long *) (mem_p +
00105                                                             arrtab[i])
00106                             << ":" << mem_p + arrtab[i] +
00107                             sizeof(unsigned long) << endl;
00108                 } else {
00109                         os << arrfst + i << "/(null):" << endl;
00110                 }
00111         }
00112 }
00113 
00114 NVArray::NVArray(const char *dbname, int flags)
00115 :NVcontainer()
00116 {
00117         open(dbname, flags);
00118 }
00119 
00120 ASSERT(nvoff_t NVArray::nvalloc(size_t rsz) {
00121        nvoff_t r = NVcontainer::nvalloc(rsz);
00122        if (!arrtab) return r;
00123        if ((const char *) (arrtab + (arrlst - arrfst)) <=
00124            mem_p + r) return r;
00125        if (mem_p + (r + rsz) <= (const char *) arrtab) return r;
00126        VERB(char buf[256];
00127             sprintf(buf, "allocated illegal memory block [%lu,%lu[\n", r,
00128                     r + rsz); slog.p(Logger::Error) << buf);
00129        kill(getpid(), SIGABRT); exit(100);}
00130 
00131        void NVArray::nvfree(nvoff_t p) {
00132        if (!arrtab) {
00133        NVcontainer::nvfree(p); return;}
00134        if ((const char *) (arrtab + (arrlst - arrfst)) <= mem_p + p) {
00135        NVcontainer::nvfree(p); return;}
00136        int psz = *(unsigned long *) (mem_p + (p - sizeof(unsigned long)));
00137        if (mem_p + (p + psz) <= (const char *) arrtab) {
00138        NVcontainer::nvfree(p); return;}
00139        kill(getpid(), SIGABRT);}
00140 
00141 )
00142 
00143 void NVArray::open(const char *dbname, int flags) {
00144         NVcontainer::open(dbname, flags);
00145         }
00146 
00147 void NVArray::ssetsize(unsigned long fst, unsigned long lst)
00148 {
00149         nvoff_t *ndata;
00150         nvoff_t p, q;
00151         unsigned long i, n;
00152 
00153         p = nvalloc((lst - fst + 1 + 2) * sizeof(unsigned long));
00154         q = getdata();
00155         ndata = (nvoff_t *) (mem_p + p);
00156         ndata[0] = fst;
00157         ndata[1] = lst;
00158         n = lst - fst + 1;
00159         if (arrfst <= arrlst) {
00160                 for (i = 0; i < n; i++) {
00161                         if (arrfst <= i + fst && i + fst <= arrlst) {
00162                                 ndata[2 + i] = arrtab[i + fst - arrfst];
00163                         } else {
00164                                 ndata[2 + i] = 0;
00165                         }
00166                 }
00167         } else {
00168                 for (i = 0; i < n; i++)
00169                         ndata[2 + i] = 0;
00170         }
00171         arrfst = fst;
00172         arrlst = lst;
00173         setdata(p);
00174         arrtab = ndata + 2;
00175         if (q)
00176                 nvfree(q);
00177 }
00178 
00179 int NVArray::setsize(unsigned long fst, unsigned long lst, int flags)
00180 {
00181         // Usually, the user should have already set an excludive lock
00182         // Otherwise, it cannot be guaranteed that no other process
00183         // changes the arraysize again
00184         // This is just to ensure that the NVArray cannot get inconsistent
00185         // even in the case where the user uses this database incorrectly.
00186         lock(ExclLock);
00187         int ok = 1;
00188         unsigned long i, n;
00189 
00190         if (arrfst <= arrlst) {
00191                 // Clean up existing array or return an error
00192                 if (fst > arrfst) {
00193                         n = fst - arrfst + 1;
00194                         for (i = 0; i < n; i++) {
00195                                 if (arrtab[i]) {
00196                                         if (flags & force)
00197                                                 nvfree(arrtab[i]);
00198                                         else
00199                                                 ok = 0;
00200                                 }
00201                         }
00202                 }
00203                 if (lst < arrlst) {
00204                         n = arrlst - arrfst + 1;
00205                         for (i = lst - arrfst + 1; i < n; i++) {
00206                                 if (arrtab[i]) {
00207                                         if (flags & force) {
00208                                                 nvfree(arrtab[i]);
00209                                                 arrtab[i] = 0;
00210                                         } else
00211                                                 ok = 0;
00212                                 }
00213                         }
00214                 }
00215         }
00216         if (ok)
00217                 ssetsize(fst, lst);
00218         lock(UnLock);
00219         if (ok)
00220                 return 0;
00221         else
00222                 return -1;
00223 }
00224 
00225 void NVArray::clear(void)
00226 {
00227         lock(ExclLock);
00228         sclear();
00229         lock(UnLock);
00230 }
00231 
00232 void NVArray::set(unsigned long i, const char *data, size_t szdata)
00233 {
00234         lock(ExclLock);
00235         sset(i, data, szdata);
00236         lock(UnLock);
00237 }
00238 
00239 void NVArray::del(unsigned long i)
00240 {
00241         lock(ExclLock);
00242         sdel(i);
00243         lock(UnLock);
00244 }
00245 
00246 int NVArray::is_empty(void)
00247 {
00248         int r;
00249         lock(ShrdLock);
00250         r = sis_empty();
00251         lock(UnLock);
00252         return r;
00253 }
00254 
00255 int NVArray::has_element(unsigned long i)
00256 {
00257         int r;
00258         lock(ShrdLock);
00259         r = shas_element(i);
00260         lock(UnLock);
00261         return r;
00262 }
00263 
00264 void NVArray::get(unsigned long i, const char **data, size_t * szdata)
00265 {
00266         lock(ShrdLock);
00267         sget(i, (char **) data, szdata);
00268         lock(UnLock);
00269 }
00270 
00271 void NVArray::print(ostream & os)
00272 {
00273         lock(ShrdLock);
00274         sprint(os);
00275         lock(UnLock);
00276 }

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