示例#1
0
/* actual implementation */
static char *
UDFBATreverse_(BAT **ret, BAT *src)
{
	BATiter li;
	BAT *bn = NULL;
	BUN p = 0, q = 0;

	/* assert calling sanity */
	assert(ret != NULL);

	/* handle NULL pointer */
	if (src == NULL)
		throw(MAL, "batudf.reverse", RUNTIME_OBJECT_MISSING);

	/* check tail type */
	if (src->ttype != TYPE_str) {
		throw(MAL, "batudf.reverse",
		      "tail-type of input BAT must be TYPE_str");
	}

	/* allocate result BAT */
	bn = BATnew(src->htype, TYPE_str, BATcount(src));
	if (bn == NULL) {
		throw(MAL, "batudf.reverse", MAL_MALLOC_FAIL);
	}
	BATseqbase(bn, src->hseqbase);

	/* create BAT iterator */
	li = bat_iterator(src);

	/* the core of the algorithm, expensive due to malloc/frees */
	BATloop(src, p, q) {
		char *tr = NULL, *err = NULL;

		/* get original head & tail value */
		ptr h = BUNhead(li, p);
		const char *t = (const char *) BUNtail(li, p);

		/* revert tail value */
		err = UDFreverse_(&tr, t);
		if (err != MAL_SUCCEED) {
			/* error -> bail out */
			BBPreleaseref(bn->batCacheid);
			return err;
		}

		/* assert logical sanity */
		assert(tr != NULL);

		/* insert original head and reversed tail in result BAT */
		/* BUNins() takes care of all necessary administration */
		BUNins(bn, h, tr, FALSE);

		/* free memory allocated in UDFreverse_() */
		GDKfree(tr);
	}
示例#2
0
BUN
copy_inserted(BAT *b, BAT *i )
{
	BUN nr = 0;
	BUN r;
       	BATiter ii = bat_iterator(i);

	for (r = i->batInserted; r < BUNlast(i); r++) {
		BUNins(b, BUNhead(ii,r), BUNtail(ii,r), TRUE);
       		nr++;
	}
	return nr;
}
示例#3
0
str
batnil_2_timestamp(bat *res, const bat *bid)
{
	BAT *b, *dst;
	BATiter bi;
	BUN p, q;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(SQL, "batcalc.nil_2_timestamp", "Cannot access descriptor");
	}
	bi = bat_iterator(b);
	dst = BATnew(b->htype, TYPE_timestamp, BATcount(b), TRANSIENT);
	if (dst == NULL) {
		BBPunfix(b->batCacheid);
		throw(SQL, "sql.2_timestamp", MAL_MALLOC_FAIL);
	}
	BATseqbase(dst, b->hseqbase);
	BATloop(b, p, q) {
		timestamp r = *timestamp_nil;
		BUNins(dst, BUNhead(bi, p), &r, FALSE);
	}
示例#4
0
/*
 * The prime routine for the BAT layer is to create a new hash index.
 * Its argument is the element type and the maximum number of BUNs be
 * stored under the hash function.
 */
BAT *
BAThash(BAT *b, BUN masksize)
{
	BAT *o = NULL;
	lng t0,t1;
	(void) t0; 
	(void) t1;

	if (VIEWhparent(b)) {
		bat p = VIEWhparent(b);
		o = b;
		b = BATdescriptor(p);
		if (!ALIGNsynced(o, b) || BUNfirst(o) != BUNfirst(b)) {
			BBPunfix(b->batCacheid);
			b = o;
			o = NULL;
		}
	}
	MT_lock_set(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
	if (b->H->hash == NULL) {
		unsigned int tpe = ATOMstorage(b->htype);
		BUN cnt = BATcount(b);
		BUN mask;
		BUN p = BUNfirst(b), q = BUNlast(b), r;
		Hash *h = NULL;
		Heap *hp = NULL;
		str nme = BBP_physical(b->batCacheid);
		BATiter bi = bat_iterator(b);

		ALGODEBUG fprintf(stderr, "#BAThash: create hash(" BUNFMT ");\n", BATcount(b));
		/* cnt = 0, hopefully there is a proper capacity from
		 * which we can derive enough information */
		if (!cnt)
			cnt = BATcapacity(b);

		if (b->htype == TYPE_void) {
			if (b->hseqbase == oid_nil) {
				MT_lock_unset(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
				ALGODEBUG fprintf(stderr, "#BAThash: cannot create hash-table on void-NIL column.\n");
				return NULL;
			}
			ALGODEBUG fprintf(stderr, "#BAThash: creating hash-table on void column..\n");

			tpe = TYPE_void;
		}
		/* determine hash mask size p = first; then no dynamic
		 * scheme */
		if (masksize > 0) {
			mask = HASHmask(masksize);
		} else if (ATOMsize(ATOMstorage(tpe)) == 1) {
			mask = (1 << 8);
		} else if (ATOMsize(ATOMstorage(tpe)) == 2) {
			mask = (1 << 12);
		} else if (b->hkey) {
			mask = HASHmask(cnt);
		} else {
			/* dynamic hash: we start with
			 * HASHmask(cnt/64); if there are too many
			 * collisions we try HASHmask(cnt/16), then
			 * HASHmask(cnt/4), and finally
			 * HASHmask(cnt).  */
			mask = HASHmask(cnt >> 6);
			p += (cnt >> 2);	/* try out on first 25% of b */
			if (p > q)
				p = q;
		}

		if (mask < 1024)
			mask = 1024;
		t0 = GDKusec();
		do {
			BUN nslots = mask >> 3;	/* 1/8 full is too full */

			r = BUNfirst(b);
			if (hp) {
				HEAPfree(hp);
				GDKfree(hp);
			}
			if (h) {
				ALGODEBUG fprintf(stderr, "#BAThash: retry hash construction\n");
				GDKfree(h);
			}
			/* create the hash structures */
			hp = (Heap *) GDKzalloc(sizeof(Heap));
			if (hp &&
			    (hp->filename = GDKmalloc(strlen(nme) + 12)) != NULL)
				sprintf(hp->filename, "%s.%chash", nme, b->batCacheid > 0 ? 'h' : 't');
			if (hp == NULL ||
			    hp->filename == NULL ||
			    (h = HASHnew(hp, ATOMtype(b->htype), BATcapacity(b), mask)) == NULL) {

				MT_lock_unset(&GDKhashLock(ABS(b->batCacheid)), "BAThash");
				if (hp != NULL) {
					GDKfree(hp->filename);
					GDKfree(hp);
				}
				return NULL;
			}

			switch (tpe) {
			case TYPE_bte:
				starthash(bte);
				break;
			case TYPE_sht:
				starthash(sht);
				break;
			case TYPE_int:
			case TYPE_flt:
				starthash(int);
				break;
			case TYPE_dbl:
			case TYPE_lng:
				starthash(lng);
				break;
			default:
				for (; r < p; r++) {
					ptr v = BUNhead(bi, r);
					BUN c = (BUN) heap_hash_any(b->H->vheap, h, v);

					if ( HASHget(h,c) == HASHnil(h) &&
					    nslots-- == 0)
						break;	/* mask too full */
					HASHputlink(h,r, HASHget(h,c));
					HASHput(h,c, r);
				}
				break;
			}
		} while (r < p && mask < cnt && (mask <<= 2));

		/* finish the hashtable with the current mask */
		p = r;
		switch (tpe) {
		case TYPE_bte:
			finishhash(bte);
			break;
		case TYPE_sht:
			finishhash(sht);
			break;
		case TYPE_int:
		case TYPE_flt:
			finishhash(int);
			break;
		case TYPE_dbl:
		case TYPE_lng:
			finishhash(lng);
			break;
		default:
			for (; p < q; p++) {
				ptr v = BUNhead(bi, p);
				BUN c = (BUN) heap_hash_any(b->H->vheap, h, v);

				HASHputlink(h,p, HASHget(h,c));
				HASHput(h,c,p);
			}
			break;
		}
		b->H->hash = h;
		t1 = GDKusec();
		ALGODEBUG 
				fprintf(stderr, "#BAThash: hash construction "LLFMT" usec\n", t1-t0);
		ALGODEBUG HASHcollisions(b,b->H->hash);
	}
示例#5
0
void
QOTupdateStatistics(str nme, int actions, lng val)
{
	BATiter bi;
	BUN p;
	oid idx;
	int ival=0, *ip= &ival;
	lng lval=0, *lp= &lval;

	QOTstatisticsInit();
	MT_lock_set(&qotlock, "QOT statistics");
	p = BUNfnd(BATmirror(qotStat[QOTnames]),(ptr)nme);
	if (p == BUN_NONE) {
		BUNappend(qotStat[QOTnames], nme, FALSE);
		BUNappend(qotStat[QOTcalls],  &ival, FALSE);
		BUNappend(qotStat[QOTactions], &ival, FALSE);
		BUNappend(qotStat[QOTtimings], &lval, FALSE);
		p = BUNfnd(BATmirror(qotStat[QOTnames]),(ptr)nme);
		if (p == BUN_NONE){
			MT_lock_unset(&qotlock, "QOT statistics");
			return;
		}
	}
	bi = bat_iterator(qotStat[QOTnames]);
	idx = *(oid*) BUNhead(bi,p);

	p = BUNfnd(qotStat[QOTcalls],&idx);
	if (p == BUN_NONE) {
#ifdef _Q_STATISTICS_DEBUG
		mnstr_printf(GDKout,"#Could not access 'calls'\n");
#endif
		MT_lock_unset(&qotlock, "QOT statistics");
		return;
	}
	bi = bat_iterator(qotStat[QOTcalls]);
	ip = (int*) BUNtail(bi,p);
	*ip = *ip+1;
	bi.b->tsorted = bi.b->trevsorted = 0;
	bi.b->tkey = 0;

	p = BUNfnd(qotStat[QOTactions],&idx);
	if (p == BUN_NONE){
#ifdef _Q_STATISTICS_DEBUG
		mnstr_printf(GDKout,"#Could not access 'actions'\n");
#endif
		MT_lock_unset(&qotlock, "QOT statistics");
		return;
	}
	bi = bat_iterator(qotStat[QOTactions]);
	ip = (int*) BUNtail(bi,p);
	*ip = *ip+ actions;
	bi.b->tsorted = bi.b->trevsorted = 0;
	bi.b->tkey = 0;

	p = BUNfnd(qotStat[QOTtimings],&idx);
	if (p == BUN_NONE){
#ifdef _Q_STATISTICS_DEBUG
		mnstr_printf(GDKout, "#Could not access 'timings'\n");
#endif
		MT_lock_unset(&qotlock, "QOT statistics");
		return ;
	}
	bi = bat_iterator(qotStat[QOTtimings]);
	lp = (lng*) BUNtail(bi,p);
	*lp = *lp+ val;
	bi.b->tsorted = bi.b->trevsorted = 0;
	bi.b->tkey = 0;
	MT_lock_unset(&qotlock, "QOT statistics");
}