#include <NVcontainer.h>
Inheritance diagram for NVcontainer:

Public Types | |
| enum | { UnLock = F_UNLCK, ShrdLock = F_RDLCK, ExclLock = F_WRLCK } |
| enum | { Block = 0x0, NoBlock = 0x1 } |
Public Member Functions | |
| int | lock (int command, int block=Block) |
| int | get_lock (void) |
| virtual void | open (const char *dbname, int flags=0) |
| virtual int | is_open (void) |
| virtual void | close (void) |
| void | rename_to_bad_and_close (void) |
| void | setmtime (nvtime_t tm, int force=0) |
| void | getmtime (nvtime_t *tm) |
Protected Member Functions | |
| NVcontainer (void) | |
| NVcontainer (const char *dbname, int flags=0) | |
| virtual | ~NVcontainer (void) |
| virtual void | make_current (void) |
| virtual int | is_current (void) |
| virtual size_t | resize (size_t nsz) |
| nvoff_t | getdata () |
| nvoff_t | getdatap () |
| void | setdata (nvoff_t d) |
| nvoff_t | nvalloc (size_t rsz) |
| void | nvfree (nvoff_t f) |
Protected Attributes | |
| char * | mem_p |
| size_t | mem_sz |
Private Member Functions | |
| FreeList * | o2fl (nvoff_t o) |
| nvoff_t | fl2o (FreeList *r) |
Private Attributes | |
| int | lck_stack [NVcontainer_LOCKSTACKSIZE] |
| int | lck_stackp |
| char | mem_fn [MAXPATHLEN] |
| int | mem_fd |
| Header * | mem_hdr |
Definition at line 29 of file NVcontainer.h.
|
|
Definition at line 98 of file NVcontainer.h.
|
|
|
Definition at line 103 of file NVcontainer.h.
|
|
|
Definition at line 102 of file NVcontainer.cc. References lck_stackp, mem_fd, mem_fn, mem_hdr, mem_p, and NVcontainer_LOCKSTACKSIZE.
00103 {
00104 lck_stackp = NVcontainer_LOCKSTACKSIZE;
00105 mem_fn[0] = '\0';
00106 mem_fd = -1;
00107 mem_p = NULL;
00108 mem_hdr = (Header *) mem_p;
00109 }
|
|
||||||||||||
|
Definition at line 111 of file NVcontainer.cc. References lck_stackp, mem_fd, NVcontainer_LOCKSTACKSIZE, and open().
00112 {
00113 lck_stackp = NVcontainer_LOCKSTACKSIZE;
00114 mem_fd = -1;
00115 open(dbname, flags);
00116 }
|
|
|
Definition at line 118 of file NVcontainer.cc. References close().
00119 {
00120 close();
00121 }
|
|
|
Reimplemented in NVActiveDB. Definition at line 705 of file NVcontainer.cc. References lck_stackp, mem_fd, mem_fn, mem_hdr, mem_p, mem_sz, NVcontainer_LOCKSTACKSIZE, slog, and VERB. Referenced by NVActiveDB::close(), nvfree(), open(), rename_to_bad_and_close(), and ~NVcontainer().
00706 {
00707 if (mem_fd < 0)
00708 return;
00709 munmap(mem_p, mem_sz);
00710 ::close(mem_fd);
00711 if (lck_stackp != NVcontainer_LOCKSTACKSIZE) {
00712 VERB(slog.
00713 p(Logger::
00714 Critical) <<
00715 "NVcontainer::close: Forgot to unlock the container before closing it!\n");
00716 lck_stackp = NVcontainer_LOCKSTACKSIZE;
00717 }
00718 mem_fn[0] = '\0';
00719 mem_fd = -1;
00720 mem_p = NULL;
00721 mem_hdr = (Header *) mem_p;
00722 }
|
|
|
Definition at line 62 of file NVcontainer.h. References mem_p, and nvoff_t. Referenced by nvalloc(), and nvfree().
00062 {
00063 return r ? (char *) r - mem_p : 0;
00064 }
|
|
|
Reimplemented in NVActiveDB. Definition at line 603 of file NVcontainer.cc. References lck_stack, lck_stackp, NVcontainer_LOCKSTACKSIZE, and UnLock. Referenced by NVActiveDB::get_lock().
00604 {
00605 return lck_stackp <
00606 NVcontainer_LOCKSTACKSIZE ? lck_stack[lck_stackp] : UnLock;
00607 }
|
|
|
Definition at line 236 of file NVcontainer.cc. References mem_hdr, nvoff_t, and NVcontainer::Header::userdata. Referenced by NVListIter::attach(), NVHash::make_current(), NVArray::make_current(), NVList::remove(), and NVArray::ssetsize().
|
|
|
Definition at line 241 of file NVcontainer.cc. References mem_hdr, mem_p, nvoff_t, and NVcontainer::Header::userdata. Referenced by NVList::append(), NVList::clear(), NVList::is_empty(), NVList::prepend(), NVList::print(), and NVList::remove().
|
|
|
Definition at line 748 of file NVcontainer.cc. References lock(), mem_hdr, NVcontainer::Header::mtime, nvtime_t, ShrdLock, and UnLock. Referenced by NVActiveDB::getmtime(), and CNewsgroup::updateOverview().
|
|
|
Definition at line 86 of file NVcontainer.h. References mem_hdr, mem_sz, and NVcontainer::Header::size. Referenced by NVHash::make_current(), make_current(), and NVArray::make_current().
|
|
|
Reimplemented in NVActiveDB. Definition at line 700 of file NVcontainer.cc. References mem_fd. Referenced by NVActiveDB::is_open().
00701 {
00702 return mem_fd >= 0;
00703 }
|
|
||||||||||||
|
|
Reimplemented in NVArray, and NVHash. Definition at line 123 of file NVcontainer.cc. References ERROR_LOCATION, NVcontainer::Header::hlen, is_current(), mem_fd, mem_fn, mem_hdr, mem_p, mem_sz, nvoff_t, Logger::p(), rename_to_bad_and_close(), NVcontainer::Header::size, slog, and NVcontainer::Header::version. Referenced by lock(), NVHash::make_current(), NVArray::make_current(), open(), and resize().
00124 {
00125 struct stat st;
00126
00127 if (mem_p) {
00128 if (is_current())
00129 return;
00130 munmap(mem_p, mem_sz);
00131 }
00132
00133 if (fstat(mem_fd, &st) < 0) {
00134 throw SystemError("NVContainer(20801): fstat failed",
00135 errno, ERROR_LOCATION);
00136 }
00137
00138 if ((nvoff_t) st.st_size <=
00139 (nvoff_t) sizeof(Header) + (nvoff_t) sizeof(FreeList)) {
00140 #ifdef HAVE_SSTREAM
00141 stringstream sb;
00142 #else
00143 strstream sb;
00144 #endif
00145 sb << "NVConatiner::make_current(): info-record shrunk;"
00146 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00147 << " st.st_size: " << (unsigned long int) st.st_size
00148 << " sizeof(Header): " << (unsigned long int) sizeof(Header);
00149 throw Error(sb.rdbuf()->str(), ERROR_LOCATION);
00150 }
00151
00152 mem_sz = st.st_size;
00153 mem_p = (char *) mmap(NULL, mem_sz,
00154 PROT_READ | PROT_WRITE, MAP_SHARED,
00155 mem_fd, 0);
00156 if (mem_p == (char *) -1) {
00157 mem_p = NULL;
00158 throw SystemError("NVContainer::make_current(): mmap failed", errno,
00159 ERROR_LOCATION);
00160 }
00161 mem_hdr = (Header *) mem_p;
00162 //Do some sanity checks on the database
00163 if (mem_hdr->hlen != sizeof(Header)) {
00164 #ifdef HAVE_SSTREAM
00165 stringstream sb;
00166 #else
00167 strstream sb;
00168 #endif
00169 sb << "NVConatiner::make_current(): wrong header size"
00170 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00171 << " mem_hdr->hlen: " << (unsigned long int) mem_hdr->hlen
00172 << " sizeof(Header): " << (unsigned long int) sizeof(Header);
00173 rename_to_bad_and_close(); // close manipulate the member structure !!
00174 throw Error(sb.rdbuf()->str(), ERROR_LOCATION);
00175 }
00176 if (mem_hdr->version != 2) {
00177 #ifdef HAVE_SSTREAM
00178 stringstream sb;
00179 #else
00180 strstream sb;
00181 #endif
00182 sb << "NVConatiner::make_current(): wrong header version"
00183 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00184 << " mem_hdr->version: " << (unsigned long int) mem_hdr->version;
00185 rename_to_bad_and_close(); // close manipulate the member structure !!
00186 throw Error(sb.rdbuf()->str(), ERROR_LOCATION);
00187 }
00188 if (mem_sz != mem_hdr->size) {
00189 #ifdef HAVE_SSTREAM
00190 stringstream sb;
00191 #else
00192 strstream sb;
00193 #endif
00194 sb << "NVConatiner::make_current(): wrong database size stored "
00195 << "in db-header - may be a hazard"
00196 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00197 << " mem_sz: " << (unsigned long int) mem_sz
00198 << " mem_hdr->size: " << (unsigned long int) mem_hdr->size;
00199 slog.p(Logger::Critical) << sb.rdbuf()->str();
00200 }
00201 }
|
|
|
Definition at line 251 of file NVcontainer.cc. References ASSERT, NVcontainer::Header::bytes_free, ERROR_LOCATION, ExclLock, fl2o(), NVcontainer::Header::freelist, lock(), mem_hdr, mem_p, mem_sz, NVcontainer::FreeList::next, nvoff_t, o2fl(), Logger::p(), resize(), NVcontainer::FreeList::size, slog, UnLock, and VERB. Referenced by NVHash::open(), NVlist::sappend(), NVNewsgroup::setarticle(), NVNewsgroup::setover(), NVlist::sprepend(), NVArray::sset(), and NVArray::ssetsize().
00252 {
00253 lock(ExclLock);
00254 FreeList *flhead = o2fl(mem_hdr->freelist);
00255 FreeList *cur, *prv, *res;
00256
00257 // The allocated memory block has to meet several requirements
00258 // * aligned on 16 Byte boundary
00259 // * size has to be a multiple of 16 (simplifies the alignment)
00260 // * the allocated block has to hold its size
00261 // the memory after the size indicator will be returned
00262 rsz = (rsz + sizeof(unsigned long) + 0xf) & (~0xf);
00263 if (flhead == NULL) {
00264 throw Error ("NVContainer(5946): Database file corrupted (freelist==NULL)",
00265 ERROR_LOCATION);
00266 }
00267 // flhead points to the last free memory block available in the database
00268 prv = flhead;
00269 cur = o2fl(prv->next);
00270 // find the first suitable memory block in the database
00271 while (cur->size < rsz && cur != flhead) {
00272 prv = cur;
00273 cur = o2fl(cur->next);
00274 }
00275
00276 if (cur == flhead) {
00277 // Special care has to be taken for the last free memory block
00278 // It must always be present! So we have to resize it, if its
00279 // memory is smaller than the requested size plus the size
00280 // necessary to maintain the last block of free memory.
00281 if (flhead->size < rsz + sizeof(FreeList)) {
00282 nvoff_t prvoff = fl2o(prv);
00283 // Since it is very likely that the mapped region will change
00284 // during the resize operation, we will have to save the
00285 // currently used pointers
00286 int needsz = rsz + sizeof(FreeList) - flhead->size;
00287 resize(mem_sz + needsz);
00288 cur = flhead = o2fl(mem_hdr->freelist);
00289 prv = o2fl(prvoff);
00290 ASSERT(if (cur->size < rsz + sizeof(FreeList)) {
00291 throw
00292 AssertionError
00293 ("NVContainer::nvalloc: resize failed",
00294 ERROR_LOCATION);}
00295 );
00296 }
00297 }
00298 ASSERT(if (cur->size < rsz) {
00299 throw
00300 AssertionError
00301 ("NVContainer::nvalloc: did not find a large enough free memory block",
00302 ERROR_LOCATION);}
00303 );
00304
00305 res = cur;
00306
00307 if (cur->size < rsz + sizeof(FreeList)) {
00308 // The available space is too small to split?
00309 // This may only occur if cur _is_not_ the tail of the free blocks
00310 ASSERT(if (res == flhead) {
00311 throw
00312 AssertionError
00313 ("NVContainer::nvalloc: Cannot split block of free memory at tail of database",
00314 ERROR_LOCATION);}
00315 );
00316 prv->next = cur->next;
00317 rsz = cur->size;
00318 } else {
00319 // Split the space into two parts
00320 cur = (FreeList *) ((char *) cur + rsz);
00321 cur->size = res->size - rsz;
00322 if (prv != res) {
00323 // list contains at least two blocks
00324 cur->next = res->next;
00325 prv->next = fl2o(cur);
00326 if (res == flhead) {
00327 mem_hdr->freelist = fl2o(cur);
00328 }
00329 } else {
00330 // list contains only one block pointing to itself
00331 // this must be the free memory block at the tail
00332 ASSERT(if (res != flhead) {
00333 throw
00334 AssertionError
00335 ("NVList::nvalloc: Lost block of free memory at tail of database",
00336 ERROR_LOCATION);}
00337 );
00338 mem_hdr->freelist = cur->next = fl2o(cur);
00339 }
00340 }
00341 mem_hdr->bytes_free -= rsz;
00342 lock(UnLock);
00343
00344 *(unsigned long *) res = rsz;
00345 #ifdef FREELIST_ASSERT_ON
00346 char buf[256];
00347 int i = 10000;
00348 prv = flhead = o2fl(mem_hdr->freelist);;
00349 cur = o2fl(prv->next);
00350
00351 VERB(sprintf
00352 (buf, "nvalloc: checking freelist flhead=%p\n", flhead);
00353 slog.p(Logger::Debug) << buf);
00354 while (cur != flhead && i) {
00355 VERB(sprintf
00356 (buf, "nvalloc: elem(%lu)={%lu,%lu}\n",
00357 (nvoff_t) ((char *) cur - mem_p), cur->next,
00358 cur->size); slog.p(Logger::Debug) << buf);
00359 prv = cur;
00360 cur = o2fl(cur->next);
00361 ASSERT(if (prv >= cur) {
00362 throw
00363 AssertionError
00364 ("NVContainer::nvalloc: freelist out of order!",
00365 ERROR_LOCATION);}
00366 );
00367 i--;
00368 }
00369 VERB(sprintf
00370 (buf, "nvfree: tail(%lu)={%lu,%lu}\n",
00371 (nvoff_t) ((char *) cur - mem_p), cur->next, cur->size);
00372 slog.p(Logger::Debug) << buf);
00373 if (!i)
00374 VERB(slog.
00375 p(Logger::
00376 Debug) <<
00377 "nvalloc: more than 10000 free blocks!\n");
00378 #endif
00379 return (nvoff_t) ((char *) res - mem_p) + sizeof(unsigned long);
00380 }
|
|
|
Definition at line 382 of file NVcontainer.cc. References ASSERT, NVcontainer::Header::bytes_free, close(), ERROR_LOCATION, ExclLock, fl2o(), NVcontainer::Header::freelist, lock(), mem_hdr, mem_p, mem_sz, NVcontainer::FreeList::next, nvoff_t, o2fl(), Logger::p(), NVcontainer::FreeList::size, slog, UnLock, and VERB. Referenced by CNewsgroup::prefetchGroup(), NVArray::sclear(), NVArray::sdel(), NVNewsgroup::setarticle(), NVNewsgroup::setsize(), NVArray::setsize(), NVlist::sremove(), NVArray::sset(), NVArray::ssetsize(), and CNewsgroup::sUpdateOverview().
00383 {
00384 #ifdef FREELIST_ASSERT_ON
00385 VERB(char buf[256];
00386 sprintf(buf, "NVcontainer::nvfree(%lu)\n", p);
00387 slog.p(Logger::Debug) << buf);
00388 #endif
00389 lock(ExclLock);
00390
00391 FreeList *pb, *pe;
00392 int psz;
00393 #ifdef FREELIST_ASSERT_ON
00394 FreeList *flhead;
00395 FreeList *cur, *prv;
00396 int i = 10000;
00397 prv = flhead = o2fl(mem_hdr->freelist);;
00398 cur = o2fl(prv->next);
00399
00400 VERB(sprintf(buf, "NVContainer::nvfree: checking freelist flhead=%p\n", flhead);
00401 slog.p(Logger::Debug) << buf);
00402 while (cur != flhead && i) {
00403 VERB(sprintf
00404 (buf, "NVContainer::nvfree: elem(%lu)={%lu,%lu}\n",
00405 (nvoff_t) ((char *) cur - mem_p), cur->next,
00406 cur->size); slog.p(Logger::Debug) << buf);
00407 prv = cur;
00408 cur = o2fl(cur->next);
00409 ASSERT(if (prv >= cur) {
00410 throw
00411 AssertionError
00412 ("NVContainer::nvfree: freelist out of order!",
00413 ERROR_LOCATION);}
00414 );
00415 i--;
00416 }
00417 VERB(sprintf
00418 (buf, "NVContainer::nvfree: tail(%lu)={%lu,%lu}\n",
00419 (nvoff_t) ((char *) cur - mem_p), cur->next, cur->size);
00420 slog.p(Logger::Debug) << buf);
00421 if (!i)
00422 VERB(slog.
00423 p(Logger::
00424 Debug) << "NVContainer::nvfree: more than 10000 free blocks!\n");
00425 #else
00426 FreeList *flhead = o2fl(mem_hdr->freelist);
00427 FreeList *cur = NULL, *prv = NULL;
00428 #endif
00429
00430 pb = o2fl(p - sizeof(unsigned long));
00431 psz = *(unsigned long *) pb;
00432 pe = (FreeList *) ((char *) pb + psz);
00433
00434 // ASSERT(memset(pb,255,psz));
00435 ASSERT(if ((char *) pb < mem_p || mem_p + mem_sz < (char *) pe) {
00436 char buf[1024];
00437 close();
00438 sprintf(buf,
00439 "NVcontainer::nvfree: tried to free illegal memory block ([%p,%p])!\nNVcontainer mapped from [%p,%p]",
00440 pb, pe, mem_p, mem_p + mem_sz);
00441 throw AssertionError(buf, ERROR_LOCATION);});
00442
00443 // flhead points to the last free memory block available in the database
00444 prv = flhead;
00445 cur = o2fl(prv->next);
00446 while (cur < pb && cur != flhead) {
00447 prv = cur;
00448 cur = o2fl(cur->next);
00449 ASSERT(if (prv >= cur) {
00450 throw
00451 AssertionError
00452 ("NVContainer::nvfree: freelist out of order!",
00453 ERROR_LOCATION);}
00454 );
00455 }
00456 ASSERT(if (cur < pb) {
00457 char buf[1024];
00458 close();
00459 sprintf(buf,
00460 "NVcontainer::nvfree: tried to free unallocated memory block ([%p,%p])!\n Address must be smaller than flhead (%p)!\nNVcontainer mapped from[%p,%p]",
00461 pb, pe, flhead, mem_p, mem_p + mem_sz);
00462 throw AssertionError(buf, ERROR_LOCATION);});
00463
00464 if ((char *) prv + prv->size == (char *) pb) {
00465 #ifdef FREELIST_ASSERT_ON
00466 VERB(slog.
00467 p(Logger::Debug) << "NVContainer::nvfree: adjacent to previous\n");
00468 #endif
00469 // The freed block is adjacent to the previous free block
00470 prv->size += psz;
00471 if (pe == cur) {
00472 #ifdef FREELIST_ASSERT_ON
00473 VERB(slog.
00474 p(Logger::
00475 Debug) <<
00476 "NVContainer::nvfree: adjacent to next---cool\n");
00477 #endif
00478 // The freed block is adjacent to the next free block too, cool :)
00479 if (cur == flhead)
00480 mem_hdr->freelist = fl2o(prv);
00481 prv->size += cur->size;
00482 prv->next = cur->next;
00483 }
00484 } else if (pe == cur) {
00485 #ifdef FREELIST_ASSERT_ON
00486 VERB(slog.
00487 p(Logger::Debug) << "NVContainer::nvfree: adjacent to next\n");
00488 #endif
00489 // The freed block is adjacent to the next free block
00490 if (cur->next == fl2o(cur)) {
00491 // Only one block of free memory left
00492 ASSERT(if (flhead != cur) {
00493 throw
00494 AssertionError
00495 ("NVContainer::nvfree: flhead lost trailing block of free memory",
00496 ERROR_LOCATION);}
00497 );
00498 mem_hdr->freelist = pb->next = fl2o(pb);
00499 pb->size = psz + cur->size;
00500 } else {
00501 pb->next = cur->next;
00502 pb->size = psz + cur->size;
00503 prv->next = fl2o(pb);
00504 if (cur == flhead)
00505 mem_hdr->freelist = fl2o(pb);
00506 }
00507 } else {
00508 VERB(slog.p(Logger::Debug) << "NVContainer::nvfree: not adjacent\n");
00509 // The freed block neither is adjacent to the previous nor to the
00510 // next free block
00511 pb->next = fl2o(cur);
00512 pb->size = psz;
00513 prv->next = fl2o(pb);
00514 }
00515 mem_hdr->bytes_free += psz;
00516 #ifdef FREELIST_ASSERT_ON
00517 i = 10000;
00518 prv = flhead = o2fl(mem_hdr->freelist);;
00519 cur = o2fl(prv->next);
00520
00521 VERB(sprintf(buf, "NVContainer::nvfree: checking freelist flhead=%p\n", flhead);
00522 slog.p(Logger::Debug) << buf);
00523 while (cur != flhead && i) {
00524 VERB(sprintf
00525 (buf, "NVContainer::nvfree: elem(%lu)={%lu,%lu}\n",
00526 (nvoff_t) ((char *) cur - mem_p), cur->next,
00527 cur->size); slog.p(Logger::Debug) << buf);
00528 prv = cur;
00529 cur = o2fl(cur->next);
00530 ASSERT(if (prv >= cur) {
00531 throw
00532 AssertionError
00533 ("NVContainer::nvfree: freelist out of order!",
00534 ERROR_LOCATION);}
00535 );
00536 i--;
00537 }
00538 VERB(sprintf
00539 (buf, "NVContainer::nvfree: tail(%lu)={%lu,%lu}\n",
00540 (nvoff_t) ((char *) cur - mem_p), cur->next, cur->size);
00541 slog.p(Logger::Debug) << buf);
00542 if (!i)
00543 VERB(slog.
00544 p(Logger::
00545 Debug) << "NVContainer::nvfree: more than 10000 free blocks!\n");
00546 #endif
00547 lock(UnLock);
00548 }
|
|
|
Definition at line 59 of file NVcontainer.h. References mem_p. Referenced by nvalloc(), nvfree(), and resize().
00059 {
00060 return (FreeList *) (o ? mem_p + o : NULL);
00061 }
|
|
||||||||||||
|
Definition at line 611 of file NVcontainer.cc. References ASSERT, Block, NVcontainer::Header::bytes_free, close(), ERROR_LOCATION, ExclLock, NVcontainer::Header::freelist, NVcontainer::Header::hlen, make_current(), mem_fd, mem_fn, NVcontainer::FreeList::next, nvflock(), NVcontainer::FreeList::size, NVcontainer::Header::size, and UnLock. Referenced by NVArray::NVArray(), NVcontainer(), NVNewsgroup::NVNewsgroup(), and NVHash::open().
00612 {
00613 ASSERT(if (!dbname) throw
00614 AssertionError
00615 ("NVContainer::open() called with null-pointer\n",
00616 ERROR_LOCATION));
00617
00618 if (strcmp(mem_fn, dbname) == 0)
00619 return;
00620
00621 if (mem_fd >= 0)
00622 close();
00623
00624 struct stat st;
00625
00626 flags = 0;
00627 strcpy(mem_fn, dbname);
00628 if ((mem_fd =::open(mem_fn, O_RDWR | O_CREAT, 0644)) < 0) {
00629 #ifdef HAVE_SSTREAM
00630 stringstream sb;
00631 #else
00632 strstream sb;
00633 #endif
00634 sb << "NVConatiner::open(): cannot open("
00635 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00636 << ",O_RDWR|O_CREAT)";
00637 throw SystemError(sb.rdbuf()->str(), errno, ERROR_LOCATION);
00638 }
00639
00640 nvflock(mem_fd, ExclLock, Block);
00641 if (fstat(mem_fd, &st) < 0) {
00642 #ifdef HAVE_SSTREAM
00643 stringstream sb;
00644 #else
00645 strstream sb;
00646 #endif
00647 sb << "NVConatiner::open(): fstat failed"
00648 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn));
00649 throw SystemError(sb.rdbuf()->str(), errno, ERROR_LOCATION);
00650 }
00651 if (st.st_size == 0) {
00652 Header hdr;
00653 FreeList fl;
00654 hdr.freelist = hdr.hlen;
00655 hdr.size = 0x10000;
00656 fl.next = hdr.freelist;
00657 fl.size = hdr.bytes_free = hdr.size - hdr.hlen;
00658
00659 if (ftruncate(mem_fd, hdr.size) < 0) {
00660 unlink(mem_fn);
00661 #ifdef HAVE_SSTREAM
00662 stringstream sb;
00663 #else
00664 strstream sb;
00665 #endif
00666 sb << "NVConatiner::open(): ftruncate failed, unlinked"
00667 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn));
00668 throw SystemError (sb.rdbuf()->str(), errno, ERROR_LOCATION);
00669 }
00670 if (write(mem_fd, &hdr, sizeof(Header)) != sizeof(Header)) {
00671 unlink(mem_fn);
00672 #ifdef HAVE_SSTREAM
00673 stringstream sb;
00674 #else
00675 strstream sb;
00676 #endif
00677 sb << "NVConatiner::open(): write(info-record) failed, unlinked"
00678 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn));
00679 throw SystemError (sb.rdbuf()->str(), errno, ERROR_LOCATION);
00680 }
00681 if (write(mem_fd, &fl, sizeof(FreeList)) !=
00682 sizeof(FreeList)) {
00683 unlink(mem_fn);
00684 #ifdef HAVE_SSTREAM
00685 stringstream sb;
00686 #else
00687 strstream sb;
00688 #endif
00689 sb << "NVConatiner::open(): write(free-record) failed unlinked"
00690 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn));
00691 throw SystemError (sb.rdbuf()->str(), errno, ERROR_LOCATION);
00692 }
00693 }
00694 nvflock(mem_fd, UnLock, Block);
00695
00696 //Sanity checks of an existing database will be done in
00697 make_current();
00698 }
|
|
|
Definition at line 724 of file NVcontainer.cc. References close(), Logger::Error, mem_fn, Logger::p(), and slog. Referenced by make_current().
00725 {
00726 string f_new = mem_fn;
00727
00728 f_new += ".bad";
00729 slog.p(Logger::Error) << "NVcontainer::rename_to_bad_and_close: "
00730 << "Error: bad database file: " << f_new << "\n";
00731 if (rename (mem_fn, f_new.c_str()) != 0) {
00732 slog.p (Logger::Error) << "NVcontainer::rename_to_bad_and_close: "
00733 << "rename error: errno=" << errno << " errtxt: "
00734 << strerror (errno) << "\n";
00735 }
00736 close ();
00737 }
|
|
|
Definition at line 203 of file NVcontainer.cc. References NVcontainer::Header::bytes_free, ERROR_LOCATION, ExclLock, NVcontainer::Header::freelist, lock(), make_current(), mem_fd, mem_fn, mem_hdr, mem_sz, o2fl(), NVcontainer::Header::size, NVcontainer::FreeList::size, slog, UnLock, and VERB. Referenced by nvalloc().
00204 {
00205 if (nsz < mem_sz) {
00206 VERB(slog.
00207 p(Logger::
00208 Warning) <<
00209 "NVContainer: reduction of database size not supported, ignored\n");
00210 return mem_sz;
00211 }
00212
00213 lock(ExclLock);
00214 FreeList *flhead = o2fl(mem_hdr->freelist);
00215
00216 nsz = (nsz + 0x10000) & (~0xffff);
00217 if (ftruncate(mem_fd, nsz) < 0) {
00218 #ifdef HAVE_SSTREAM
00219 stringstream sb;
00220 #else
00221 strstream sb;
00222 #endif
00223 sb << "NVConatiner::resize(): ftruncate failed "
00224 << " mem_fn: " << ((mem_fn==NULL)? ("NULL") : (mem_fn))
00225 << " nsz: " << (unsigned long int) nsz;
00226 throw SystemError(sb.rdbuf()->str(), errno, ERROR_LOCATION);
00227 }
00228 mem_hdr->bytes_free += nsz - mem_sz;
00229 flhead->size += nsz - mem_sz;
00230 mem_hdr->size = nsz;
00231 make_current();
00232 lock(UnLock);
00233 return mem_sz;
00234 }
|
|
|
Definition at line 246 of file NVcontainer.cc. References mem_hdr, nvoff_t, and NVcontainer::Header::userdata. Referenced by NVHash::open(), and NVArray::ssetsize().
|
|
||||||||||||
|
Definition at line 739 of file NVcontainer.cc. References ExclLock, lock(), mem_hdr, NVcontainer::Header::mtime, nvtime_t, and UnLock. Referenced by CNewsgroup::prefetchGroup(), NVNewsgroup::readoverdb(), NVActiveDB::setmtime(), CNewsgroup::setsize(), and CNewsgroup::sUpdateOverview().
|
|
|
Definition at line 52 of file NVcontainer.h. Referenced by get_lock(), and lock(). |
|
|
Definition at line 53 of file NVcontainer.h. Referenced by close(), get_lock(), lock(), and NVcontainer(). |
|
|
Definition at line 56 of file NVcontainer.h. Referenced by close(), is_open(), lock(), make_current(), NVcontainer(), open(), and resize(). |
|
|
Definition at line 55 of file NVcontainer.h. Referenced by close(), make_current(), NVcontainer(), open(), rename_to_bad_and_close(), and resize(). |
|
|
Definition at line 57 of file NVcontainer.h. Referenced by close(), getdata(), getdatap(), getmtime(), is_current(), make_current(), nvalloc(), NVcontainer(), nvfree(), resize(), setdata(), and setmtime(). |
|
|
Definition at line 71 of file NVcontainer.h. Referenced by close(), NVListIter::data(), NVHashIter::data(), fl2o(), NVActiveDB_Iter::get(), getdatap(), make_current(), nvalloc(), NVcontainer(), nvfree(), and o2fl(). |
|
|
Definition at line 72 of file NVcontainer.h. Referenced by close(), is_current(), make_current(), nvalloc(), nvfree(), and resize(). |
1.3.6-20040222