Пример #1
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;
}
Пример #2
0
static BAT *
MATproject_hge( BAT *map, BAT **bats, int len, int ttpe )
{
	BAT *res;
	int i;
	BUN j, cnt = BATcount(map);
	hge *resT, **batsT;
	bte *mapT;

	res = BATnew(TYPE_void, ttpe, cnt, TRANSIENT);
	batsT = (hge**)GDKmalloc(sizeof(hge*) * len);
	if (res == NULL || batsT == NULL) {
		if (res)
			BBPreclaim(res);
		if (batsT)
			GDKfree(batsT);
		return NULL;
	}
	BATseqbase(res, map->hseqbase);
	resT = (hge*)Tloc(res, 0);
	mapT = (bte*)Tloc(map, 0);
	for (i=0; i<len; i++)
		batsT[i] = (hge*)Tloc(bats[i], 0);
	for (j=0; j<cnt; j++)
		resT[j] = *batsT[mapT[j]]++;
	BATsetcount(res, j);
	res->hrevsorted = j <= 1;
	GDKfree(batsT);
	return res;
}
Пример #3
0
str DCselectInsert(int *ret, int *res, int *bid, lng *low, lng *hgh)
{
	BAT *b, *r;

	lng *readerH, *writerH;
	lng *readerT, *writerT;

	BUN size, i;

	(void) ret;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "dc.selectInsert", "Cannot access input BAT");

	if ((r = BATdescriptor(*res)) == NULL)
		throw(MAL, "dc.selectInsert", "Cannot access result BAT");

	size = BATcount(b);

	if (size > BATcapacity(r) - BATcount(r)) {
		BUN ncap;
		BUN grows;
		BUN needed = size - (BATcapacity(r) - BATcount(r));
		ncap = BATcapacity(r) + needed;
		grows = BATgrows(r);
		if (ncap > grows)
			grows = ncap;
		if (BATextend(r, grows) == NULL)
			throw(MAL, "dc.selectInsert", "Failed to make room for the new values");
	}
/*printf("in dc.selectInsert size is "OIDFMT,size);*/
	writerH = (lng *) Hloc(r, BUNfirst(r));
	writerT = (lng *) Tloc(r, BUNfirst(r));

	readerH = (lng *) Hloc(b, BUNfirst(b));
	readerT = (lng *) Tloc(b, BUNfirst(b));

	for (i = 0; i < size; i++) {
		if (*readerT >= *low && *readerT <= *hgh) {
			*writerH = *readerH;
			*writerT = *readerT;

			writerH++;
			writerT++;
		}
		readerH++;
		readerT++;
	}
	BATsetcount(r, (BUN) (writerT - (lng *) Tloc(r, BUNfirst(r))));

	BBPunfix(*bid);
	BBPunfix(*res);

	return MAL_SUCCEED;
}
Пример #4
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;
}
Пример #5
0
static BAT *
MATsort_bte( BAT **map, BAT **bats, int len, BUN cnt, int rev )
{
	BAT *res;
	int i;
	bte *resT, **batsT, *in;
	bte *mapT;
	BUN len1, len2;
	bte *map_in = NULL;

	res = BATnew(TYPE_void, bats[0]->ttype, cnt, TRANSIENT);
	*map = BATnew(TYPE_void, TYPE_bte, cnt, TRANSIENT);
	if (res == NULL || *map == NULL) {
		BBPreclaim(res);
		BBPreclaim(*map);
		*map = NULL;
		return NULL;
	}
	BATseqbase(res, 0);
	BATseqbase(*map, 0);
	resT = (bte*)Tloc(res, 0);
	mapT = (bte*)Tloc(*map, 0);
	batsT = (bte**)GDKmalloc(sizeof(bte*) * len);
	for (i=0; i<len; i++)
		batsT[i] = (bte*)Tloc(bats[i], 0);
	/* merge */
	in = batsT[0];
	len1 = BATcount(bats[0]);
	map_in = NULL;
	/* TODO: change into a tree version */
	for (i=1; i<len; i++) {
		len2 = BATcount(bats[i]);
		if (rev) {
			MATsortloop_bte_rev( resT+cnt-len1-len2, 
					mapT+cnt-len1-len2, 
				        in, map_in, len1, 
					batsT[i], i, len2);
		} else {
			MATsortloop_bte_( resT+cnt-len1-len2, 
					mapT+cnt-len1-len2, 
				        in, map_in, len1, 
					batsT[i], i, len2);
		}
		in = resT+cnt-len1-len2;
		map_in = mapT+cnt-len1-len2;
		len1 += len2;
	}
	BATsetcount(res, len1);
	BATsetcount(*map, len1);
	res->hrevsorted = len1 <= 1;
	(*map)->hrevsorted = len1 <= 1;
	GDKfree(batsT);
	return res;
}
Пример #6
0
static BAT *
MATproject_any( BAT *map, BAT **bats, int len )
{
	BAT *res;
	int i;
	BUN j, cnt = BATcount(map);
	BATiter *bats_i;
	BUN *batsT;
	bte *mapT;

	res = BATnew(TYPE_void, bats[0]->ttype, cnt, TRANSIENT);
	batsT = (BUN*)GDKmalloc(sizeof(BUN) * len);
	bats_i = (BATiter*)GDKmalloc(sizeof(BATiter) * len);
	if (res == NULL || batsT == NULL || bats_i == NULL) {
		if (res)
			BBPreclaim(res);
		if (batsT)
			GDKfree(batsT);
		if (bats_i)
			GDKfree(bats_i);
		return NULL;
	}
	BATseqbase(res, map->hseqbase);
	mapT = (bte*)Tloc(map, 0);
	for (i=0; i<len; i++) {
		batsT[i] = 0;
		bats_i[i] = bat_iterator(bats[i]);
	}
	for (j=0; j<cnt; j++)
		BUNappend(res, BUNtail(bats_i[mapT[j]], batsT[mapT[j]]++), FALSE);
	GDKfree(batsT);
	GDKfree(bats_i);
	return res;
}
Пример #7
0
static BAT *
MATsort_any( BAT **map, BAT **bats, int len, BUN cnt, int rev )
{
	BAT *res = 0, *in;
	int i;
	bte *mapT;
	BUN len1, len2;
	bte *map_in = NULL;

	*map = BATnew(TYPE_void, TYPE_bte, cnt, TRANSIENT);
	if (*map == NULL)
		return NULL;
	BATseqbase(*map, 0);
	mapT = (bte*)Tloc(*map, 0);
	/* merge */
	/* TODO: change into a tree version */
	in = bats[0];
	len1 = BATcount(in);
	for (i=1; i<len; i++) {
		len2 = BATcount(bats[i]);
		if (rev) {
			res = MATsortloop_rev( 
				mapT+cnt-len1-len2, 
		        	in, map_in, len1, 
				bats[i], i, len2);
		} else {
			res = MATsortloop_( 
				mapT+cnt-len1-len2, 
		        	in, map_in, len1, 
				bats[i], i, len2);
		}
		if (i != 1)
			BBPunfix(in->batCacheid);
		if (res == NULL)
			return NULL;
		in = res;
		map_in = mapT+cnt-len1-len2;
		len1 += len2;
	}
	BATsetcount(*map, len1);
	(*map)->hrevsorted = len1 <= 1;
	return res;
}
Пример #8
0
str
MKEYbathash(bat *res, const bat *bid)
{
	BAT *b, *dst;
	wrd *r;
	BUN n;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(SQL, "mkey.bathash", RUNTIME_OBJECT_MISSING);

	assert(BAThvoid(b) || BAThrestricted(b));

	n = BATcount(b);
	dst = BATnew(TYPE_void, TYPE_wrd, n, TRANSIENT);
	if (dst == NULL) {
		BBPunfix(b->batCacheid);
		throw(SQL, "mkey.bathash", MAL_MALLOC_FAIL);
	}
	BATseqbase(dst, b->hseqbase);
	BATsetcount(dst, n);

	r = (wrd *) Tloc(dst, BUNfirst(dst));

	switch (ATOMstorage(b->ttype)) {
	case TYPE_void: {
		oid o = b->tseqbase;
		if (o == oid_nil)
			while (n-- > 0)
				*r++ = wrd_nil;
		else
			while (n-- > 0)
				*r++ = (wrd) o++;
		break;
	}
	case TYPE_bte: {
		bte *v = (bte *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_bte(v);
			v++;
		}
		break;
	}
	case TYPE_sht: {
		sht *v = (sht *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_sht(v);
			v++;
		}
		break;
	}
	case TYPE_int:
	case TYPE_flt: {
		int *v = (int *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_int(v);
			v++;
		}
		break;
	}
	case TYPE_lng:
	case TYPE_dbl: {
		lng *v = (lng *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_lng(v);
			v++;
		}
		break;
	}
#ifdef HAVE_HGE
	case TYPE_hge: {
		hge *v = (hge *) Tloc(b, BUNfirst(b));
		while (n-- > 0) {
			*r++ = MKEYHASH_hge(v);
			v++;
		}
		break;
	}
#endif
	default: {
		BATiter bi = bat_iterator(b);
		BUN (*hash)(const void *) = BATatoms[b->ttype].atomHash;
		int (*cmp)(const void *, const void *) = ATOMcompare(b->ttype);
		void *nil = ATOMnilptr(b->ttype);
		BUN i;
		const void *v;

		BATloop(b, i, n) {
			v = BUNtail(bi, i);
			if ((*cmp)(v, nil) == 0)
				*r++ = wrd_nil;
			else
				*r++ = (wrd) (*hash)(v);
		}
		break;
	}
	}
Пример #9
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;
}
Пример #10
0
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;
}
Пример #11
0
/*
 * 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;
}
Пример #12
0
// 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;
}
Пример #13
0
str
BKCreuseBATmap(bat *ret, const bat *bid, const bat *did)
{
	BAT *b, *d, *bn, *bs;
	oid bidx, oidx = 0, *o, *ol;
	oid *r;
	gdk_return res;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "bat.shrinkMap", RUNTIME_OBJECT_MISSING);
	}
	if ( b->htype != TYPE_void) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.shrinkMap", SEMANTIC_TYPE_MISMATCH);
	}
	if ((d = BATdescriptor(*did)) == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.shrinkMap", RUNTIME_OBJECT_MISSING);
	}
	bn= BATnew(TYPE_void, TYPE_oid, BATcount(b) - BATcount(d), TRANSIENT);
	if (bn == NULL) {
		BBPunfix(b->batCacheid);
		BBPunfix(d->batCacheid);
		throw(MAL, "bat.shrinkMap", MAL_MALLOC_FAIL );
	}
	res = BATsubsort(&bs, NULL, NULL, d, NULL, NULL, 0, 0);
	BBPunfix(d->batCacheid);
	if (res != GDK_SUCCEED) {
		BBPunfix(b->batCacheid);
		BBPunfix(bn->batCacheid);
		throw(MAL, "bat.shrinkMap", MAL_MALLOC_FAIL );
	}

	oidx = b->hseqbase;
	bidx = oidx + BATcount(b)-1;
	o  = (oid*)Tloc(bs, BUNfirst(bs));
	ol = (oid*)Tloc(bs, BUNlast(bs));
	r  = (oid*)Tloc(bn, BUNfirst(bn));

	for (; oidx <= bidx; oidx++) {
		if ( *o == oidx ){
			while ( ol > o && ol[-1] == bidx) {
				bidx--;
				ol--;
			}
			*r++ = bidx;
			o += (o < ol);
			bidx--;
		} else {
			*r++ = oidx;
		}
	}

    BATsetcount(bn, BATcount(b)-BATcount(bs));
	BATseqbase(bn, b->hseqbase);
    bn->tsorted = 0;
    bn->trevsorted = 0;
    bn->tdense = 0;

    if (!(bn->batDirty&2)) BATsetaccess(bn, BAT_READ);

	BBPunfix(b->batCacheid);
	BBPunfix(bs->batCacheid);
	BBPkeepref(*ret= bn->batCacheid);
	return MAL_SUCCEED;
}
Пример #14
0
str
BKCreuseBAT(bat *ret, const bat *bid, const bat *did)
{
	BAT *b, *d, *bn, *bs;
	oid oidx = 0, bidx, *o, *ol;
	gdk_return res;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "bat.reuse", RUNTIME_OBJECT_MISSING);
	}
	if ( b->htype != TYPE_void) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.reuse", SEMANTIC_TYPE_MISMATCH);
	}
	if ((d = BATdescriptor(*did)) == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.reuse", RUNTIME_OBJECT_MISSING);
	}
	bn= BATnew(b->htype, b->ttype, BATcount(b) - BATcount(d), TRANSIENT);
	if (bn == NULL) {
		BBPunfix(b->batCacheid);
		BBPunfix(d->batCacheid);
		throw(MAL, "bat.reuse", MAL_MALLOC_FAIL );
	}
	res = BATsubsort(&bs, NULL, NULL, d, NULL, NULL, 0, 0);
	BBPunfix(d->batCacheid);
	if (res != GDK_SUCCEED) {
		BBPunfix(b->batCacheid);
		BBPunfix(bn->batCacheid);
		throw(MAL, "bat.reuse", MAL_MALLOC_FAIL );
	}

	oidx = b->hseqbase;
	bidx = oidx + BATcount(b)-1;
	o = (oid*)Tloc(bs, BUNfirst(bs));
	ol= (oid*)Tloc(bs, BUNlast(bs));

	switch(ATOMstorage(b->ttype) ){
	case TYPE_bte: reuseloop(bte); break;
	case TYPE_sht: reuseloop(sht); break;
	case TYPE_int: reuseloop(int); break;
	case TYPE_lng: reuseloop(lng); break;
#ifdef HAVE_HGE
	case TYPE_hge: reuseloop(hge); break;
#endif
	case TYPE_flt: reuseloop(flt); break;
	case TYPE_dbl: reuseloop(dbl); break;
	case TYPE_oid: reuseloop(oid); break;
	case TYPE_str: /* to be done based on its index width */
	default:
		if (ATOMvarsized(bn->ttype)) {
			BUN p = BUNfirst(b);
			BUN q = BUNlast(b);
			BATiter bi = bat_iterator(b);

			for (;p<q; oidx++, p++) {
				if ( *o == oidx ){
					while ( ol > o && ol[-1] == bidx) {
						bidx--;
						q--;
						ol--;
					}
					BUNappend(bn, BUNtail(bi, --q), FALSE);
					o += (o < ol);
					bidx--;
				} else {
					BUNappend(bn, BUNtail(bi, p), FALSE);
				}
			}
		} else {
			switch( b->T->width){
			case 1:reuseloop(bte); break;
			case 2:reuseloop(sht); break;
			case 4:reuseloop(int); break;
			case 8:reuseloop(lng); break;
#ifdef HAVE_HGE
			case 16:reuseloop(hge); break;
#endif
			default:
				throw(MAL, "bat.shrink", "Illegal argument type");
			}
		}
	}

    BATsetcount(bn, BATcount(b) - BATcount(bs));
	BATseqbase(bn, b->hseqbase);
    bn->tsorted = 0;
    bn->trevsorted = 0;
    bn->tdense = 0;
	bn->tkey = b->tkey;

    if (!(bn->batDirty&2)) BATsetaccess(bn, BAT_READ);

	BBPunfix(b->batCacheid);
	BBPunfix(bs->batCacheid);
	BBPkeepref(*ret= bn->batCacheid);
	return MAL_SUCCEED;
}