コード例 #1
0
ファイル: dcoperator.c プロジェクト: Clay-Birkett/monetdb
str
DCsliceStrict(int *ret, bat *bid, lng *start, lng *end)
{
	BAT *b, *bn = NULL;

	if ((b = BATdescriptor(*bid)) == NULL) {
		throw(MAL, "dcoperator.sliceStrict", "Cannot access descriptor");
	}

	assert(*start >= 0);
	assert(*end >= 0);
	assert(*start <= (lng) BUN_MAX);
	assert(*end < (lng) BUN_MAX);
	assert(*start <= *end);

	if ((BUN) ((*end - *start) + 1) > BATcount(b)) {
		bn = BATnew(b->htype, b->ttype, 0);
		BATsetcount(bn, 0);
		*ret = bn->batCacheid;
		BBPkeepref(*ret);
		return MAL_SUCCEED;
	}

	bn = BATslice(b, (BUN) *start, (BUN) *end + 1);

	BBPreleaseref(b->batCacheid);
	if (bn != NULL) {
		if (!(bn->batDirty & 2))
			bn = BATsetaccess(bn, BAT_READ);
		*ret = bn->batCacheid;
		BBPkeepref(*ret);
		return MAL_SUCCEED;
	}
	throw(MAL, "dcoperator.sliceStrict", "GDKerror");
}
コード例 #2
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;
}
コード例 #3
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;
}
コード例 #4
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;
}