/* in the commit prelude, the delta status in the memory image of all * bats is commited */ static gdk_return prelude(int cnt, bat *subcommit) { int i = 0; while (++i < cnt) { bat bid = subcommit ? subcommit[i] : i; if (BBP_status(bid) & BBPPERSISTENT) { BAT *b = BBP_cache(bid); if (b == NULL && (BBP_status(bid) & BBPSWAPPED)) { b = BBPquickdesc(bid, TRUE); if (b == NULL) return GDK_FAIL; } if (b) { assert(!isVIEW(b)); assert(b->batRole == PERSISTENT); BATcommit(b); } } } return GDK_SUCCEED; }
/* * 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); }
str BKCgetSize(lng *tot, const bat *bid){ BAT *b; lng size = 0; lng blksize = (lng) MT_pagesize(); if ((b = BATdescriptor(*bid)) == NULL) { throw(MAL, "bat.getDiskSize", RUNTIME_OBJECT_MISSING); } size = sizeof (bat); if ( !isVIEW(b)) { BUN cnt = BATcapacity(b); size += ROUND_UP(b->H->heap.free, blksize); size += ROUND_UP(b->T->heap.free, blksize); if (b->H->vheap) size += ROUND_UP(b->H->vheap->free, blksize); if (b->T->vheap) size += ROUND_UP(b->T->vheap->free, blksize); if (b->H->hash) size += ROUND_UP(sizeof(BUN) * cnt, blksize); if (b->T->hash) size += ROUND_UP(sizeof(BUN) * cnt, blksize); size += IMPSimprintsize(b); } *tot = size; BBPunfix(*bid); return MAL_SUCCEED; }
/* * @+ 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; }
gdk_return BATmaterializeh(BAT *b) { int ht; BUN cnt; Heap head; BUN p, q; oid h, *x; bte tshift; BATcheck(b, "BATmaterialize", GDK_FAIL); assert(!isVIEW(b)); ht = b->htype; cnt = BATcapacity(b); head = b->H->heap; p = BUNfirst(b); q = BUNlast(b); assert(cnt >= q - p); ALGODEBUG fprintf(stderr, "#BATmaterialize(%d);\n", (int) b->batCacheid); if (!BAThdense(b) || ht != TYPE_void) { /* no voids */ return GDK_SUCCEED; } ht = TYPE_oid; /* cleanup possible ACC's */ HASHdestroy(b); IMPSdestroy(b); b->H->heap.filename = NULL; if (HEAPalloc(&b->H->heap, cnt, sizeof(oid)) != GDK_SUCCEED) { b->H->heap = head; return GDK_FAIL; } /* point of no return */ b->htype = ht; tshift = b->T->shift; BATsetdims(b); if (b->ttype) { b->T->shift = tshift; /* restore in case it got changed */ b->T->width = 1 << tshift; } b->batDirty = TRUE; b->batDirtydesc = TRUE; b->H->heap.dirty = TRUE; /* set the correct dense info */ b->hdense = TRUE; /* So now generate [h..h+cnt-1] */ h = b->hseqbase; x = (oid *) b->H->heap.base; for (; p < q; p++) *x++ = h++; cnt = h - b->hseqbase; BATsetcount(b, cnt); /* cleanup the old heaps */ HEAPfree(&head, 0); return GDK_SUCCEED; }
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; }