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
00182
00183
00184
00185
00186 lock(ExclLock);
00187 int ok = 1;
00188 unsigned long i, n;
00189
00190 if (arrfst <= arrlst) {
00191
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 }