예제 #1
0
파일: mat.c 프로젝트: Mytherin/MonetDBLite
/*
 * Enable incremental packing. The SQL front-end requires
 * fixed oid sequences.
 */
str
MATpackIncrement(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
{
	bat *ret = getArgReference_bat(stk,p,0);
	int	pieces;
	BAT *b, *bb, *bn;
	size_t newsize;

	(void) cntxt;
	b = BATdescriptor( stk->stk[getArg(p,1)].val.ival);
	if ( b == NULL)
		throw(MAL, "mat.pack", RUNTIME_OBJECT_MISSING);

	if ( getArgType(mb,p,2) == TYPE_int){
		/* first step, estimate with some slack */
		pieces = stk->stk[getArg(p,2)].val.ival;
		bn = BATnew(TYPE_void, b->ttype?b->ttype:TYPE_oid, (BUN)(1.2 * BATcount(b) * pieces), TRANSIENT);
		if (bn == NULL)
			throw(MAL, "mat.pack", MAL_MALLOC_FAIL);
		/* allocate enough space for the vheap, but not for strings,
		 * since BATappend does clever things for strings */
		if ( b->T->vheap && bn->T->vheap && ATOMstorage(b->ttype) != TYPE_str){
			newsize =  b->T->vheap->size * pieces;
			if (HEAPextend(bn->T->vheap, newsize, TRUE) != GDK_SUCCEED)
				throw(MAL, "mat.pack", MAL_MALLOC_FAIL);
		}
		BATseqbase(bn, b->H->seq);
		BATseqbase(BATmirror(bn), b->T->seq);
		BATappend(bn,b,FALSE);
		assert(!bn->H->nil || !bn->H->nonil);
		assert(!bn->T->nil || !bn->T->nonil);
		bn->H->align = (pieces-1);
		BBPkeepref(*ret = bn->batCacheid);
		BBPunfix(b->batCacheid);
	} else {
		/* remaining steps */
		bb = BATdescriptor(stk->stk[getArg(p,2)].val.ival);
		if ( bb ){
			if (BATcount(b) == 0)
				BATseqbase(b, bb->H->seq);
			if (BATcount(b) == 0)
				BATseqbase(BATmirror(b), bb->T->seq);
			BATappend(b,bb,FALSE);
		}
		b->H->align--;
		if(b->H->align == 0)
			BATsetaccess(b, BAT_READ);
		assert(!b->H->nil || !b->H->nonil);
		assert(!b->T->nil || !b->T->nonil);
		BBPkeepref(*ret = b->batCacheid);
		if( bb) 
			BBPunfix(bb->batCacheid);
	}
	return MAL_SUCCEED;
}
예제 #2
0
파일: mat.c 프로젝트: jaiminpan/Monetdb
/*
 * The pack is an ordinary multi BAT insert. Oid synchronistion
 * between pieces should be ensured by the code generators.
 * The pack operation could be quite expensive, because it
 * may create a really large BAT.
 * The slice over a mat helps to avoid constructing intermediates
 * that are subsequently reduced.
 * Contrary to most operations, NIL arguments are skipped and
 * do not produce RUNTIME_OBJECT_MISSING.
 */
static str
MATpackInternal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
{
	int i, *ret = (int*) getArgReference(stk,p,0);
	BAT *b, *bn;
	BUN cap = 0;
	int tt = TYPE_any;
	(void) cntxt;
	(void) mb;

	for (i = 1; i < p->argc; i++) {
		int bid = stk->stk[getArg(p,i)].val.ival;
		b = BBPquickdesc(abs(bid),FALSE);
		if (b && bid < 0)
			b = BATmirror(b);
		if( b ){
			assert(BAThdense(b));
			if (tt == TYPE_any){
				tt = b->ttype;
			}
			if (!tt && tt != b->ttype)
				tt = b->ttype;
			cap += BATcount(b);
		}
	}
	if (tt == TYPE_any){
		*ret = 0;
		return MAL_SUCCEED;
	}

	bn = BATnew(TYPE_void, tt, cap, TRANSIENT);
	if (bn == NULL)
		throw(MAL, "mat.pack", MAL_MALLOC_FAIL);

	for (i = 1; i < p->argc; i++) {
		b = BATdescriptor(stk->stk[getArg(p,i)].val.ival);
		if( b ){
			if (BATcount(bn) == 0)
				BATseqbase(bn, b->H->seq);
			if (BATcount(bn) == 0)
				BATseqbase(BATmirror(bn), b->T->seq);
			BATappend(bn,b,FALSE);
			BBPunfix(b->batCacheid);
		}
	}
	assert(!bn->H->nil || !bn->H->nonil);
	assert(!bn->T->nil || !bn->T->nonil);
	BATsettrivprop(bn);
	BATderiveProps(bn,FALSE);
	BBPkeepref(*ret = bn->batCacheid);
	return MAL_SUCCEED;
}
예제 #3
0
/*
 * @-
 * The operator below is only working for a very limited
 * case. It also re-uses oids, which may become a semantic
 * problem quickly.
 */
str DCdeleteUpperSlice(int *ret, int *bid, int *pos)
{
	BAT *b;
	int *readerT, *writerT;
	BUN size, i;

	(void) ret;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "dc.deleteUpperSlice", "Cannot access input BAT");
	/* check for a failure */
	assert(b != NULL);

	/* remove Hashes etc */
	if (b->H->hash)
		HASHremove(b);
	if (b->T->hash)
		HASHremove(BATmirror(b));

	size = BATcount(b);
	writerT = (int *) Tloc(b, BUNfirst(b));
	readerT = (int *) Tloc(b, BUNfirst(b)) + *pos;

	for (i = *pos; i < size; i++)
		*writerT++ = *readerT++;
	b->batInserted -= *pos;

	BATsetcount(b, (BUN) (writerT - (int *) Tloc(b, BUNfirst(b))));
	BBPunfix(*bid);
	b->batDirty = TRUE;
	return MAL_SUCCEED;
}
예제 #4
0
/*
 * Destroy a view.
 */
void
VIEWdestroy(BAT *b)
{
	assert(isVIEW(b));

	/* remove any leftover private hash structures */
	if (b->H->hash)
		HASHremove(BATmirror(b));
	if (b->T->hash)
		HASHremove(b);
	IMPSdestroy(b);
	VIEWunlink(b);

	if (b->htype && !b->H->heap.parentid) {
		HEAPfree(&b->H->heap, 0);
	} else {
		b->H->heap.base = NULL;
		b->H->heap.filename = NULL;
	}
	if (b->ttype && !b->T->heap.parentid) {
		HEAPfree(&b->T->heap, 0);
	} else {
		b->T->heap.base = NULL;
		b->T->heap.filename = NULL;
	}
	b->H->vheap = NULL;
	b->T->vheap = NULL;
	BATfree(b);
}
예제 #5
0
/*
 * the @#VIEWcombine@ routine effortlessly produces a view with double
 * vision on the head column.
 */
BAT *
VIEWcombine(BAT *b)
{
	BAT *bn = VIEWhcreate(b), *bm;

	if (bn == NULL)
		return NULL;
	bm = BATmirror(bn);
	if (bm == NULL)
		return NULL;
	if (bn->htype != TYPE_void) {
		assert(bn->T->vheap == NULL);
		bn->T = bn->H;
		bm->H = bn->H;
		if (bn->T->heap.parentid)
			BBPshare(bn->T->heap.parentid);
		if (bn->T->vheap) {
			assert(bn->T->vheap->parentid != abs(bn->batCacheid));
			assert(bn->T->vheap->parentid > 0);
			BBPshare(bn->T->vheap->parentid);
		}
		ALIGNsetH(bn, b);
	} else {
		BATseqbase(bm, bn->hseqbase);
	}
	return bn;
}
예제 #6
0
파일: aggr.c 프로젝트: Clay-Birkett/monetdb
static str
AGGRgrouped2(bat *retval, bat *bid, bat *eid, int tp,
			 BAT *(*grpfunc)(BAT *, BAT *, BAT *, BAT *, int, int, int),
			 int skip_nils,
			 const char *malfunc)
{
	BAT *b, *g, *e;

	b = BATdescriptor(*bid);	/* [gid,value] */
	if (b == NULL)
		throw(MAL, "aggr.sum", RUNTIME_OBJECT_MISSING);
	g = BATmirror(BATmark(b, 0)); /* [dense,gid] */
	e = BATmirror(BATmark(BATmirror(b), 0)); /* [dense,value] */
	BBPreleaseref(b->batCacheid);
	b = e;
	e = BATdescriptor(*eid);	/* [gid,any] */
	return AGGRgrouped(retval, b, g, e, tp, grpfunc, skip_nils, malfunc);
}
예제 #7
0
/*
 * @-
 * The operator below is only working for a very limited cases.
 */
str DCreplaceTailBasedOnHead(int *ret, int *res, int *bid)
{
	BAT *b, *r;
	oid *readerH_b;
	int *writerT_r, *readerT_b;
	BUN size_b, size_r, i;

	(void) ret;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "dc.replaceTailBasedOnHead", "Cannot access input BAT");
	/* check for a failure */
	assert(b != NULL);

	if ((r = BATdescriptor(*res)) == NULL)
		throw(MAL, "dc.replaceTailBasedOnHead", "Cannot access result BAT");
	/* check for a failure */
	assert(r != NULL);


	/* remove Hashes etc */
	if (r->H->hash)
		HASHremove(r);
	if (r->T->hash)
		HASHremove(BATmirror(r));

	size_r = BATcount(r);
	size_b = BATcount(b);


	if ((b->htype == TYPE_void) && (size_b == size_r)) {
		writerT_r = (int *) Tloc(r, BUNfirst(r));
		readerT_b = (int *) Tloc(b, BUNfirst(b));
		for (i = 0; i < size_r; i++) {
			*writerT_r = *readerT_b;
			writerT_r++;
			readerT_b++;
		}
	} else if ((b->htype != TYPE_void) && (size_b < size_r)) {
		readerH_b = (oid *) Hloc(b, BUNfirst(b));
		readerT_b = (int *) Tloc(b, BUNfirst(b));
		for (i = 0; i < size_b; i++) {
			writerT_r = (int *) Tloc(r, BUNfirst(r)) + *readerH_b;
			*writerT_r = *readerT_b;
			readerH_b++;
			readerT_b++;
		}
	}

	BBPunfix(*bid);
	BBPunfix(*res);
	r->batDirty = TRUE;
	return MAL_SUCCEED;
}
예제 #8
0
파일: gdk_utils.c 프로젝트: lajus/monetinr
char *
GDKgetenv(const char *name)
{
	BUN b = BUNfnd(BATmirror(GDKkey), (ptr) name);

	if (b != BUN_NONE) {
		BATiter GDKenvi = bat_iterator(GDKval);
		return BUNtail(GDKenvi, b);
	}
	return NULL;
}
예제 #9
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCisSortedReverse(bit *res, const bat *bid)
{
	BAT *b;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "bat.isSorted", RUNTIME_OBJECT_MISSING);
	}
	*res = BATordered_rev(BATmirror(b));
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}
예제 #10
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCsetkey(bat *res, const bat *bid, const bit *param)
{
	BAT *b;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "bat.setKey", RUNTIME_OBJECT_MISSING);
	}
	BATkey(BATmirror(b), *param ? BOUND2BTRUE :FALSE);
	*res = b->batCacheid;
	BBPkeepref(b->batCacheid);
	return MAL_SUCCEED;
}
예제 #11
0
static BAT *
delta_full_bat_( sql_column *c, sql_delta *bat, int temp, BAT *d, BAT *s)
{
	/* return full normalized column bat

		if (s) {
			b := b.semijoin(s);
			i := i.semijoin(s);
			u := u.semijoin(s);
		}
		b := b.kunion(i);
		b := b.kdiff(u);
		b := b.kunion(u);
		b := b.kdiff(reverse(d));
	*/
	BAT *r, *b, *u, *i = temp_descriptor(bat->ibid);
	r = i; 
	if (temp) {
		if (s) {
			r = BATsemijoin(i,s);
			bat_destroy(i);
		}
		return r;
	}
	b = temp_descriptor(bat->bid);
	u = temp_descriptor(bat->ubid);
	if (s) {
		BAT *t;

		t = BATsemijoin(b,s); bat_destroy(b); b = t;
		t = BATsemijoin(i,s); bat_destroy(i); i = t;
		t = BATsemijoin(u,s); bat_destroy(u); u = t;
	}
	assert(b->ttype == i->ttype);
	if (BATcount(i)) {
		r = BATkunion(b,i); bat_destroy(b); b = r;
	}
	bat_destroy(i); 
	if (BATcount(u)) {
		r = BATkdiff(b,u); bat_destroy(b); b = r;
		assert(b->ttype == u->ttype);
		r = BATkunion(b,u); bat_destroy(b); b = r;
	}
	bat_destroy(u); 
	if (d && BATcount(d)) {
		r = BATkdiff(b,BATmirror(d)); bat_destroy(b); b = r;
	}
	if (!bat->cached && !c->base.wtime && !s) 
		bat->cached = temp_descriptor(b->batCacheid);
	return b;
}
예제 #12
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCappend_reverse_val_wrap(bat *r, const bat *bid, const void *u)
{
	BAT *b;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "bat.append", RUNTIME_OBJECT_MISSING);
	if ((b = setaccess(b, BAT_WRITE)) == NULL)
		throw(MAL, "bat.append", OPERATION_FAILED);
	if (b->htype >= TYPE_str && ATOMstorage(b->htype) >= TYPE_str) {
		if (u == 0 || *(str*)u == 0)
			u = (ptr) str_nil;
		else
			u = (ptr) *(str *)u;
	}
	b = BATmirror(b);
	if (BUNappend(b, u, FALSE) != GDK_SUCCEED) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.append", GDK_EXCEPTION);
	}
	b = BATmirror(b);
	BBPkeepref(*r = b->batCacheid);
	return MAL_SUCCEED;
}
예제 #13
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCreverse(bat *ret, const bat *bid)
{
	BAT *b, *bn = NULL;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "bat.reverse", RUNTIME_OBJECT_MISSING);
	}

	bn = BATmirror(b);			/* bn inherits ref from b */
	assert(bn != NULL);
	*ret = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	return MAL_SUCCEED;
}
예제 #14
0
파일: mat.c 프로젝트: jaiminpan/Monetdb
str
MATproject(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	bat *res_id = (bat*) getArgReference(stk,pci,0);
	bat map_id = *(bat*) getArgReference(stk,pci,1);
	BAT *res = NULL, *map;
	/* rest of the args are parts, (excluding result and map) */
	BAT **bats = GDKzalloc(sizeof(BAT*) * pci->argc - 2);
	BUN bcnt = 0; 
	int i, len = pci->argc-2, sorted = 1;

	(void) cntxt; (void) mb; (void) stk; 
	if( bats == NULL)
		throw(SQL, "mat.project",MAL_MALLOC_FAIL);
	map = BATdescriptor(map_id);
	if (!map)
		goto error;
	for (i=2; i<pci->argc; i++) {
		bat id = *(bat*) getArgReference(stk,pci,i);
		bats[i-2] = BATdescriptor(id);
		if (!bats[i-2])
			goto error;
		bcnt += BATcount(bats[i-2]);
		if (!bats[i-2]->T->sorted)
			sorted = 0;
	}
	assert(bcnt == BATcount(map));

	res = MATproject_(map, bats, len );
	if (sorted && res)
		BATordered(BATmirror(res));
error:
	if (map) BBPunfix(map->batCacheid);
	if (bats) {
		for (i=0; i<len && bats[i]; i++)
			BBPunfix(bats[i]->batCacheid);
		GDKfree(bats);
	}
	if (res) {
		BATsettrivprop(res);
		BBPkeepref( *res_id = res->batCacheid);
		return MAL_SUCCEED;
	}
	throw(SQL, "mat.project","Cannot access descriptor");
}
예제 #15
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCgetKey(bit *ret, const bat *bid)
{
	BAT *b;

	if ((b = BATdescriptor(*bid)) == NULL) 
		throw(MAL, "bat.setPersistence", RUNTIME_OBJECT_MISSING);
	if (BATcount(b) <= 1) {
		*ret = TRUE;
	} else {
		if (!b->tkey) {
			BATderiveHeadProps(BATmirror(b), 1);
		}
		*ret = b->tkey ? TRUE : FALSE;
	}
	BBPunfix(b->batCacheid);
	return MAL_SUCCEED;
}
예제 #16
0
파일: bat5.c 프로젝트: sekcheong/monetdb
str
BKCdensebat(bat *ret, const wrd *size)
{
	BAT *bn;
	wrd sz = *size;

	if (sz < 0)
		sz = 0;
	if (sz > (wrd) BUN_MAX)
		sz = (wrd) BUN_MAX;
	bn = BATnew(TYPE_void, TYPE_void, (BUN) sz, TRANSIENT);
	if (bn == NULL)
		throw(MAL, "bat.densebat", GDK_EXCEPTION);
	BATsetcount(bn, (BUN) sz);
	BATseqbase(bn, 0);
	BATseqbase(BATmirror(bn), 0);
	*ret = bn->batCacheid;
	BBPkeepref(*ret);
	return MAL_SUCCEED;
}
예제 #17
0
static oid
column_find_row(sql_trans *tr, sql_column *c, void *value, ...)
{
	va_list va;
	BUN q;
	BAT *b = NULL, *s = NULL, *r = NULL, *d = NULL;
	oid rid = oid_nil;
	sql_column *nc;
	void *nv;
	sql_dbat *bat = c->t->data;

	if (bat->dbid) 
		d = store_funcs.bind_del(tr, c->t, RDONLY);
	va_start(va, value);
	while ((nc = va_arg(va, sql_column *)) != NULL) {
		nv = va_arg(va, void *);

		b = full_column(c, d, s);
		if (s)
			bat_destroy(s);
		s = BATselect(b, value, value);
		bat_destroy(b);
		c = nc;
		value = nv;
	}
	va_end(va);
	b = full_column(c, d, s);
	if (s)
		bat_destroy(s);
	if (d)
		bat_destroy(d);

	r = BATmirror(b);
	q = BUNfnd(r, value);
	if (q != BUN_NONE) {
		BATiter ri = bat_iterator(r);
		rid = *(oid *) BUNtail(ri, q);
	}
	bat_destroy(b);
	return rid;
}
예제 #18
0
/*
 * The @#VIEWhead@ routine effortlessly projects out the tail column.
 */
BAT *
VIEWhead(BAT *b)
{
	BAT *bn = VIEWhcreate(b), *bm;
	BATstore *bs;

	if (bn == NULL)
		return NULL;
	bs = BBP_desc(bn->batCacheid);
	bm = BATmirror(bn);
	if (bm == NULL)
		return NULL;
	bm->H = bn->T = &bs->T;
	bn->T->type = TYPE_void;
	bn->T->varsized = 1;
	bn->T->shift = 0;
	bn->T->width = 0;
	bn->T->heap.parentid = 0;
	bn->T->hash = NULL;
	bn->T->heap.size = bn->T->heap.free = 0;
	bn->T->heap.base = NULL;
	BATseqbase(bm, oid_nil);
	return bn;
}
예제 #19
0
/*
 * Materialize a view into a normal BAT. If it is a slice, we really
 * want to reduce storage of the new BAT.
 */
gdk_return
VIEWreset(BAT *b)
{
	bat hp, tp, hvp, tvp;
	Heap head, tail, hh, th;
	BAT *n = NULL, *v = NULL;

	if (b == NULL)
		return GDK_FAIL;
	hp = VIEWhparent(b);
	tp = VIEWtparent(b);
	hvp = VIEWvhparent(b);
	tvp = VIEWvtparent(b);
	if (hp || tp) {
		BAT *m;
		BATstore *bs;
		BUN cnt;
		str nme;
		size_t nmelen;

		/* alloc heaps */
		memset(&head, 0, sizeof(Heap));
		memset(&tail, 0, sizeof(Heap));
		memset(&hh, 0, sizeof(Heap));
		memset(&th, 0, sizeof(Heap));

		n = BATdescriptor(abs(b->batCacheid)); /* normalized */
		if (n == NULL)
			goto bailout;
		m = BATmirror(n); /* mirror of normalized */
		bs = BBP_desc(n->batCacheid);
		cnt = BATcount(n) + 1;
		nme = BBP_physical(n->batCacheid);
		nmelen = nme ? strlen(nme) : 0;

		assert(n->batCacheid > 0);
		assert(hp || !b->htype);
		assert(tp || !b->ttype);

		head.farmid = BBPselectfarm(n->batRole, n->htype, offheap);
		tail.farmid = BBPselectfarm(n->batRole, n->ttype, offheap);
		if (n->htype) {
			head.filename = (str) GDKmalloc(nmelen + 12);
			if (head.filename == NULL)
				goto bailout;
			snprintf(head.filename, nmelen + 12, "%s.head", nme);
			if (n->htype && HEAPalloc(&head, cnt, Hsize(n)) != GDK_SUCCEED)
				goto bailout;
		}
		if (n->ttype) {
			tail.filename = (str) GDKmalloc(nmelen + 12);
			if (tail.filename == NULL)
				goto bailout;
			snprintf(tail.filename, nmelen + 12, "%s.tail", nme);
			if (n->ttype && HEAPalloc(&tail, cnt, Tsize(n)) != GDK_SUCCEED)
				goto bailout;
		}
		if (n->H->vheap) {
			hh.farmid = BBPselectfarm(n->batRole, n->htype, varheap);
			hh.filename = (str) GDKmalloc(nmelen + 12);
			if (hh.filename == NULL)
				goto bailout;
			snprintf(hh.filename, nmelen + 12, "%s.hheap", nme);
			if (ATOMheap(n->htype, &hh, cnt) != GDK_SUCCEED)
				goto bailout;
		}
		if (n->T->vheap) {
			th.farmid = BBPselectfarm(n->batRole, n->ttype, varheap);
			th.filename = (str) GDKmalloc(nmelen + 12);
			if (th.filename == NULL)
				goto bailout;
			snprintf(th.filename, nmelen + 12, "%s.theap", nme);
			if (ATOMheap(n->ttype, &th, cnt) != GDK_SUCCEED)
				goto bailout;
		}

		v = VIEWcreate(n, n);
		if (v == NULL)
			goto bailout;

		/* cut the link to your parents */
		VIEWunlink(n);
		if (hp) {
			BBPunshare(hp);
			BBPunfix(hp);
		}
		if (tp) {
			BBPunshare(tp);
			BBPunfix(tp);
		}
		if (hvp) {
			BBPunshare(hvp);
			BBPunfix(hvp);
		}
		if (tvp) {
			BBPunshare(tvp);
			BBPunfix(tvp);
		}

		/* make sure everything points there */
		m->S = n->S = &bs->S;
		m->T = n->H = &bs->H;
		m->H = n->T = &bs->T;

		n->H->type = v->H->type;
		n->H->varsized = v->H->varsized;
		n->H->shift = v->H->shift;
		n->H->width = v->H->width;
		n->H->seq = v->H->seq;

		n->T->type = v->T->type;
		n->T->varsized = v->T->varsized;
		n->T->shift = v->T->shift;
		n->T->width = v->T->width;
		n->T->seq = v->T->seq;

		n->H->heap.parentid = n->T->heap.parentid = 0;
		n->batRestricted = BAT_WRITE;

		/* reset BOUND2KEY */
		n->H->key = BAThkey(v);
		n->T->key = BATtkey(v);

		/* copy the heaps */
		n->H->heap = head;
		n->T->heap = tail;

		/* unshare from parents heap */
		if (hh.base) {
			assert(n->H->vheap == NULL);
			n->H->vheap = (Heap *) GDKzalloc(sizeof(Heap));
			if (n->H->vheap == NULL)
				goto bailout;
			*n->H->vheap = hh;
			n->H->vheap->parentid = n->batCacheid;
		}
		if (th.base) {
			assert(n->T->vheap == NULL);
			n->T->vheap = (Heap *) GDKzalloc(sizeof(Heap));
			if (n->T->vheap == NULL)
				goto bailout;
			*n->T->vheap = th;
			n->T->vheap->parentid = n->batCacheid;
		}

		n->batSharecnt = 0;
		n->batCopiedtodisk = 0;
		n->batDirty = 1;

		/* reset BOUND2KEY */
		n->hkey = BAThkey(v);
		n->tkey = BATtkey(v);

		/* make the BAT empty and insert all again */
		DELTAinit(n);
		/* reset capacity */
		n->batCapacity = cnt;

		/* swap n and v in case the original input was reversed, because
		 * BATins demands (v)oid-headed input */
		if (b->batCacheid < 0) {
			n = m;
			m = BATmirror(v);
		} else {
			m = v;
		}
		/* insert all of v in n, and quit */
		BATins(n, m, FALSE);
		BBPreclaim(v);
		BBPunfix(n->batCacheid);
	}
	return GDK_SUCCEED;
      bailout:
	BBPreclaim(v);
	if (n != NULL)
		BBPunfix(n->batCacheid);
	HEAPfree(&head, 0);
	HEAPfree(&tail, 0);
	HEAPfree(&hh, 0);
	HEAPfree(&th, 0);
	return GDK_FAIL;
}
예제 #20
0
/* only materialize the tail */
gdk_return
BATmaterializet(BAT *b)
{
	return BATmaterializeh(BATmirror(b));
}
예제 #21
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");
}
예제 #22
0
BAT *
VIEWcreate_(BAT *h, BAT *t, int slice_view)
{
	BATstore *bs;
	BAT *bn;
	bat hp = 0, tp = 0, vc = 0;

	BATcheck(h, "VIEWcreate_", NULL);
	BATcheck(t, "VIEWcreate_", NULL);

	if (BATcount(h) != BATcount(t))
		slice_view = 1;
	bs = BATcreatedesc(h->htype, t->ttype, FALSE, TRANSIENT);
	if (bs == NULL)
		return NULL;
	bn = &bs->B;

	hp = VIEWhparent(h);
	tp = VIEWtparent(t);
	if ((hp == 0 && h->htype != TYPE_void) || h->H->heap.copied)
		hp = h->batCacheid;
	if ((tp == 0 && t->ttype != TYPE_void) || t->T->heap.copied)
		tp = -t->batCacheid;
	assert(h->htype != TYPE_void || !hp);
	assert(t->ttype != TYPE_void || !tp);
	/* the H and T column descriptors are fully copied. We need
	 * copies because in case of a mark, we are going to override
	 * a column with a void. Take care to zero the accelerator
	 * data, though. */
	*bn->H = *h->H;
	bn->batDeleted = h->batDeleted;
	bn->batFirst = h->batFirst;
	bn->batInserted = h->batInserted;
	bn->batCount = h->batCount;
	bn->batCapacity = h->batCapacity;
	if (bn->batFirst > 0) {
		bn->H->heap.base += h->batFirst * h->H->width;
		bn->batFirst = 0;
	}
	if (h->H == t->T) {
		vc = 1;
		tp = hp;
		bn->T = bn->H;
	} else {
		*bn->T = *t->T;
		if (bn->batCapacity > t->batCapacity)
			bn->batCapacity = t->batCapacity;
		if (t->batFirst > 0)
			bn->T->heap.base += t->batFirst * t->T->width;
		if (bn->batCount < t->batCount) {
			/* we can't be sure anymore there are nils */
			bn->T->nil = 0;
		}
	}

	if (hp)
		BBPshare(hp);
	if (tp)
		BBPshare(tp);
	if (bn->H->vheap) {
		assert(h->H->vheap);
		assert(bn->H->vheap->parentid > 0);
		bn->H->vheap->farmid = h->H->vheap->farmid;
		BBPshare(bn->H->vheap->parentid);
	}
	if (bn->T->vheap) {
		assert(t->T->vheap);
		assert(bn->T->vheap->parentid > 0);
		bn->T->vheap->farmid = t->T->vheap->farmid;
		BBPshare(bn->T->vheap->parentid);
	}

	/* note: H/T->heap's points into bs which was just overwritten
	 * with a copy from the parent(s). Clear the copied flag since
	 * our heap was not copied from our parent(s) even if our
	 * parent's heap was copied from its parent(s). */
	bn->H->heap.copied = bn->T->heap.copied = 0;
	bn->H->props = bn->T->props = NULL;

	/* correct values after copy of head and tail info */
	if (hp)
		bn->H->heap.parentid = hp;
	if (tp)
		bn->T->heap.parentid = tp;
	BATinit_idents(bn);
	/* Some bits must be copied individually. */
	bn->batDirty = BATdirty(h);
	bn->batRestricted = BAT_READ;
	if (slice_view || !hp || isVIEW(h))
		/* slices are unequal to their parents; cannot use accs */
		bn->H->hash = NULL;
	else
		/* equal pointers to parent mean view uses acc of parent */
		bn->H->hash = h->H->hash;
	if (slice_view || !tp || isVIEW(t))
		bn->T->hash = NULL;
	else
		bn->T->hash = t->T->hash;
	/* imprints are shared, but the check is dynamic */
	bn->H->imprints = NULL;
	bn->T->imprints = NULL;
	BBPcacheit(bs, 1);	/* enter in BBP */
	/* View of VIEW combine, ie we need to fix the head of the mirror */
	if (vc) {
		BAT *bm = BATmirror(bn);
		bm->H = bn->H;
	}
	return bn;
}
예제 #23
0
/* BATsample implements sampling for void headed BATs */
BAT *
BATsample(BAT *b, BUN n)
{
	BAT *bn;
	BUN cnt, slen;
	BUN rescnt;
	struct oidtreenode *tree = NULL;

	BATcheck(b, "BATsample", NULL);
	assert(BAThdense(b));
	ERRORcheck(n > BUN_MAX, "BATsample: sample size larger than BUN_MAX\n", NULL);
	ALGODEBUG
		fprintf(stderr, "#BATsample: sample " BUNFMT " elements.\n", n);

	cnt = BATcount(b);
	/* empty sample size */
	if (n == 0) {
		bn = BATnew(TYPE_void, TYPE_void, 0, TRANSIENT);
		if (bn == NULL) {
			GDKerror("BATsample: memory allocation error");
			return NULL;
		}
		BATsetcount(bn, 0);
		BATseqbase(bn, 0);
		BATseqbase(BATmirror(bn), 0);
	/* sample size is larger than the input BAT, return all oids */
	} else if (cnt <= n) {
		bn = BATnew(TYPE_void, TYPE_void, cnt, TRANSIENT);
		if (bn == NULL) {
			GDKerror("BATsample: memory allocation error");
			return NULL;
		}
		BATsetcount(bn, cnt);
		BATseqbase(bn, 0);
		BATseqbase(BATmirror(bn), b->H->seq);
	} else {
		oid minoid = b->hseqbase;
		oid maxoid = b->hseqbase + cnt;
		/* if someone samples more than half of our tree, we
		 * do the antiset */
		bit antiset = n > cnt / 2;
		slen = n;
		if (antiset)
			n = cnt - n;

		tree = GDKmalloc(n * sizeof(struct oidtreenode));
		if (tree == NULL) {
			GDKerror("#BATsample: memory allocation error");
			return NULL;
		}
		bn = BATnew(TYPE_void, TYPE_oid, slen, TRANSIENT);
		if (bn == NULL) {
			GDKfree(tree);
			GDKerror("#BATsample: memory allocation error");
			return NULL;
		}
		/* while we do not have enough sample OIDs yet */
		for (rescnt = 0; rescnt < n; rescnt++) {
			oid candoid;
			do {
				/* generate a new random OID */
				candoid = (oid) (minoid + DRAND * (maxoid - minoid));
				/* if that candidate OID was already
				 * generated, try again */
			} while (!OIDTreeMaybeInsert(tree, candoid, rescnt));
		}
		if (!antiset) {
			OIDTreeToBAT(tree, bn);
		} else {
			OIDTreeToBATAntiset(tree, bn, minoid, maxoid);
		}
		GDKfree(tree);

		BATsetcount(bn, slen);
		bn->trevsorted = bn->batCount <= 1;
		bn->tsorted = 1;
		bn->tkey = 1;
		bn->tdense = bn->batCount <= 1;
		if (bn->batCount == 1)
			bn->tseqbase = *(oid *) Tloc(bn, BUNfirst(bn));
		bn->hdense = 1;
		bn->hseqbase = 0;
		bn->hkey = 1;
		bn->hrevsorted = bn->batCount <= 1;
		bn->hsorted = 1;
	}
	return bn;
}
예제 #24
0
파일: aggr.c 프로젝트: Clay-Birkett/monetdb
/*
 * grouped aggregates
 */
static str
AGGRgrouped(bat *retval, BAT *b, BAT *g, BAT *e, int tp,
			BAT *(*grpfunc)(BAT *, BAT *, BAT *, BAT *, int, int, int),
			int skip_nils,
			const char *malfunc)
{
	BAT *bn, *t, *map;

	if (b == NULL || g == NULL || e == NULL) {
		if (b)
			BBPreleaseref(b->batCacheid);
		if (g)
			BBPreleaseref(g->batCacheid);
		if (e)
			BBPreleaseref(e->batCacheid);
		throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
	}
	if (tp == TYPE_any && grpfunc == BATgroupmedian)
		tp = b->ttype;
	if (!BAThdense(b) || !BAThdense(g)) {
		/* if b or g don't have a dense head, replace the head with a
		 * dense sequence */
		t = BATjoin(BATmirror(b), g, MIN(BATcount(b), BATcount(g)));
		BBPreleaseref(b->batCacheid);
		BBPreleaseref(g->batCacheid);
		b = BATmirror(BATmark(t, 0));
		g = BATmirror(BATmark(BATmirror(t), 0));
		BBPreleaseref(t->batCacheid);
	}
	if (b->hseqbase != g->hseqbase || BATcount(b) != BATcount(g)) {
		/* b and g are not aligned: align them by creating a view on
		 * one or the other */
		oid min;				/* lowest common oid */
		oid max;				/* highest common oid */
		min = b->hseqbase;
		if (min < g->hseqbase)
			min = g->hseqbase;
		max = b->hseqbase + BATcount(b);
		if (g->hseqbase + BATcount(g) < max)
			max = g->hseqbase + BATcount(g);
		if (b->hseqbase != min || b->hseqbase + BATcount(b) != max) {
			if (min >= max)
				min = max = b->hseqbase;
			t = BATslice(b, BUNfirst(b) + (BUN) (min - b->hseqbase),
						 BUNfirst(b) + (BUN) (max - b->hseqbase));
			BBPreleaseref(b->batCacheid);
			b = t;
		}
		if (g->hseqbase != min || g->hseqbase + BATcount(g) != max) {
			if (min >= max)
				min = max = g->hseqbase;
			t = BATslice(g, BUNfirst(g) + (BUN) (min - g->hseqbase),
						 BUNfirst(g) + (BUN) (max - g->hseqbase));
			BBPreleaseref(g->batCacheid);
			g = t;
		}
	}
	if (!BAThdense(e)) {
		/* if e doesn't have a dense head, renumber the group ids with
		 * a dense sequence at the cost of some left joins */
		map = BATmark(e, 0);	/* [gid,newgid(dense)] */
		BBPreleaseref(e->batCacheid);
		e = BATmirror(map);		/* [newgid(dense),gid] */
		t = BATleftjoin(g, map, BATcount(g)); /* [oid,newgid] */
		BBPreleaseref(g->batCacheid);
		g = t;
	} else {
		map = NULL;
	}
	bn = (*grpfunc)(b, g, e, NULL, tp, skip_nils, 1);
	if (bn != NULL && (grpfunc == BATgroupmin || grpfunc == BATgroupmax)) {
		BAT *bnn = BATouterjoin(bn, b, BATcount(bn));
		BBPreleaseref(bn->batCacheid);
		bn = bnn;
	}
	BBPreleaseref(b->batCacheid);
	BBPreleaseref(g->batCacheid);
	if (map == NULL)			/* if map!=NULL, e is mirror of map */
		BBPreleaseref(e->batCacheid);
	if (bn == NULL) {
		char *errbuf = GDKerrbuf;
		char *s;

		if (map)
			BBPreleaseref(map->batCacheid);

		if (errbuf && *errbuf) {
			if (strncmp(errbuf, "!ERROR: ", 8) == 0)
				errbuf += 8;
			if (strchr(errbuf, '!') == errbuf + 5) {
				s = createException(MAL, malfunc, "%s", errbuf);
			} else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
				s = createException(MAL, malfunc, "%s", s + 2);
			} else {
				s = createException(MAL, malfunc, "%s", errbuf);
			}
			*GDKerrbuf = 0;
			return s;
		}
		throw(MAL, malfunc, OPERATION_FAILED);
	}
	if (map) {
		t = BATleftjoin(map, bn, BATcount(bn));
		BBPreleaseref(map->batCacheid);
		BBPreleaseref(bn->batCacheid);
		bn = t;
	}
	*retval = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	return MAL_SUCCEED;
}
예제 #25
0
파일: aggr.c 프로젝트: Clay-Birkett/monetdb
static str
AGGRsubgrouped(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid,
			   int skip_nils, int abort_on_error, int tp,
			   BAT *(*grpfunc)(BAT *, BAT *, BAT *, BAT *, int, int, int),
			   const char *malfunc)
{
	BAT *b, *g, *e, *s, *bn;

	b = BATdescriptor(*bid);
	g = gid ? BATdescriptor(*gid) : NULL;
	e = eid ? BATdescriptor(*eid) : NULL;
	if (b == NULL || (gid != NULL && g == NULL) || (eid != NULL && e == NULL)) {
		if (b)
			BBPreleaseref(b->batCacheid);
		if (g)
			BBPreleaseref(g->batCacheid);
		if (e)
			BBPreleaseref(e->batCacheid);
		throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
	}
	if (tp == TYPE_any && grpfunc == BATgroupmedian)
		tp = b->ttype;

	if (sid) {
		s = BATdescriptor(*sid);
		if (s == NULL) {
			BBPreleaseref(b->batCacheid);
			if (g)
				BBPreleaseref(g->batCacheid);
			if (e)
				BBPreleaseref(e->batCacheid);
			throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
		}
	} else {
		if (!BAThdense(b)) {
			/* XXX backward compatibility code: ignore non-dense head, but
			 * only if no candidate list */
			s = BATmirror(BATmark(BATmirror(b), 0));
			BBPreleaseref(b->batCacheid);
			b = s;
		}
		s = NULL;
	}
	bn = (*grpfunc)(b, g, e, s, tp, skip_nils, abort_on_error);
	BBPreleaseref(b->batCacheid);
	if (g)
		BBPreleaseref(g->batCacheid);
	if (e)
		BBPreleaseref(e->batCacheid);
	if (s)
		BBPreleaseref(s->batCacheid);
	if (bn == NULL) {
		char *errbuf = GDKerrbuf;
		char *s;

		if (errbuf && *errbuf) {
			if (strncmp(errbuf, "!ERROR: ", 8) == 0)
				errbuf += 8;
			if (strchr(errbuf, '!') == errbuf + 5) {
				s = createException(MAL, malfunc, "%s", errbuf);
			} else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
				s = createException(MAL, malfunc, "%s", s + 2);
			} else {
				s = createException(MAL, malfunc, "%s", errbuf);
			}
			*GDKerrbuf = 0;
			return s;
		}
		throw(MAL, malfunc, OPERATION_FAILED);
	}
	*retval = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	return MAL_SUCCEED;
}
예제 #26
0
파일: netcdf.c 프로젝트: sekcheong/monetdb
/* Load variable varid from data set ncid into the bat v. Generate dimension
 * bats dim using NCDFARRAYseries */
static str
NCDFloadVar(bat **dim, bat *v, int ncid, int varid, nc_type vtype, int vndims, int *vdims)
{

	BAT *res;
	bat vbid, *dim_bids;
	int retval, i, j;
	char *sermsg = NULL;
	size_t sz = 1;
	size_t *dlen = NULL, *val_rep = NULL, *grp_rep = NULL;

	if ( dim == NULL )
		return createException(MAL, "netcdf.importvar", "array of dimension bat is NULL");
	dim_bids = *dim;

	dlen = (size_t *)GDKzalloc(sizeof(size_t) * vndims);

	for (i = 0; i < vndims; i++){
		if ((retval = nc_inq_dimlen(ncid, vdims[i], &dlen[i])))
			return createException(MAL, "netcdf.importvar",
								   "Cannot read dimension %d : %s",
								   vdims[i], nc_strerror(retval));
		sz *= dlen[i];
	}

	switch (vtype) {
	case NC_INT:
	{
		LOAD_NCDF_VAR(int,int);
		break;
	}
	case NC_FLOAT:
	case NC_DOUBLE:
	{
		LOAD_NCDF_VAR(dbl,double);
		break;
	}

	default:
	  return createException(MAL, "netcdf.importvar",
			   "Type %s not supported yet",
			   prim_type_name(vtype));

	}

	BATsetcount(res, sz);
	res->T->nonil = TRUE;
	res->T->nil = FALSE;
	res->tsorted = FALSE;
	res->trevsorted = FALSE;
	BATkey(BATmirror(res), FALSE);
	BBPkeepref(vbid = res->batCacheid);

	res = NULL;

	/* Manually create dimensions with range [0:1:dlen[i]] */
	val_rep = (size_t *)GDKmalloc(sizeof(size_t) * vndims);
	grp_rep = (size_t *)GDKmalloc(sizeof(size_t) * vndims);

    	/* compute the repetition factor inside of the series (val_rep) and of series (grp_rep) */
	for (i = 0; i < vndims; i++) {
		val_rep[i] = grp_rep[i] = 1;
		for (j = 0; j < i; j++)
			grp_rep[i] *= dlen[j];
        for (j = i + 1; j < vndims; j++)
            val_rep[i] *= dlen[j];
	}

	for (i = 0; i < vndims; i++) {
		sermsg = NCDFARRAYseries(&dim_bids[i], 0, 1, dlen[i], val_rep[i], grp_rep[i]);

		if (sermsg != MAL_SUCCEED) {
			BBPdecref(vbid, 1); /* undo the BBPkeepref(vbid) above */
			for ( j = 0; j < i; j++) /* undo log. ref of previous dimensions */
				BBPdecref(dim_bids[j], 1);
			GDKfree(dlen);
			GDKfree(val_rep);
			GDKfree(grp_rep);
			return createException(MAL, "netcdf.loadvar", "Failed to create a dimension of variable %d", varid);
		}
	}
	/* to do : is descriptor check of dim_bids is needed? */

	GDKfree(dlen);
	GDKfree(val_rep);
	GDKfree(grp_rep);

	*v = vbid;

	return MAL_SUCCEED;
}
예제 #27
0
파일: aggr.c 프로젝트: jaiminpan/Monetdb
static str
AGGRsubgroupedExt(bat *retval1, bat *retval2, bat *bid, bat *gid, bat *eid, bat *sid,
			   int skip_nils, int abort_on_error, int tp,
			   BAT *(*grpfunc1)(BAT *, BAT *, BAT *, BAT *, int, int, int),
			   gdk_return (*grpfunc2)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *, int, int, int),
			   BAT *(*quantilefunc)(BAT *, BAT *, BAT *, BAT *, int, double, int, int),
			   bat *quantile,
			   const char *malfunc)
{
	BAT *b, *g, *e, *s, *bn = NULL, *cnts, *q = NULL;
	double qvalue;

   /* one of grpfunc1, grpfunc2 and quantilefunc is non-NULL and the others are */
	assert((grpfunc1 && grpfunc2 == NULL && quantilefunc == NULL) ||
			(grpfunc1 == NULL && grpfunc2 && quantilefunc == NULL) ||
			(grpfunc1 == NULL && grpfunc2 == NULL && quantilefunc) );

	/* if retval2 is non-NULL, we must have grpfunc2 */
	assert(retval2 == NULL || grpfunc2 != NULL);

	b = BATdescriptor(*bid);
	g = gid ? BATdescriptor(*gid) : NULL;
	e = eid ? BATdescriptor(*eid) : NULL;
	q = quantile ? BATdescriptor(*quantile) : NULL;

	if (b == NULL || (gid != NULL && g == NULL) || (eid != NULL && e == NULL)) {
		if (b)
			BBPreleaseref(b->batCacheid);
		if (g)
			BBPreleaseref(g->batCacheid);
		if (e)
			BBPreleaseref(e->batCacheid);
		throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
	}
	if (tp == TYPE_any && (grpfunc1 == BATgroupmedian || quantilefunc == BATgroupquantile))
		tp = b->ttype;

	if (sid) {
		s = BATdescriptor(*sid);
		if (s == NULL) {
			BBPreleaseref(b->batCacheid);
			if (g)
				BBPreleaseref(g->batCacheid);
			if (e)
				BBPreleaseref(e->batCacheid);
			throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
		}
	} else {
		if (!BAThdense(b)) {
			/* XXX backward compatibility code: ignore non-dense head, but
			 * only if no candidate list */
			s = BATmirror(BATmark(BATmirror(b), 0));
			BBPreleaseref(b->batCacheid);
			b = s;
		}
		s = NULL;
	}
	if (grpfunc1)
		bn = (*grpfunc1)(b, g, e, s, tp, skip_nils, abort_on_error);
	if (quantilefunc) {
		assert(BATcount(q)>0);
		assert(q->ttype == TYPE_dbl);
		qvalue = ((const double *)Tloc(q, BUNfirst(q)))[0];
		if (qvalue <  0|| qvalue > 1) {
			char *s;
			s = createException(MAL, malfunc, "quantile value of %f is not in range [0,1]", qvalue);
			return s;
		}
		bn = (*quantilefunc)(b, g, e, s, tp, qvalue, skip_nils, abort_on_error);
	}
	if (grpfunc2 && (*grpfunc2)(&bn, retval2 ? &cnts : NULL, b, g, e, s, tp, skip_nils, abort_on_error) == GDK_FAIL)
		bn = NULL;

	BBPreleaseref(b->batCacheid);
	if (g)
		BBPreleaseref(g->batCacheid);
	if (e)
		BBPreleaseref(e->batCacheid);
	if (s)
		BBPreleaseref(s->batCacheid);
	if (bn == NULL) {
		char *errbuf = GDKerrbuf;
		char *s;

		if (errbuf && *errbuf) {
			if (strncmp(errbuf, "!ERROR: ", 8) == 0)
				errbuf += 8;
			if (strchr(errbuf, '!') == errbuf + 5) {
				s = createException(MAL, malfunc, "%s", errbuf);
			} else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
				s = createException(MAL, malfunc, "%s", s + 2);
			} else {
				s = createException(MAL, malfunc, "%s", errbuf);
			}
			*GDKerrbuf = 0;
			return s;
		}
		throw(MAL, malfunc, OPERATION_FAILED);
	}
	*retval1 = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	if (retval2) {
		*retval2 = cnts->batCacheid;
		BBPkeepref(cnts->batCacheid);
	}
	return MAL_SUCCEED;
}
예제 #28
0
파일: aggr.c 프로젝트: jaiminpan/Monetdb
/*
 * grouped aggregates
 */
static str
AGGRgrouped(bat *retval1, bat *retval2, BAT *b, BAT *g, BAT *e, int tp,
			BAT *(*grpfunc1)(BAT *, BAT *, BAT *, BAT *, int, int, int),
			gdk_return (*grpfunc2)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *, int, int, int),
			BAT *(*quantilefunc)(BAT *, BAT *, BAT *, BAT *, int, double, int, int),
			BAT *quantile,
			int skip_nils,
			const char *malfunc)
{
	BAT *bn, *cnts = NULL, *t, *map;
	double qvalue;

   /* one of grpfunc1, grpfunc2 and quantilefunc is non-NULL and the others are */
	assert((grpfunc1 != NULL && grpfunc2 == NULL && quantilefunc == NULL) ||
			(grpfunc1 == NULL && grpfunc2 != NULL && quantilefunc == NULL) ||
			(grpfunc1 == NULL && grpfunc2 == NULL && quantilefunc != NULL) );
	/* if retval2 is non-NULL, we must have grpfunc2 */
	assert(retval2 == NULL || grpfunc2 != NULL);
	assert(quantile == NULL || quantilefunc != NULL);

	if (b == NULL || g == NULL || e == NULL) {
		if (b)
			BBPreleaseref(b->batCacheid);
		if (g)
			BBPreleaseref(g->batCacheid);
		if (e)
			BBPreleaseref(e->batCacheid);
		throw(MAL, malfunc, RUNTIME_OBJECT_MISSING);
	}
	if (tp == TYPE_any && (grpfunc1 == BATgroupmedian || quantilefunc == BATgroupquantile))
		tp = b->ttype;
	if (!BAThdense(b) || !BAThdense(g)) {
		/* if b or g don't have a dense head, replace the head with a
		 * dense sequence */
		t = BATjoin(BATmirror(b), g, MIN(BATcount(b), BATcount(g)));
		BBPreleaseref(b->batCacheid);
		BBPreleaseref(g->batCacheid);
		b = BATmirror(BATmark(t, 0));
		g = BATmirror(BATmark(BATmirror(t), 0));
		BBPreleaseref(t->batCacheid);
	}
	if (b->hseqbase != g->hseqbase || BATcount(b) != BATcount(g)) {
		/* b and g are not aligned: align them by creating a view on
		 * one or the other */
		oid min;				/* lowest common oid */
		oid max;				/* highest common oid */
		min = b->hseqbase;
		if (min < g->hseqbase)
			min = g->hseqbase;
		max = b->hseqbase + BATcount(b);
		if (g->hseqbase + BATcount(g) < max)
			max = g->hseqbase + BATcount(g);
		if (b->hseqbase != min || b->hseqbase + BATcount(b) != max) {
			if (min >= max)
				min = max = b->hseqbase;
			t = BATslice(b, BUNfirst(b) + (BUN) (min - b->hseqbase),
						 BUNfirst(b) + (BUN) (max - b->hseqbase));
			BBPreleaseref(b->batCacheid);
			b = t;
		}
		if (g->hseqbase != min || g->hseqbase + BATcount(g) != max) {
			if (min >= max)
				min = max = g->hseqbase;
			t = BATslice(g, BUNfirst(g) + (BUN) (min - g->hseqbase),
						 BUNfirst(g) + (BUN) (max - g->hseqbase));
			BBPreleaseref(g->batCacheid);
			g = t;
		}
	}
	if (!BAThdense(e)) {
		/* if e doesn't have a dense head, renumber the group ids with
		 * a dense sequence at the cost of some left joins */
		map = BATmark(e, 0);	/* [gid,newgid(dense)] */
		BBPreleaseref(e->batCacheid);
		e = BATmirror(map);		/* [newgid(dense),gid] */
		t = BATleftjoin(g, map, BATcount(g)); /* [oid,newgid] */
		BBPreleaseref(g->batCacheid);
		g = t;
	} else {
		map = NULL;
	}
	if (grpfunc1)
		bn = (*grpfunc1)(b, g, e, NULL, tp, skip_nils, 1);
	if (quantilefunc) {
		assert(BATcount(quantile)>0);
		assert(quantile->ttype == TYPE_dbl);
		qvalue = ((const double *)Tloc(quantile, BUNfirst(quantile)))[0];
		if (qvalue <  0|| qvalue > 1) {
			char *s;
			s = createException(MAL, malfunc, "quantile value of %f is not in range [0,1]", qvalue);
			return s;
		}
		bn = (*quantilefunc)(b, g, e, NULL, tp, qvalue, skip_nils, 1);
	}
	if (grpfunc2 && (*grpfunc2)(&bn, retval2 ? &cnts : NULL, b, g, e, NULL, tp, skip_nils, 1) == GDK_FAIL)
		bn = NULL;
	if (bn != NULL && (grpfunc1 == BATgroupmin || grpfunc1 == BATgroupmax)) {
		t = BATproject(bn, b);
		BBPreleaseref(bn->batCacheid);
		bn = t;
	}
	BBPreleaseref(b->batCacheid);
	BBPreleaseref(g->batCacheid);
	if (map == NULL)			/* if map!=NULL, e is mirror of map */
		BBPreleaseref(e->batCacheid);
	if (bn == NULL) {
		char *errbuf = GDKerrbuf;
		char *s;

		if (map)
			BBPreleaseref(map->batCacheid);

		if (errbuf && *errbuf) {
			if (strncmp(errbuf, "!ERROR: ", 8) == 0)
				errbuf += 8;
			if (strchr(errbuf, '!') == errbuf + 5) {
				s = createException(MAL, malfunc, "%s", errbuf);
			} else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
				s = createException(MAL, malfunc, "%s", s + 2);
			} else {
				s = createException(MAL, malfunc, "%s", errbuf);
			}
			*GDKerrbuf = 0;
			return s;
		}
		throw(MAL, malfunc, OPERATION_FAILED);
	}
	if (map) {
		t = BATleftjoin(map, bn, BATcount(bn));
		BBPreleaseref(bn->batCacheid);
		bn = t;
		if (cnts) {
			t = BATleftjoin(map, cnts, BATcount(cnts));
			BBPreleaseref(cnts->batCacheid);
			cnts = t;
		}
		BBPreleaseref(map->batCacheid);
	}
	*retval1 = bn->batCacheid;
	BBPkeepref(bn->batCacheid);
	if (retval2) {
		*retval2 = cnts->batCacheid;
		BBPkeepref(cnts->batCacheid);
	}
	return MAL_SUCCEED;
}
예제 #29
0
파일: mat.c 프로젝트: jaiminpan/Monetdb
static str
MATpackSliceInternal(MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
{
	int i, i1 = p->argc, i2 = -1, *ret = (int*) getArgReference(stk,p,0);
	BAT *b, *bn;
	BUN cap = 0, fst, lst, cnt, c;
	int ht = TYPE_any, tt = TYPE_any;

	assert(p->argc > 3);
	switch getArgType(mb,p,1) {
	case TYPE_wrd:
		fst = (BUN) *(wrd*) getArgReference(stk,p,1);
		break;
	case TYPE_lng:
		fst = (BUN) *(lng*) getArgReference(stk,p,1);
		break;
	case TYPE_int:
		fst = (BUN) *(int*) getArgReference(stk,p,1);
		break;
	default:
		throw(MAL, "mat.packSlice", "wrong type for lower bound");
	}
	switch getArgType(mb,p,2) {
	case TYPE_wrd: {
		wrd l = *(wrd*) getArgReference(stk,p,2);
		if (l == wrd_nil)
			lst = BUN_MAX; /* no upper bound */
		else
			lst = (BUN) l;
		break;
	}
	case TYPE_lng: {
		lng l = *(lng*) getArgReference(stk,p,2);
		if (l == lng_nil)
			lst = BUN_MAX; /* no upper bound */
		else
			lst = (BUN) l;
		break;
	}
	case TYPE_int: {
		int l = *(int*) getArgReference(stk,p,2);
		if (l == int_nil)
			lst = BUN_MAX; /* no upper bound */
		else
			lst = (BUN) l;
		break;
	}
	default:
		throw(MAL, "mat.packSlice", "wrong type for upper bound");
	}
	if (lst < BUN_MAX)
		lst++; /* inclusive -> exclusive upper bound */
	if (lst < fst)
		lst = fst;
	cnt = lst - fst;

	for (i = 3; i < p->argc && cap < lst; i++) {
		int bid = stk->stk[getArg(p,i)].val.ival;
		b = BBPquickdesc(abs(bid),FALSE);
		if (b && bid < 0)
			b = BATmirror(b);
		if (b == NULL)
			throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING);
		if (ht == TYPE_any){
			ht = b->htype;
			tt = b->ttype;
		}
		c = BATcount(b);
		if (cap <= fst) {
			/* The optimal case is when the requested slice falls completely in one BAT.
			 * In that case, we can simply return a slice (view) of that BAT.
			 * (A pitty that we have calculated the other slices as well.)
			 */
			if (lst <= cap + c) {
				b = BATdescriptor(bid);
				if( b){
					bn = BATslice(b, fst - cap, lst - cap);
					BBPunfix(b->batCacheid);
					BBPkeepref(*ret = bn->batCacheid);
				} else
					throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING);

				return MAL_SUCCEED;
			}
			if (fst < cap + c) {
				/* fst falls in BAT i1 == i */
				i1 = i;
				fst -= cap;
				lst -= cap;
				cap = 0;
			}
		}
		cap += c;
	}
	/* lst falls in BAT i2 == i-1 */
	i2 = i - 1;
	if (cap <= fst) /* i.e., (i1 > i2) */
		cap = 0;
	else
		cap -= fst;
	cnt = MIN(cnt, cap);

	assert(ht== TYPE_void);
	bn = BATnew(TYPE_void, tt, cnt, TRANSIENT);
	if (bn == NULL)
		throw(MAL, "mat.packSlice", MAL_MALLOC_FAIL);
	/* must set seqbase or else BATins will not materialize column */
	BATseqbase(bn, 0);
	if (tt == TYPE_void)
		BATseqbase(BATmirror(bn), 0);

	for (i = i1; i <= i2; i++) {
		b = BATdescriptor(stk->stk[getArg(p,i)].val.ival);
		if (b == NULL){
			BBPreleaseref(bn->batCacheid);
			throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING);
		}
		c = BATcount(b);
		/* use the right oid ranges, don't change the input */
		if (i == i1 && fst > 0) {
			BAT *bb = b;
			b = BATslice(bb, fst, c);
			BBPunfix(bb->batCacheid);
		} else
		if (i == i2 && lst < c) {
			BAT *bb = b;
			b = BATslice(bb, 0, lst);
			BBPunfix(bb->batCacheid);
		}
		BATins(bn,b,FALSE);
		lst -= c;
		BBPunfix(b->batCacheid);
	}
	BBPkeepref(*ret = bn->batCacheid);
	return MAL_SUCCEED;
}
예제 #30
0
파일: mat.c 프로젝트: jaiminpan/Monetdb
// merging multiple OID lists, optimized for empty bats
// Further improvement should come from multi-bat merging.
str
MATmergepack(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
{
	int i,j= 0, *ret = (int*) getArgReference(stk,p,0);
	int top=0;
	oid  **o_end, **o_src, *o, *oo, onxt;
	BAT *b, *bn, *bm, **bats;
	BUN cap = 0;

	(void)cntxt;
	(void)mb;
	bats = (BAT**) GDKzalloc(sizeof(BAT*) * p->argc);
	o_end = (oid**) GDKzalloc(sizeof(oid*) * p->argc);
	o_src = (oid**) GDKzalloc(sizeof(oid*) * p->argc);

	if ( bats ==0 || o_end == 0 || o_src == 0){
		if (bats) GDKfree(bats);
		if (o_src) GDKfree(o_src);
		if (o_end) GDKfree(o_end);
		throw(MAL,"mat.mergepack",MAL_MALLOC_FAIL);
	}
	for (i = 1; i < p->argc; i++) {
		int bid = stk->stk[getArg(p,i)].val.ival;
		b = BATdescriptor(abs(bid));
		if (b ){
			cap += BATcount(b);
			if ( BATcount(b) ){
				// pre-sort the arguments
				onxt = *(oid*) Tloc(b,BUNfirst(b));
				for( j =top; j > 0 && onxt < *o_src[j-1]; j--){
					o_src[j] = o_src[j-1];
					o_end[j] = o_end[j-1];
					bats[j] = bats[j-1];
				}
				o_src[j] = (oid*) Tloc(b,BUNfirst(b));
				o_end[j] = o_src[j] + BATcount(b);
				bats[j] = b;
				top++;
			}
		}
	}

	bn = BATnew(TYPE_void, TYPE_oid, cap, TRANSIENT);
	if (bn == NULL){
		GDKfree(bats);
		GDKfree(o_src);
		GDKfree(o_end);
		throw(MAL, "mat.pack", MAL_MALLOC_FAIL);
	}

	if ( cap == 0){
		BATseqbase(bn, 0);
		BATseqbase(BATmirror(bn), 0);
		BBPkeepref(*ret = bn->batCacheid);
		GDKfree(bats);
		GDKfree(o_src);
		GDKfree(o_end);
		return MAL_SUCCEED;
	}
	BATseqbase(bn, bats[0]->hseqbase);
	// UNROLL THE MULTI-BAT MERGE
	o = (oid*) Tloc(bn,BUNfirst(bn));
	while( top){
		*o++ = *o_src[0];
		o_src[0]++;
		if( o_src[0] == o_end[0]){
			// remove this one
			for(j=0; j< top; j++){
				o_src[j]= o_src[j+1];
				o_end[j]= o_end[j+1];
				bats[j] = bats[j+1];
			}
			top--;
		} else{
			// resort priority queue
			onxt= *o_src[0];
			for( j=1; j< top && onxt > *o_src[j]; j++){
				oo = o_src[j]; o_src[j]= o_src[j-1]; o_src[j-1]= oo;
				oo = o_end[j]; o_end[j]= o_end[j-1]; o_end[j-1]= oo;
				bm = bats[j]; bats[j]=bats[j-1]; bats[j-1] = bm;
			}
		}
	}
	for( i=0; i< top; i++)
		BBPunfix(bats[i]->batCacheid);
    BATsetcount(bn, (BUN) (o - (oid *) Tloc(bn, BUNfirst(bn))));
    BATseqbase(bn, 0);
	BATsettrivprop(bn);
	GDKfree(bats);
	GDKfree(o_src);
	GDKfree(o_end);
    /* properties */
    bn->trevsorted = 0;
    bn->tsorted = 1;
    bn->tkey = 1;
    bn->T->nil = 0;
    bn->T->nonil = 1;
	BBPkeepref(*ret = bn->batCacheid);
	return MAL_SUCCEED;
}