Exemplo n.º 1
0
str
BKCinsert_bat_force(bat *r, const bat *bid, const bat *sid, const bit *force)
{
	BAT *b, *s;

	if ((b = BATdescriptor(*bid)) == NULL)
		throw(MAL, "bat.insert", RUNTIME_OBJECT_MISSING);
	if ((b = setaccess(b, BAT_WRITE)) == NULL)
		throw(MAL, "bat.insert", OPERATION_FAILED);
	if ((s = BATdescriptor(*sid)) == NULL) {
		BBPunfix(b->batCacheid);
		throw(MAL, "bat.insert", RUNTIME_OBJECT_MISSING);
	}
	if (BATins(b, s, *force) != GDK_SUCCEED) {
		BBPunfix(b->batCacheid);
		BBPunfix(s->batCacheid);
		throw(MAL, "bat.insert", GDK_EXCEPTION);
	}
	BBPunfix(s->batCacheid);
	BBPkeepref(*r = b->batCacheid);
	return MAL_SUCCEED;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;
}