⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdk_bbp.c

📁 这个是内存数据库中的一个管理工具
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* return and revive a cached bat from the cache */static INLINE bat batcache_get(int bin) {	batcache_int i = batcache_batbin[bin];	if (i >= 0) {		/* manage fifo-list */  		int bid = batcache[i].bid;		batcache_int j = batcache[i].fifo_prev;		batcache_int k = batcache[i].fifo_next;		if (j < 0) {			assert(batcache_first == i);			batcache_first = k;		} else {			batcache[j].fifo_next = k;		}		if (k < 0) {			assert(batcache_last == i);			batcache_last = j;		} else {			batcache[k].fifo_prev = j; 		}		batcache[i].fifo_next = batcache_free;		batcache_free = i;		/* manage bin-list */  		batcache_batbin[bin] = j = batcache[i].bin_next;		if (j >= 0) batcache[j].bin_prev = -1;		/* revive the bat */		*BBP_logical(bid) = 't';		BBP_refs(bid)++;		/* clearing bits can be done without the lock */		BBP_status_off(bid, BBPUNLOADING, "BBPrecycle");		return bid;	}		return 0;}extern char* BATstring_h;extern char* BATstring_t;static intBBPaddtobin(BAT *b){	int bin = BATCACHE_BIN(b->htype, b->ttype);	bat bid = b->batCacheid, parent = VIEWparent(b);	char *s = BBP_logical(bid);	BAT *m = BBP_cache(-bid);	/* only cache simple non-saved non-renamed transient bats */	if (m == NULL || batcache_minsize == 0 || b->batCopiedtodisk || b->batLview || BBPtmpcheck(s) == 0 || b->htype > TYPE_str || b->ttype > TYPE_str) {		BATdelete(b); /* handles persistent case also (file deletes) */		return 1;	}	if ((parent == 0) && (b->htype | b->ttype)) {		/* additional restrictions do not hold for views and void,void bats */		int bunwidth = batcache_widthbin[bin];		size_t minsize = bunwidth * batcache_minsize;		size_t maxsize = minsize+minsize;		/* bat should be of the right size, types and BUN layoutt */		if (b->batBuns->size < minsize || b->batBuns->size >= maxsize || 		    BUNsize(b) != bunwidth || BATCACHE_NOTYPE(b->htype) || BATCACHE_NOTYPE(b->ttype))		{			BATdelete(b); /* handles persistent case also (file deletes) */			return 1;		} 	} 	assert(BBP_refs(bid) == 0);	assert(BBP_lrefs(bid) == 0);	assert(b->batCacheid > 0);	/* change views into void,void bats */	if (parent) {		BATstore *bs = (BATstore*) b;					/* cut view loose from parent */		VIEWunlink(b);		unshare(parent);		b->batParentid = 0;		/* take care of mirror views */		b->H = m->T = &bs->H;		b->T = m->H = &bs->T;		/* make it a void,void bat */ 		b->dims = m->dims = batcache_dims;		b->batBuns->base = NULL; /* was shared with parent! */		b->hheap = b->theap = NULL;	}	/* free non-reusable stuff that has to be freed anyway */        if (b->hident != BATstring_h) {		if (b->hident) GDKfree(b->hident);                b->hident = BATstring_h;	}        if (b->tident != BATstring_t) {		if (b->tident) GDKfree(b->tident);                b->tident = BATstring_t;	}	if (b->hhash) HASHremove(b);	if (b->thash) HASHremove(BBPcache(-bid));	if (b->H->props) { PROPdestroy(b->H->props); b->H->props = NULL; }	if (b->T->props) { PROPdestroy(b->T->props); b->T->props = NULL; }	gdk_set_lock(GDKcacheLock, "BBPaddtobin");	batcache_put(bin, b->batCacheid);	gdk_unset_lock(GDKcacheLock, "BBPaddtobin");	return 0;}BAT *BBPrecycle(int ht, int tt, ssize_t cap){	int bin = BATCACHE_BIN(ht,tt);	bat bid = 0;	BAT *b;	if (cap > batcache_minsize || BATCACHE_NOTYPE(ht) || BATCACHE_NOTYPE(tt))		return NULL;	gdk_set_lock(GDKcacheLock, "BBPrecycle");	bid = batcache_get(bin);	gdk_unset_lock(GDKcacheLock, "BBPrecycle");	b = BBP_cache(bid);	if (b) {		/* make the bat empty; do this extra work only if the bat is reused (not in BBPaddtobin) */		BAT *m = BBP_cache(-bid);		b->htype = m->ttype = ht; 		b->hsorted = ATOMlinear(ht)?GDK_SORTED:0;		b->dims.headloc = m->dims.tailloc = 0;		b->halign = 0;		b->hkey = m->tkey = FALSE;		b->hdense = 0;		b->hseqbase = m->tseqbase = (ht == TYPE_void) ? oid_nil : 0;		b->ttype = m->htype = tt; 		b->tsorted = ATOMlinear(tt)?GDK_SORTED:0;		b->dims.tailloc = m->dims.headloc = batcache_locbin[bin];		b->talign = 0;		b->tkey = m->hkey = FALSE;		b->tdense = 0;		b->tseqbase = m->hseqbase = (tt == TYPE_void) ? oid_nil : 0;		b->batSet = FALSE;        	b->batFirst = b->batInserted = b->batDeleted = b->batBuns->base;		b->batRestricted = 0;        	b->batBuns->free = 0;        	b->batDirty = TRUE;        	BATsetcount(b,0);		if (b->hheap) memset(b->hheap->base, 0, b->hheap->free = GDK_STRHASHTABLE*sizeof(var_t));		if (b->theap) memset(b->theap->base, 0, b->theap->free = GDK_STRHASHTABLE*sizeof(var_t));		return b;	}	return NULL;}/* query and change the minimum bat size to cache */wrdBBPrecycle_minsize(wrd val){	gdk_set_lock(GDKcacheLock, "BBPrecycle_minsize");	if (val != wrd_nil) {		/* flush the cache */		while(batcache_first >= 0) {			batcache_int i = batcache_del();			batcache[i].fifo_next = batcache_free;			batcache_free = i;		}		batcache_minsize = val; 	}	val = (wrd) batcache_minsize;	gdk_unset_lock(GDKcacheLock, "BBPrecycle_minsize");	return val;}#line 2482 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 2522 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"static BAT *dirty_bat(bat i, int subcommit, int *unload){	if (BBPvalid(i)) {		int unloadable = (BBP_refs(i) == 0);	/* are no other threads currently executing on this image?? */		int newbat = (BBP_status(i) & BBPNEW);		BAT *b;		BBPspin(i, "dirty_bat", BBPSAVING);		b = BBP_cache(i);		if (b != NULL) {			if (BBP_status(i) & BBPPERSISTENT) {				if (unload)					*unload = BATcheckmodes(b, newbat, unloadable) && unloadable;				if (subcommit || BATdirty(b))					return b;	/* the bat is loaded, persistent and dirty */			}		} else if (BBP_status(i) & BBPSWAPPED) {			b = (BAT *) BBPquickdesc(i, TRUE);			if (b) {				if (unload)					(void) BATcheckmodes(b, newbat, 0);				if (subcommit || b->batDirtydesc)					return b;	/* only the desc is loaded & dirty */			}		}	}	return NULL;}#line 2552 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 2559 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"static intfile_move(str srcdir, str dstdir, str name, str e){	long_str ext;	int ret = 0;	strcpy(ext, e);	ret = GDKmove(srcdir, name, ext, dstdir, name, ext);	if (ret == 0) {		return 0;	}	if (ret == 0) {		return 0;	} else {		long_str path;		struct stat st;		GDKfilepath(path, srcdir, name, ext);		if (stat(path, &st)) {			/* source file does not exist; the best recovery is to give an error but continue			 * by considering the BAT as not saved; making sure that this time it does get saved.			 */			return 2;	/* indicate something fishy, but not fatal */		}	}	return 1;}/* returns 1 if the file exists */static intfile_exists(str dir, str name, str ext){	long_str path;	struct stat st;	GDKfilepath(path, dir, name, ext);	return (stat(path, &st) == 0);}static intheap_move(Heap *hp, str srcdir, str dstdir, str nme, str ext){	/* see doc at BATsetaccess()/gdk_bat.mx for an expose on .priv heap modes */	if (file_exists(dstdir, nme, ext)) {		return 0;       /* dont overwrite heap with the committed state already in dstdir */	} else if (hp->filename && hp->storage == STORE_PRIV) {		long_str path;		struct stat st;		GDKfilepath(path, srcdir, nme, ext);		if (stat(path, &st)) {			/* in order to prevent half-saved X files surviving a recover			 * we create a dummy file in the BACKUP(dstdir) whose precense			 * will trigger BBPrecover to remove them. Thus, X.priv will 			 * prevail where it otherwise wouldn't have.			 */			FILE *fp;			long_str kill_ext;			strcpy(kill_ext, ext);			strcat(kill_ext, ".kill");			GDKfilepath(path, dstdir, nme, kill_ext);			fp = fopen(path, "w");			IODEBUG THRprintf(GDKout, "#open %s = %d\n", path, fp?0:-1);			if (fp != NULL) {				fclose(fp);				return 0;			} else {				return 1;			}		}		/* if X.priv already has a saved X, that one is backed up as normal.. */	}	return file_move(srcdir, dstdir, nme, ext);}#line 2635 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 2649 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"static int backup_files = 0, backup_dir = 0, backup_subdir = 0;static intBBPprepare(bit subcommit){	int start_subcommit, ret = 0, set = 1 + subcommit;	/* tmLock is only used here, helds usually very shortly just to protect the file counters */	gdk_unset_lock(GDKtmLock, "BBPprepare");	start_subcommit = (subcommit && backup_subdir == 0);	if (start_subcommit) {		/* starting a subcommit. Make sure SUBDIR and DELDIR are clean */		ret = (BBPrecover_subdir() < 0) ;	}	if (backup_files == 0) {		struct stat st;		backup_dir = 0; 		ret = (stat(BAKDIR, &st) == 0 && BBPrecover()); 		if (ret == 0) {			/* make a new BAKDIR */			ret = mkdir(BAKDIR, 0755);			IODEBUG THRprintf(GDKout, "#mkdir %s = %d\n", BAKDIR, ret);		}	}	if (ret == 0 && start_subcommit) {		/* make a new SUBDIR (subdir of BAKDIR) */		ret = mkdir(SUBDIR, 0755);		IODEBUG THRprintf(GDKout, "#mkdir %s = %d\n", SUBDIR, ret);	}	if (ret == 0 && backup_dir != set) {		/* a valid backup dir *must* at least contain BBP.dir */ 		if (GDKmove(backup_dir?BAKDIR:BATDIR, "BBP", "dir", subcommit?SUBDIR:BAKDIR, "BBP", "dir")) {			ret = 1;		} else {		  	backup_dir = set; 		}	}	/* increase counters */	if (ret == 0) {		backup_subdir += subcommit;		backup_files++;	}	gdk_unset_lock(GDKtmLock, "BBPprepare");	return ret?-1:0;}intBBPbackup(BAT *b, bit subcommit){	long_str srcdir, nme;	str s = BBP_physical(b->batCacheid);	int ret = 0;	if (BBPprepare(subcommit)) {		return -1;	}	if (b->batCopiedtodisk == 0 || nme == NULL || b->batPersistence != PERSISTENT) {		return 0;	}	/* determine location dir and physical suffix */	GDKfilepath(srcdir, BATDIR, s, NULL);	s = strrchr(srcdir, DIR_SEP);	strcpy(nme, ++s);	srcdir[s - srcdir] = 0;        if ((b->batDirty || b->batDirtydesc) && !file_exists(BAKDIR, nme, "desc")) {                /* file will be saved (is dirty), move the old image into backup */        	ret |= file_move(srcdir, subcommit?SUBDIR:BAKDIR, nme, "desc");	} else if (subcommit && (b->batDirty || b->batDirtydesc || file_exists(BAKDIR, nme, "desc"))) {                /* file is clean. move the backup into the subcommit dir (commit should eliminate backup) */		ret |= file_move(BAKDIR, SUBDIR, nme, "desc");        }	if (ret & 1) return -1;#line 2739 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"        #line 2727 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"	if (b->batBuns && b->batBuns->storage != STORE_MMAP) { /* direct mmap is unprotected (readonly usage, or has WAL protection)  */		str ext = (b->batBuns->filename && b->batBuns->storage == STORE_PRIV)?"buns.kill":"buns";		if (( b->batDirty || b->batDirtybuns) && !file_exists(BAKDIR, nme, ext)) {                 	/* file will be saved (is dirty), move the old image into backup */		        ret |= heap_move(b->batBuns, srcdir, subcommit?SUBDIR:BAKDIR, nme, "buns");       		} else if (subcommit && (( b->batDirty || b->batDirtybuns) || file_exists(BAKDIR, nme, ext))) {                	/* file is clean. move the backup into the subcommit dir (commit should eliminate backup) */			ret |= file_move(BAKDIR, SUBDIR, nme, ext);		}		if (ret & 1) return -1;	}#line 2739 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"        #line 2727 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"	if (b->hheap && b->hheap->storage != STORE_MMAP) { /* direct mmap is unprotected (readonly usage, or has WAL protection)  */		str ext = (b->hheap->filename && b->hheap->storage == STORE_PRIV)?"hheap.kill":"hheap";		if (( (b->batDirty || b->hheapdirty) && b->htype && b->hvarsized) && !file_exists(BAKDIR, nme, ext)) {                 	/* file will be saved (is dirty), move the old image into backup */		        ret |= heap_move(b->hheap, srcdir, subcommit?SUBDIR:BAKDIR, nme, "hheap");       		} else if (subcommit && (( (b->batDirty || b->hheapdirty) && b->htype && b->hvarsized) || file_exists(BAKDIR, nme, ext))) {                	/* file is clean. move the backup into the subcommit dir (commit should eliminate backup) */			ret |= file_move(BAKDIR, SUBDIR, nme, ext);		}		if (ret & 1) return -1;	}#line 2740 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"        #line 2727 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"	if (b->theap && b->theap->storage != STORE_MMAP) { /* direct mmap is unprotected (readonly usage, or has WAL protection)  */		str ext = (b->theap->filename && b->theap->storage == STORE_PRIV)?"theap.kill":"theap";		if (( (b->batDirty || b->theapdirty) && b->ttype && b->tvarsized) && !file_exists(BAKDIR, nme, ext)) {                 	/* file will be saved (is dirty), move the old image into backup */		        ret |= heap_move(b->theap, srcdir, subcommit?SUBDIR:BAKDIR, nme, "theap");       		} else if (subcommit && (( (b->batDirty || b->theapdirty) && b->ttype && b->tvarsized) || file_exists(BAKDIR, nme, ext))) {                	/* file is clean. move the backup into the subcommit dir (commit should eliminate backup) */			ret |= file_move(BAKDIR, SUBDIR, nme, ext);		}		if (ret & 1) return -1;	}#line 2741 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"	return 0;}#line 2745 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"#line 2758 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_bbp.mx"intBBPsync(int cnt, bat* subcommit){	int ret = 0, bbpdirty = 0;	int t0 = 0, t1 = 0;	PERFDEBUG t0 = t1 = GDKms();	ret = BBPprepare(subcommit != NULL);	/* PHASE 1: safeguard everything in a backup-dir */	bbpdirty = BBP_dirty;	if (OIDdirty()) {		bbpdirty = BBP_dirty = 1;	}	if (ret == 0) {		int idx = 0;		while(++idx < cnt) {			bat i = subcommit?subcommit[idx]:idx;			if (BBP_status(i) & BBPEXISTING) {				BAT *b = dirty_bat(i, subcommit != NULL, NULL);				if (b != NULL && BBPbackup(b, subcommit != NULL))					break;			}		}		ret = (idx < cnt);	}	PERFDEBUG THRprintf(GDKout, "#BBPsync (move time %d) %d files\n", (t1 = GDKms()) - t0, backup_files);	/* PHASE 2: save the repository */	if (ret == 0) {		int idx = 0;		while(++idx < cnt) {			bat i = subcommit?subcommit[idx]:idx;			if (BBP_status(i) & BBPPERSISTENT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -