📄 gdk_bbp.c
字号:
#line 150 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#include "monetdb_config.h"#include "gdk.h"#include "gdk_storage.h"#line 154 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 163 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"BBPrec *BBP = NULL; /* fixed base VM address of BBP array */bat BBPmaxsize = BBPMAXSIZE; /* size of non-commited VM BBP array */bat BBPlimit = 0; /* current committed VM BBP array */bat BBPsize = 0; /* current used size of BBP array */bat BBP_free = 0; /* first free slot in BBP array */#line 170 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 182 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"bat *BBP_hash = NULL; /* BBP logical name hash buckets */bat BBP_mask = 0; /* number of buckets = & mask */static void BBPspin(bat bid, str debug, int event);static int BBPfree(BAT *b, str calledFrom );static int BBPdestroy(BAT *b);static void BBPuncacheit_(bat bid, int unloaddesc);static void BBPinitcache(void);static int BBPprepare(bit subcommit); static int stamp = 0;static INLINE intBBPstamp(void){ return ++stamp;}static voidBBPsetstamp(int newstamp){ stamp = newstamp;}static voidBBP_insert(bat i){ bat idx = (bat) (strHash(BBP_logical(i)) & BBP_mask); BBP_next(i) = BBP_hash[idx]; BBP_hash[idx] = i;}static voidBBP_delete(bat i){ bat *h = BBP_hash; str s = BBP_logical(i); bat idx = (bat) (strHash(s) & BBP_mask); for (h += idx; (i = *h) != 0; h = &BBP_next(i)) { if (strcmp(BBP_logical(i), s) == 0) { *h = BBP_next(i); break; } }}#line 234 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"int BBP_curstamp = 0; /* unique stamp for creation of a bat */MT_Id BBP_notrim = ~((MT_Id) 0); /* avoids BBPtrim when we really do not want it */int BBP_dirty = 0; /* BBP structures modified? */int BBPin = 0; /* bats loaded statistic */int BBPout = 0; /* bats saved statistic */#line 241 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 313 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"static MT_Id locked_by = 0;static INLINE MT_IdBBP_getpid(void){ MT_Id x = MT_getpid(); return x;}static int BBPunloadCnt = 0;voidBBPlock(str nme){ int i; /* wait for all pending unloads to finish */ gdk_set_lock(GDKunloadLock, nme); if (BBPunloadCnt > 0) gdk_wait_cond(GDKunloadCond, GDKunloadLock, nme); gdk_set_lock(GDKtrimLock, nme); BBP_notrim = BBP_getpid(); gdk_set_lock(GDKcacheLock, nme); for (i = 0; i <= BBPLOCKMASK; i++) gdk_set_lock(GDKswapLock[i & BBPLOCKMASK], nme); locked_by = BBP_notrim; gdk_unset_lock(GDKunloadLock, nme);}voidBBPunlock(str nme){ int i; for (i = BBPLOCKMASK; i >= 0; i--) gdk_unset_lock(GDKswapLock[i & BBPLOCKMASK], nme); gdk_unset_lock(GDKcacheLock, nme); BBP_notrim = 0; locked_by = 0; gdk_unset_lock(GDKtrimLock, nme);}static voidBBPinithash(void){ bat i = BBPsize; for (BBP_mask = 1; (BBP_mask << 1) <= BBPlimit; BBP_mask <<= 1) ; BBP_hash = (bat *) GDKmalloc(BBP_mask * sizeof(bat)); memset(BBP_hash, 0, BBP_mask * sizeof(bat)); BBP_mask--; while (--i > 0) { str s = BBP_logical(i); if (s) { if (*s != '.' && BBPtmpcheck(BBP_logical(i)) == 0) { BBP_insert(i); } if (BBP_logical(-i)) { BBP_insert(-i); } } else { BBP_next(i) = BBP_free; BBP_free = i; } }}#line 390 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"voidBBPextend(dbl factor, int buildhash){ int newsize = (int) (BBPlimit * factor); size_t maxsize = MAX(newsize * 2, BBPmaxsize) * sizeof(BBPrec); BBP_notrim = BBP_getpid(); BBP = (BBPrec *) GDKvmrealloc(BBP, BBPlimit * sizeof(BBPrec), newsize * sizeof(BBPrec), BBPmaxsize * sizeof(BBPrec), &maxsize, 1); if (BBP == NULL) GDKfatal("BBPextend: failed to extend BAT pool\n"); memset(BBP + BBPlimit, 0, (newsize - BBPlimit) * sizeof(BBPrec)); BBPlimit = newsize; BBPmaxsize = (int) (maxsize / sizeof(BBPrec)); if (buildhash) { GDKfree(BBP_hash); BBP_hash = NULL; BBP_free = 0; BBPinithash(); } BBP_notrim = 0;}static INLINE char *BBPparse(str *cur){ char *base, *c = *cur; for (c++; GDKisspace(*c); c++) ; for (base = c; !(GDKisspace(*c) || *c == ','); c++) ; *c = 0; *cur = c; return base;}static INLINE strBBPtmpname(str s, int len, bat i){ s[--len] = 0; while(i>0) { s[--len] = '0' + (i & 7); i >>= 3; } s[--len] = '_'; s[--len] = 'p'; s[--len] = 'm'; s[--len] = 't'; return s + len;}static int recover_dir(int direxists) { if (direxists) { /* just try; don't care about these nonvital files */ GDKunlink(BATDIR, "BBP", "bak"); GDKmove(BATDIR, "BBP", "dir", BATDIR, "BBP", "bak"); } return GDKmove(BAKDIR, "BBP", "dir", BATDIR, "BBP", "dir");}#define CONTINUE_IF_NO_SIZES_IN_BBP 1 /* provide backward compatibility */static int BBPrecover_subdir(void);voidBBPinit(void){ FILE *fp = GDKfilelocate("BBP", "rb", "dir"); int i = 0, max_stamp = 0, min_stamp = 0x7fffffff; char *s, logical[1024], batname[1024], path[1024]; char *c, buf[3000]; struct stat st; oid BBPoid = 0; /* first move everything from SUBDIR to the BAKDIR (its parent) */ if (BBPrecover_subdir() < 0) { GDKfatal("BBPinit: cannot properly process %s.\n", SUBDIR); } /* try to obtain a BBP.dir frokm bakdir */ GDKfilepath(path, BAKDIR, "BBP", "dir"); if (stat(path, &st) == 0) { /* backup exists: *must* use it */ if (fp) fclose(fp); fp = recover_dir(fp != NULL)? NULL:GDKfilelocate("BBP", "rb", "dir"); } else if (fp == NULL) { /* there was no BBP.dir either. Panic! try to use a BBP.bak */ GDKfilepath(path, BAKDIR, "BBP", "bak"); if (stat(path, &st)) { /* no BBP.bak (nor BBP.dir or BACKUP/BBP.dir): create a new one */ GDKwarning("BBPdir: initializing BBP.\n"); if (BBPdir(0, NULL) == 0) fp = GDKfilelocate("BBP", "rb", "dir"); } else if (GDKmove(BATDIR, "BBP", "bak", BATDIR, "BBP", "dir") == 0) { GDKwarning("BBPinit: reverting to dir saved in BBP.bak.\n"); fp = GDKfilelocate("BBP", "rb", "dir"); } } if (fp == NULL) { /* now it is time for real panic */ GDKfatal("BBPinit: could not write %s%cBBP.dir\n", BATDIR, DIR_SEP); } /* scan the BBP.dir to obtain its current size */ BBPlimit = BBPINIT; BBPsize = 1; if ((c = fgets(buf, sizeof(buf), fp)) != NULL) { int ptrsize, oidsize; if (sscanf(c, "%d %d", &ptrsize, &oidsize) != 2) {#ifdef CONTINUE_IF_NO_SIZES_IN_BBP GDKwarning("old BBP without size indications: assuming compatible with current server"); GDKwarning("if this assumption is not correct, quit() immediately!"); GDKwarning("otherwise, first commit() to write a new BBP"); ptrsize = SIZEOF_SIZE_T; oidsize = SIZEOF_OID;#else GDKerror("old BBP without size indications"); GDKerror("add a line to the top of the BBP file with two numbers:"); GDKerror("the size (in bytes) of pointers and the size (in bytes) of OIDs\nfor the server the BBP was created with"); exit(1);#endif } else { c = fgets(buf, sizeof(buf), fp); } if (ptrsize != SIZEOF_SIZE_T || oidsize != SIZEOF_OID) { GDKerror("database created with incompatible Mserver"); exit(1); } if (c != NULL) { BBPoid = OIDread(c); if ((c = strstr(c, "BBPsize")) != NULL) { sscanf(c, "BBPsize=%d", &i); i = (int) (i * BATMARGIN); if (i > BBPlimit) BBPlimit = i; } } } /* alloc structures; try to reserve as much space as possible */ for (;;) { size_t size = (size_t) BBPlimit * sizeof(BBPrec); size_t maxsize = (size_t) BBPmaxsize * sizeof(BBPrec); BBP = (BBPrec *) GDKvmalloc(size, &maxsize, 1); MT_alloc_register(BBP, maxsize, 'P'); if (BBP && maxsize >= BBPmaxsize * sizeof(BBPrec)) { BBPmaxsize = (int) (maxsize / sizeof(BBPrec)); break; } MT_alloc_register(BBP, maxsize, 'p'); if (BBP) GDKvmfree(BBP, size, maxsize); if ((BBPmaxsize /= 2) < BBPlimit) { GDKfatal("BBPinit: could not alloc arena\n"); } } memset(BBP, 0, BBPlimit * sizeof(BBPrec)); MT_mmap_pin(BBP, BBPlimit * sizeof(BBPrec)); /* scan the BBP.dir, and insert the BATs into the BBP */ while ((c = fgets(buf, sizeof(buf), fp)) != NULL) { int j = 0; while (*c != '[') c++; for (c++; GDKisspace(*c); c++) ; i = atoi(c); if (GDKisdigit(*c) && i > 0) { for (c++; *c != ','; c++) ; for (c++; GDKisspace(*c); c++) ; j = atoi(c); if (!GDKisdigit(*c)) c--; else for (c++; *c != ','; c++) ; } else { GDKerror("BBPinit: ignore line %s\n", buf); continue; } if (i >= BBPsize) { BBPsize = i + 1; if (BBPsize >= BBPlimit) BBPextend(BATMARGIN, FALSE); } strcpy(batname, BBPparse(&c)); BBP_status_set(i, BBPEXISTING | (j & ~(BBPLOADED | BBPNEW)), "BBPinit"); BBP_physical(i) = GDKstrdup(BBPparse(&c)); BBP_lastused(i) = BBPLASTUSED(atoi(BBPparse(&c))); if (BBP_lastused(i) > max_stamp) max_stamp = BBP_lastused(i); if (BBP_lastused(i) < min_stamp) min_stamp = BBP_lastused(i); BBP_refs(i) = 0; BBP_lrefs(i) = 1; /* any BAT we encounter here is persistent, so has a logical reference */ c = strchr(batname, '~'); if (c && c == batname) { s = BBPtmpname(logical, 64, i); } else { if (c) *c = 0; strcpy(logical, batname); s = logical; j++; } /* the backup of the logical name is set too */ BBP_logical(i) = GDKstrdup(s); BBP[ABS(i)].bak[0] = NULL; BBP[ABS(i)].bak[1] = NULL; if (BBPtmpcheck(s)) /* only backup temp names */ BBP[ABS(i)].bak[(i)<0] = BBP_logical(i); i = -i; if (c && c[1]) { BBP_logical(i) = GDKstrdup(c + 1); /* only backup temp names */ if (BBPtmpcheck(BBP_logical(i))) BBP[ABS(i)].bak[(i)<0] = BBP_logical(i); j++; } else { BBP_logical(i) = NULL; } } fclose(fp); /* normalize saved LRU stamps */ if (min_stamp <= max_stamp) { for (i = 1; i < BBPsize; i++) if (BBPvalid(i)) BBP_lastused(i) -= min_stamp; BBPsetstamp(max_stamp - min_stamp); } BBPinitcache(); /* init hash table */ BBPinithash(); BBP_notrim = 0; if (BBPoid == 0) { OIDseed(OIDrand()); /* if not yet done, init oid */ } OIDbase(BBPoid); /* will call BBPrecover if needed */ if (BBPprepare(0)) { GDKfatal("BBPinit: cannot properly process %s.\n", BAKDIR); } /* cleanup any leftovers (must be done after BBPrecover) */ BBPdiskscan();}#line 653 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 661 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"voidBBPexit(void){ bat i; if (!BBP) return; /* AARGH */ BBPlock("BBPexit"); /* stop all threads ever touching more descriptors */ /* free all memory (just for leak-checking in Purify) */ for (i = 0; i < BBPsize; i++) { if (BBPvalid(i)) { BAT *b = BBP_cache(i); if (b) { if (VIEWparent(b)) VIEWdestroy(b); else BATfree(b); } BBPuncacheit_(i, TRUE); if (BBP_logical(i) != BBP[ABS(i)].bak[(i)<0]) GDKfree(BBP[ABS(i)].bak[(i)<0]); BBP[ABS(i)].bak[(i)<0] = NULL; GDKfree(BBP_logical(i)); BBP_logical(i) = NULL; } if (BBP_physical(i)) { GDKfree(BBP_physical(i)); BBP_physical(i) = NULL; } } GDKfree(BBP_hash); BBP_hash = 0;}#line 700 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 708 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"static intnew_bbpentry(stream *s, bat i){ int r = stream_printf(s, "[ %d, %d, %s", (int) i, BBP_status(i) & BBPPERSISTENT, BBPname(i));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -