Example #1
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;
}
Example #2
0
/*
 * @+ View BATS
 * The general routine for getting a 'view' BAT upon another BAT is
 * @emph{VIEWcreate}. On this @emph{#read-only} BAT (there is kernel
 * support for this), you can then make vertical slices.  Use
 * @emph{VIEWhead} for this.
 *
 * It is possible to create a view on a writable BAT. Updates in the
 * parent are then automatically reflected in the VIEW.  Note that the
 * VIEW bat itself can never be modified.
 *
 * Horizontal views should only be given out on a view BAT, but only
 * if it is dead sure the parent BAT is read-only.  This because they
 * cannot physically share the batBuns heap with the parent, as they
 * need a modified version.
 */
static BAT *
VIEWhcreate(BAT *h)
{
	BATstore *bs;
	BAT *bn;
	bat hp;

	BATcheck(h, "VIEWhcreate", NULL);
	bs = BATcreatedesc(h->htype, TYPE_void, FALSE, TRANSIENT);
	if (bs == NULL)
		return NULL;
	bn = &bs->B;

	BATsetdims(bn);
	hp = VIEWhparent(h);

	if (h->htype == TYPE_void)
		hp = 0;
	if ((hp == 0 && h->htype != TYPE_void) || h->H->heap.copied)
		hp = h->batCacheid;
	if (hp)
		BBPshare(hp);
	*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->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);
	}

	/* correct values after copy of head info */
	bn->H->props = NULL;
	bn->H->heap.copied = 0;
	if (hp)
		bn->H->heap.parentid = hp;
	if (hp && isVIEW(h))
		bn->H->hash = NULL;
	BATinit_idents(bn);
	/* some bits must be copied individually. */
	bn->batDirty = BATdirty(h);
	bn->batRestricted = BAT_READ;

	BBPcacheit(bs, 1);		     /* enter in BBP */
	return bn;
}
Example #3
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;
}
Example #4
0
/*
 *  Mitosis-pieces are usually slices (views) of a base table/BAT.
 *  For variable-size atoms, this means that the vheap's of all pieces are
 *  likely to be identical (full) views of the same original base-BAT vheap.
 *  If so, the result of MATproject can also simply be a view of that very
 *  original base-BAT vheap (rather than a new view with all value (re-)inserted),
 *  i.e., we only need to build the result's tail BUN heap by copying the
 *  pointers (references) into the vheap from the input BATs (pieces).
 */
static BAT *
MATproject_var( BAT *map, BAT **bats, int len )
{
	BAT *res = NULL;
	int i = 0, j = -1;
	bit shared_Tvheaps = FALSE;

	while (i < len && BATcount(bats[i]) == 0)
		i++;
	if (i < len &&
	    bats[i]->tvarsized &&
	    bats[i]->T->vheap != NULL &&
	    bats[i]->T->vheap->parentid > 0) {
		shared_Tvheaps = TRUE;
		j = i++;
	}
	while (shared_Tvheaps && i < len) {
		shared_Tvheaps &= (BATcount(bats[i]) == 0 ||
		                   ( bats[i]->ttype == bats[j]->ttype &&
		                     bats[i]->batRestricted == BAT_READ &&
		                     bats[i]->T->vheap == bats[j]->T->vheap &&
		                     bats[i]->T->width == bats[j]->T->width &&
		                     bats[i]->T->shift == bats[j]->T->shift ));
		i++;
	}
	if (shared_Tvheaps) {
		switch (bats[j]->T->width) {
		case sizeof(bte):
			res = MATproject_bte(map, bats, len, TYPE_bte);
			break;
		case sizeof(sht):
			res = MATproject_sht(map, bats, len, TYPE_sht);
			break;
		case sizeof(int):
			res = MATproject_int(map, bats, len, TYPE_int);
			break;
		case sizeof(lng):
			res = MATproject_lng(map, bats, len, TYPE_lng);
			break;
#ifdef HAVE_HGE
		case sizeof(hge):
			res = MATproject_hge(map, bats, len, TYPE_hge);
			break;
#endif
		default:
			/* can (should) not happen */
			assert(0);
			return MATproject_any( map, bats, len );
		}
		if (res != NULL) {
			res->tvarsized = 1;
			res->ttype = bats[j]->ttype;
			res->T->vheap = bats[j]->T->vheap;
			res->T->width = bats[j]->T->width;
			res->T->shift = bats[j]->T->shift;
			BBPshare(bats[j]->T->vheap->parentid);
		}
	} else
		res = MATproject_any( map, bats, len );
	return res;
}