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

📄 gdk_bat.mx

📁 这个是内存数据库中的一个管理工具
💻 MX
📖 第 1 页 / 共 5 页
字号:
					(*hatmdel)(b->hheap, (var_t*) BUNhloc(b,p));				if (tatmdel)					(*tatmdel)(b->theap, (var_t*) BUNtloc(b,p));			}		}	}	b->batFirst = b->batInserted;	b->batBuns->free = b->batInserted - b->batBuns->base;	BATsetcount(b,0);	b->batDirty = TRUE;	return b; }/* free a cached BAT; leave the bat descriptor cached */intBATfree(BAT *b){	BATcheck(b, "BATfree");	/* deallocate all memory for a bat */	if (b->batCacheid < 0)		b = BBP_cache(-(b->batCacheid));	if (b->hident && !default_ident(b->hident)) 		GDKfree(b->hident);	b->hident = BATstring_h;	if (b->tident && !default_ident(b->tident)) 		GDKfree(b->tident);	b->tident = BATstring_t;	if (b->H->props)		PROPdestroy(b->H->props);	b->H->props = NULL;	if (b->T->props)		PROPdestroy(b->T->props);	b->T->props = NULL;	HASHdestroy(b);	DELTAsave(b);	       /* convert to disk format */	if (b->htype != b->ttype || b->htype != TYPE_void)		HEAPfree(b->batBuns);	if (b->hheap) 		HEAPfree(b->hheap);	if (b->theap) 		HEAPfree(b->theap);	b = BBP_cache(-b->batCacheid);	if (b) {		BBP_cache(b->batCacheid) = NULL;		GDKfree(b);	}	return 0;}/* free a cached BAT descriptor */voidBATdestroy( BAT *b ){	if (b->hident && !default_ident(b->hident)) 		GDKfree(b->hident);	b->hident = BATstring_h;	if (b->tident && !default_ident(b->tident)) 		GDKfree(b->tident);	b->tident = BATstring_t;	if (b->hheap)		GDKfree(b->hheap);	if (b->theap)		GDKfree(b->theap);	if (b->H->props)		PROPdestroy(b->H->props);	if (b->T->props)		PROPdestroy(b->T->props);	GDKfree(b);}@}@+ BAT copyingBAT copying is an often used operation. So it deserves attention.When making a copy of a BAT, the following aspects are of importance:@itemize @item the requested head and tail types. The purpose of the copy may be to slightly change these types (e.g. void <-> oid). We may also remap between types as long as they share the same ATOMstorage(type), i.e. the typeshave the same physical implementation. We may even want to allow 'dirty'trick such as viewing a flt-column suddenly as int.To allow such changes, the desired head- and tail-types are a parameter of BATcopy.@item access mode. If we want a read-only copy of a read-only BAT, aVIEW may do (in this case, the user may be after just an independent BAT header and id). This is indicated by the parameter (writeable = FALSE).  In other cases, we really want an independent physical copy (writeable = TRUE).Note that in the MIL interpreter (as opposed to the C/C++ GDK API), the result of MIL-copy() will by default be BAT_READ, the default mode for all new BATs. However, changing the mode to BAT_WRITE will be a zero-cost operation if the BAT was copied with (writeable = TRUE), such as done by MIL-copy().@end itemizeIn GDK, the result is a BAT that is BAT_WRITE iff (writeable == TRUE).NEW: there is now a special parameter setting (writeable == 2), which does createan independent BAT (not a view that shares the same heaps), however tries to share VM heap resources using copy-on-write maps. Note that the result ofthis is a read-only BAT (BAT_READ). The copy-on-write VM tricks can be used, however, to isolate these copies from changes the in parent.In these cases the copy becomes a logical view on the original, which ensuresthat the original cannot be modified or destroyed (which could affect the shared heaps).This new mode is used by the XQuery isolation mechanism and is available in MIL as rcopy(). @{@cstatic int heapcopy(Heap* dst, Heap* src, int *remap) {	if (*remap && src->storage == STORE_MMAP) {		/* use copy-on-write mmap for isolatable copy */		*dst = *src;                 dst->base = (char*) -1;		dst->filename = GDKstrdup(src->filename);		if (dst->filename) {			char path[PATHLENGTH];                        GDKfilepath(path, BATDIR, dst->filename, NULL);			dst->base = GDKmmap(path, MMAP_READ|MMAP_SEQUENTIAL|MMAP_COPY, 0, dst->maxsize);		   	if (dst->base != (char*) -1) {				dst->copied = 1;				dst->storage = STORE_PRIV;				return 0;			}			GDKfree(dst->filename);			dst->filename = NULL;		}	}	*remap = 0;	return HEAPcopy(dst, src);}static void heapfree(Heap* src, Heap *dst) {	if (dst->filename == NULL) {		dst->filename = src->filename;		src->filename = NULL;	}	HEAPfree(src);	*src = *dst;}static int wrongtype(int t1, int t2) {	/* check if types are compatible. be extremely forgiving */	if (t1) {		t1 = ATOMtype(ATOMstorage(t1));		t2 = ATOMtype(ATOMstorage(t2));		if (t1 != t2) {			if (ATOMvarsized(t1) ||			    ATOMvarsized(t2) ||			    ATOMsize(t1) != ATOMsize(t2) ||			    ATOMalign(t1) != ATOMalign(t2) ||			    BATatoms[t1].atomFix ||  			    BATatoms[t2].atomFix) return TRUE;		}	}	return FALSE;}@-There are four main implementation cases: (1) we are allowed to return a view (zero effort),(2) the result is void,void (zero effort),(3) we can copy the heaps (memcopy, or even VM page sharing)(4) we must insert BUN-by-BUN into the result (fallback) The latter case is still optimized for the case that the result is bat[void,T] for a simple fixed-size type T. In that case we do inline array[T] inserts.@cBAT *BATcopy(BAT *b, int ht, int tt, int writeable){	ssize_t bunstocopy = -1;	size_t cnt;	BAT *bn = NULL;	BATcheck(b, "BATcopy");	cnt = BATcount(b);	/* maybe a bit ugly to change the requested bat types?? */	if (b->htype == TYPE_void && !writeable) ht = TYPE_void;	if (b->ttype == TYPE_void && !writeable) tt = TYPE_void;	if (ht != b->htype && wrongtype(ht, b->htype)) {		GDKerror("BATcopy: wrong head-type requested\n");		return NULL;	}	if (tt != b->ttype && wrongtype(tt, b->ttype)) {		GDKerror("BATcopy: wrong tail-type requested\n");		return NULL;	}	/* first try case (1); create a view, possibly with different atom-types */	if (BATrestricted(b) == BAT_READ && !writeable) {		bn = VIEWcreate(b); 		if (bn == NULL) return NULL;		if (ht != bn->htype) {			BAT *bm = BATmirror(bn);			bn->htype = bm->ttype = ht;			bn->hvarsized = bm->tvarsized = ATOMvarsized(ht);                	bn->hseqbase = bm->tseqbase = b->hseqbase;		}		if (tt != bn->ttype) {			BAT *bm = BATmirror(bn);			bn->ttype = bm->htype = tt;			bn->tvarsized = bm->hvarsized = ATOMvarsized(tt);                	bn->tseqbase = bm->hseqbase = b->tseqbase;		}	} else { 		/* check whether we need case (4); BUN-by-BUN copy (by setting bunstocopy >=0) */		if (ATOMsize(ht) != ATOMsize(b->htype) ||		    ATOMsize(tt) != ATOMsize(b->ttype)) /* oops, void materialization */		{			bunstocopy = cnt;		} else if (BATatoms[ht].atomFix || BATatoms[tt].atomFix) { /* oops, we need to fix/unfix atoms */			bunstocopy = cnt;		} else if (VIEWparent(b)) {			/* extra checks needed for views */			BAT *p = BBP_cache(VIEWparent(b));			if (b->hloc == b->tloc || /* oops, mirror view! */			    ATOMsize(ht) != ATOMsize(p->htype) ||			    ATOMsize(tt) != ATOMsize(p->ttype) || /* oops, parent BUN layout was different */		            (ht == TYPE_void) != (p->htype == TYPE_void) ||		            (tt == TYPE_void) != (b->ttype == TYPE_void) || /* oops, BUN layout changes */			    BATcount(p) > cnt+cnt) /* reduced slice view: do not copy too much garbage */ 			{				bunstocopy = cnt;			}		}		bn = BATnew(ht, tt, MAX(1,bunstocopy));		if (bn == NULL) return NULL;		if (ht == TYPE_void && tt == TYPE_void) {			/* case (2): a void,void result => nothing to copy! */			bn->batBuns->free = cnt*BUNsize(bn);		} else if (bunstocopy < 0) {			/* case (3): just copy the heaps; if possible with copy-on-write VM support */			int remap = (writeable == 2) && (BATrestricted(b) != BAT_WRITE);			int hremap = remap && (ATOMstorage(ht) == TYPE_str) && !GDK_ELIMDOUBLES(b->hheap);			int tremap = remap && (ATOMstorage(tt) == TYPE_str) && !GDK_ELIMDOUBLES(b->theap);			Heap hp, hhp, thp;			memset(&hp, 0, sizeof(Heap));			memset(&hhp, 0, sizeof(Heap));			memset(&thp, 0, sizeof(Heap));			if ((heapcopy(&hp, b->batBuns, &remap) < 0) || 			    (bn->hheap && heapcopy(&hhp, b->hheap, &hremap) < 0) ||			    (bn->theap && heapcopy(&thp, b->theap, &tremap) < 0))			{				if (hhp.base) HEAPfree(&hhp);				if (hp.base) HEAPfree(&hp);				BBPreclaim(bn);				return NULL;			}			/* succeeded; replace dummy small heaps by the real ones */			DELTAsave(bn);			heapfree(bn->batBuns, &hp);			if (bn->hheap) heapfree(bn->hheap, &hhp);			if (bn->theap) heapfree(bn->theap, &thp); 			DELTAload(bn);			/* hloc/tloc must be as in src BUN heap */			if (bn->hloc != b->hloc || bn->tloc != b->tloc) {				BAT *bm = BATmirror(bn);				bn->hloc = bm->tloc = b->hloc;				bn->tloc = bm->hloc = b->tloc;			}			/* first/inserted must point equally far into the heap as in the source */			bn->batFirst = Bunbase(bn) + (b->batFirst - Bunbase(b));			bn->batInserted = Bunbase(bn) + (b->batInserted - Bunbase(b));			/* if we have copy-on-write heaps, bn is a logical view on b to ensure the heaps stay stable */			if (remap || hremap || tremap) {				bn->batLview = TRUE;				BBPshare(bn->batParentid = ABS(b->batCacheid));			}		} else if (BATatoms[ht].atomFix || BATatoms[tt].atomFix || (ht && tt) || ATOMstorage(MAX(ht,tt)) >= TYPE_str) {			/* case (4): one-by-one BUN insert (really slow) */			BUN p, q, r = BUNfirst(bn);			int xx, yy = BUNsize(bn);			BATloopFast(b, p, q, xx) {				ptr h = BUNhead(b, p);				ptr t = BUNtail(b, p);				bunfastins_nocheck(bn, r, h, t, yy);				r += yy;			}		} else if ((ht && b->htype == TYPE_void) || (tt && b->ttype == TYPE_void)) { 			/* case (4): optimized for unary void materialization */			oid cur = ht?b->hseqbase:b->tseqbase, *dst = (oid*) BUNfirst(bn);			oid inc = (cur != oid_nil);			bn->batBuns->free = bunstocopy*sizeof(oid);			while(bunstocopy--) { *dst++ = cur; cur += inc; }		} else {			/* case (4): optimized for simple array copy */			int tpe = ATOMstorage(ht|tt);			BUN cur = ht?BUNhloc(b, BUNfirst(b)):BUNtloc(b,BUNfirst(b));			int inc = BUNsize(b)/ATOMsize(tpe);			bn->batBuns->free = bunstocopy*ATOMsize(tpe);  			if (tpe == TYPE_chr || tpe == TYPE_bte) {				bte *src = (bte*) cur, *dst = (bte*) BUNfirst(bn);				while(bunstocopy--) { *dst++ = *src; src += inc; }			} else if (tpe == TYPE_sht) {				sht *src = (sht*) cur, *dst = (sht*) BUNfirst(bn);				while(bunstocopy--) { *dst++ = *src; src += inc; }			} else if ((tpe == TYPE_int) || (tpe == TYPE_flt)) {				int *src = (int*) cur, *dst = (int*) BUNfirst(bn);				while(bunstocopy--) { *dst++ = *src; src += inc; }			} else {				lng *src = (lng*) cur, *dst = (lng*) BUNfirst(bn);				while(bunstocopy--) { *dst++ = *src; src += inc; }			}		}		/* copy all properties (size+other) from the source bat */		BATsetcount(bn, cnt);	}	/* set properties (note that types may have changed in the copy) */		if (ATOMtype(ht) == ATOMtype(b->htype)) {		ALIGNsetH(bn, b); 	} else if (ATOMtype(ATOMstorage(ht)) == ATOMtype(ATOMstorage(b->htype))) {		bn->hsorted = b->hsorted; 		bn->hdense = b->hdense; 		if (b->hkey) BATkey(bn, TRUE);	} else {		bn->hsorted = bn->hdense = 0;	}	if (ATOMtype(tt) == ATOMtype(b->ttype)) {		ALIGNsetT(bn, b); 	} else if (ATOMtype(ATOMstorage(tt)) == ATOMtype(ATOMstorage(b->ttype))) {		bn->tsorted = b->tsorted;		bn->tdense = b->tdense;		if (b->tkey) BATkey(BATmirror(bn), TRUE);	} else { 		bn->tsorted = bn->tdense = 0;	}	if (writeable != TRUE) bn->batRestricted = BAT_READ;	return bn;  bunins_failed:	BBPreclaim(bn);	return NULL;}@+ BAT Unit ManipulationBinary units (tuples) are the elements stored in BATs. Wediscuss here BUN insert, replace and delete.Below are help macro's that actually move the BUNsaround and adapt search accelerator structures. @h#define hashins(h,i,v,n) HASHins_any(h,i,v)#define hashdel(h,i,v,n) HASHdel(h,i,v,n)@= bun_move	if (bs == 8) {		*(lng *) @2 = *(lng *) @1;	} else if (bs == 4) {		*(int *) @2 = *(int *) @1;	} else {		str _dst = (str) @2, _src = (str) @1, _end = _src + bs;		while (_src < _end)			*_dst++ = *_src++;	}@= hacc_update{	if (b->hhash) {		hash@1(b->hhash, @4, BUN@2(b, @3), @3 < last); 	}} @= tacc_update{	if (b->thash) {		hash@1(b->thash, (hash_t)@4, BUN@2(b, @3), @3 < last); 	}}@= acc_move{	char *tmp = alloca(bs);	if (b->hhash) {		HASHmove(b->hhash, (hash_t)@3, (hash_t)@4, BUNhead(b, @1), @1 < last); 	}	if (b->thash) {		HASHmove(b->thash, (hash_t)@3, (hash_t)@4, BUNtail(b, @1), @1 < last); 	}	/* move first to tmp); */	@:bun_move(@1,tmp)@	/* move delete to first */	@:bun_move(@2,@1)@	/* move first to deleted */	@:bun_move(tmp,@2)@}@- BUN InsertionInsertion into a BAT is split into two operations @%BUNins@ and@%BUNfastins@.  The former should be used when integrity enforcementand index maintenance is required.  The latter is used to quicklyinsert the BUN into the result without any additional check.For those cases where speed is required, the type decoding canbe circumvented by asking for a BUN using @%BATbunalloc@ and fillit directly. See gdk.mx for the bunfastins(b,h,t) macros.@cBAT *BUNfastins(BAT *b, ptr h, ptr t){	bunfastins(b, h, t);	if (!b->batDirty)		b->batDirty = TRUE;	return b;      bunins_failed:	return NULL;}@- The interface routine should also perform integrity checks.Null values should have been obtained at a higher level.This code assumes that new elements are appended to the BUN list.@c@= void_insertbun	if ((@1) && b->@1type == TYPE_void && b->@1seqbase != oid_nil) {		if (*(oid*) @1 != oid_nil) {			if (BATcount(b) == 0) {				b->@1seqbase = *(oid*) @1;				bm->@2seqbase = *(oid*) @1;			} else if (*(oid*) @1 != (b->@1seqbase + BUNgetpos(b, BUNlast(b)))) {		 		b = BATmaterialize@1(b, (size_t) ((double)BATcount(b)*1.2));				countonly=0;				if (b == NULL)					return b;			}		} else { 		 	b = BATmaterialize@1(b, (size_t) ((double)BATcount(b)*1.2));			countonly=0;			if (b == NULL)				return b;		}	}@cBAT *BUNins(BAT *b, ptr h, ptr t, bit force){	int countonly = (b->htype == TYPE_void && b->ttype == TYPE_void);	BUN p;	BAT *bm;	BATcheck(b, "BUNins");	BATcheck(h, "BUNins: head value is nil\n");	bm = BBP_cache(-b->batCacheid);	@:void_insertbun(h,t)@	@:void_insertbun(t,h)@	if (b->batSet && BUNlocate(b, h, t)) {		return b;	}	if ((b->hkey & BOUND2BTRUE) && (p = BUNfnd(b, h))) {		if (BUNinplace(b, p, h, t, 0) == NULL)			return NULL;	} else if ((b->tkey & BOUND2BTRUE) && (p = BUNfnd(bm, t))) {		if (BUNinplace(bm, p, t, h, 0) == NULL)			return NULL;	} else {		size_t i;		size_t hsize = 0, tsize = 0;		if (b->hhash && b->hheap) hsize = b->hheap->size;		if (b->thash && b->theap) tsize = b->theap->size;		ALIGNins(b, "BUNins", force);		b->batDirty = 1;		p = BUNlast(b);	/* insert at end */		i = BUNindex(b, p);		if (p > b->batFirst) {			unsigned int bunsize = BUNsize(b);

⌨️ 快捷键说明

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