Changeset: e5a1c58910b1 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e5a1c58910b1 Modified Files: MonetDB/src/gdk/gdk.mx MonetDB/src/gdk/gdk_align.mx MonetDB/src/gdk/gdk_bat.mx MonetDB/src/gdk/gdk_batop.mx MonetDB/src/gdk/gdk_bbp.mx MonetDB/src/gdk/gdk_heap.mx MonetDB/src/gdk/gdk_relop.mx MonetDB/src/gdk/gdk_storage.mx MonetDB4/src/modules/plain/decimal.mx MonetDB4/src/modules/plain/radix.mx MonetDB4/src/monet/monet_multiplex.mx MonetDB5/src/modules/mal/crackers/crackers_sideways.mx Branch: default Log Message:
Attempt to deal with views on varheaps. If a BAT is a view on another BAT, that can mean several things. - sharing BUN heap (only if no VAR heap) - sharing BUN heap + VAR heap - sharing VAR heap When sharing the VAR heap, two situations were possible: - the VAR heap structure is shared (and hence also the actual data) - the VAR heap structure is private, but the base pointer points into the parent's VAR heap data. This checkin gets rid of the latter possibility. When the VAR heap is shared, it is not completely shared. A VAR heap structure is "owned" by one BAT, the parent. Only when the parent BAT is destroyed can the heap structure and accompanying data be freed. The owner of the VAR heap structure is indicated by the parentid in the VAR heap structure. This value must now always be the ID of the owner BAT (and hence is always greater than zero). If the parentid value differs from a BAT's own ID, the var heap structure is owned by another BAT and hence the BAT is a view on this other BAT. Note that this checkin removes the possibility of a view's var heap base pointer pointing somewhere halfway into the parent's var heap data, but this situation doesn't make any sense since the BUN heap contains offsets relative to the start of the VAR heap data, which would be lost in this situation. This fixes bug 2553. diffs (truncated from 776 to 300 lines): diff -r e0460323b464 -r e5a1c58910b1 MonetDB/src/gdk/gdk.mx --- a/MonetDB/src/gdk/gdk.mx Thu Jun 10 14:14:26 2010 +0200 +++ b/MonetDB/src/gdk/gdk.mx Thu Jun 10 16:40:01 2010 +0200 @@ -3056,14 +3056,16 @@ */ #define isVIEW(x) \ (!(x)->P->lview && \ - ((x)->H->heap.parentid || ((x)->H->vheap&&(x)->H->vheap->parentid) || \ - (x)->T->heap.parentid || ((x)->T->vheap&&(x)->T->vheap->parentid))) + ((x)->H->heap.parentid || \ + (x)->T->heap.parentid || \ + ((x)->H->vheap && (x)->H->vheap->parentid != ABS((x)->batCacheid)) || \ + ((x)->T->vheap && (x)->T->vheap->parentid != ABS((x)->batCacheid)))) #define isVIEWCOMBINE(x) ((x)->H == (x)->T) #define VIEWhparent(x) ((x)->P->lview?0:(x)->H->heap.parentid) -#define VIEWvhparent(x) (((x)->P->lview||!(x)->H->vheap)?0:(x)->H->vheap->parentid) +#define VIEWvhparent(x) (((x)->P->lview||(x)->H->vheap==NULL||(x)->H->vheap->parentid==ABS((x)->batCacheid))?0:(x)->H->vheap->parentid) #define VIEWtparent(x) ((x)->P->lview?0:(x)->T->heap.parentid) -#define VIEWvtparent(x) (((x)->P->lview||!(x)->T->vheap)?0:(x)->T->vheap->parentid) +#define VIEWvtparent(x) (((x)->P->lview||(x)->T->vheap==NULL||(x)->T->vheap->parentid==ABS((x)->batCacheid))?0:(x)->T->vheap->parentid) /* VIEWparentcol(b) tells whether the head column was inherited from the parent * "as is". We must check whether the type was not overridden in the view. diff -r e0460323b464 -r e5a1c58910b1 MonetDB/src/gdk/gdk_align.mx --- a/MonetDB/src/gdk/gdk_align.mx Thu Jun 10 14:14:26 2010 +0200 +++ b/MonetDB/src/gdk/gdk_align.mx Thu Jun 10 16:40:01 2010 +0200 @@ -229,6 +229,10 @@ BBPshare(hp); *bn->H = *h->H; *bn->U = *h->U; + if (bn->H->vheap) { + assert(bn->H->vheap->parentid != 0); + BBPshare(bn->H->vheap->parentid); + } /* correct values after copy of head info */ bn->H->props = NULL; @@ -275,8 +279,8 @@ 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. +because in case of a mark, we are going to override a column with +a void. Take care to zero the accelerator data, though. @c *bn->U = *h->U; *bn->H = *h->H; @@ -296,6 +300,15 @@ BBPshare(hp); if (tp) BBPshare(tp); + if (bn->H->vheap) { + assert(bn->H->vheap->parentid > 0); + BBPshare(bn->H->vheap->parentid); + } + if (bn->T->vheap) { + assert(bn->T->vheap->parentid > 0); + 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 @@ -317,9 +330,9 @@ bn->batRestricted = BAT_READ; @- The U record may be shared with the parent; in that case, the -search accelerators of the parent can be used. If, however, we -want to take a horizontal fragment (stable=false), this cannot -be done, and we need to put different information in U (so we can't +search accelerators of the parent can be used. If, however, we +want to take a horizontal fragment (stable=false), this cannot +be done, and we need to put different information in U (so we can't use a copy. @c if (slice_view || !hp || isVIEW(h)) @@ -401,10 +414,16 @@ 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); @@ -504,7 +523,7 @@ { if (b) { bat hp = VIEWhparent(b), tp = VIEWtparent(b); - bat vhp = VIEWhparent(b), vtp = VIEWtparent(b); + bat vhp = VIEWvhparent(b), vtp = VIEWvtparent(b); BAT *hpb = NULL, *tpb = NULL; BAT *vhpb = NULL, *vtpb = NULL; @@ -525,9 +544,11 @@ return; /* unlink heaps shared with parent */ - if (vhpb && b->H->vheap && b->H->vheap == vhpb->H->vheap) + assert(b->H->vheap == NULL || b->H->vheap->parentid > 0); + assert(b->T->vheap == NULL || b->T->vheap->parentid > 0); + if (b->H->vheap && b->H->vheap->parentid != ABS(b->batCacheid)) b->H->vheap = NULL; - if (vtpb && b->T->vheap && b->T->vheap == vtpb->H->vheap) + if (b->T->vheap && b->T->vheap->parentid != ABS(b->batCacheid)) b->T->vheap = NULL; /* unlink properties shared with parent */ @@ -551,31 +572,40 @@ BAT * VIEWreset(BAT *b) { - bat hp, tp; + bat hp, tp, hvp, tvp; Heap head, tail, hh, th; + BAT *n = NULL, *v = NULL; if (b == NULL) return NULL; hp = VIEWhparent(b); tp = VIEWtparent(b); + hvp = VIEWvhparent(b); + tvp = VIEWvtparent(b); if (hp || tp) { - BAT *r = b; - BAT *n = b = BATdescriptor(ABS(b->batCacheid)); - BAT *m = BATmirror(n); - BAT *v; - BATstore *bs = BBP_desc(b->batCacheid); - BUN cnt = BATcount(b) + 1; - str nme = BBP_physical(n->batCacheid); - - assert(b->batCacheid > 0); - assert(hp || !r->htype); - assert(tp || !r->ttype); + BAT *m; + BATstore *bs; + BUN cnt; + str nme; /* 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); + + assert(n->batCacheid > 0); + assert(hp || !b->htype); + assert(tp || !b->ttype); + if (n->htype) { head.filename = (str) GDKmalloc(strlen(nme) + 12); if (head.filename == NULL) @@ -609,7 +639,7 @@ goto bailout; } - v = VIEWcreate(b, b); + v = VIEWcreate(n, n); if (v == NULL) goto bailout; @@ -623,6 +653,14 @@ BBPunshare(tp); BBPunfix(tp); } + if (hvp) { + BBPunshare(hvp); + BBPunfix(hvp); + } + if (tvp) { + BBPunshare(tvp); + BBPunfix(tvp); + } /* make sure everything points there */ m->U = n->U = &bs->U; @@ -655,16 +693,20 @@ /* 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; @@ -680,16 +722,17 @@ /* reset capacity */ n->U->capacity = cnt; - /* insert all of v in b, and quit */ - BATins(b, v, FALSE); + /* insert all of v in n, and quit */ + BATins(n, v, FALSE); BBPreclaim(v); - BBPunfix(b->batCacheid); - b = r; + BBPunfix(n->batCacheid); } return b; bailout: - if (b) - BBPunfix(b->batCacheid); + if (v != NULL) + BBPreclaim(v); + if (n != NULL) + BBPunfix(n->batCacheid); HEAPfree(&head); HEAPfree(&tail); HEAPfree(&hh); diff -r e0460323b464 -r e5a1c58910b1 MonetDB/src/gdk/gdk_bat.mx --- a/MonetDB/src/gdk/gdk_bat.mx Thu Jun 10 14:14:26 2010 +0200 +++ b/MonetDB/src/gdk/gdk_bat.mx Thu Jun 10 16:40:01 2010 +0200 @@ -143,6 +143,7 @@ @- fill in heap names, so HEAPallocs can resort to disk for very large writes. @c + assert(bn->batCacheid > 0); bn->H->heap.filename = NULL; bn->T->heap.filename = NULL; bn->batMaphead = 0; @@ -170,12 +171,14 @@ if ((bn->H->vheap = (Heap *) GDKzalloc(sizeof(Heap))) == NULL || (bn->H->vheap->filename = (str) GDKmalloc(strlen(nme) + 12)) == NULL) goto bailout; GDKfilepath(bn->H->vheap->filename, NULL, nme, "hheap"); + bn->H->vheap->parentid = bn->batCacheid; } if (ATOMneedheap(tt)) { if ((bn->T->vheap = (Heap *) GDKzalloc(sizeof(Heap))) == NULL || (bn->T->vheap->filename = (str) GDKmalloc(strlen(nme) + 12)) == NULL) goto bailout; GDKfilepath(bn->T->vheap->filename, NULL, nme, "theap"); + bn->T->vheap->parentid = bn->batCacheid; } } bn->batDirty = TRUE; @@ -185,11 +188,11 @@ HEAPfree(&bn->H->heap); if (tt) HEAPfree(&bn->T->heap); - if (ht && bn->H->vheap) { + if (bn->H->vheap) { HEAPfree(bn->H->vheap); GDKfree(bn->H->vheap); } - if (tt && bn->T->vheap) { + if (bn->T->vheap) { HEAPfree(bn->T->vheap); GDKfree(bn->T->vheap); } @@ -548,23 +551,29 @@ */ size_t cap = 0; - hh.filename = th.filename = NULL; - hh.base = th.base = NULL; - hh.parentid = th.parentid = 0; - if (b->H->vheap && b->H->vheap->free > 0) { - if (ATOMheap(b->htype, &hh, cap) < 0) - return NULL; + memset(&hh, 0, sizeof(hh)); + memset(&th, 0, sizeof(th)); + if (b->H->vheap && + b->H->vheap->free > 0 && + ATOMheap(b->htype, &hh, cap) < 0) { + return NULL; } - if (b->T->vheap && b->T->vheap->free > 0 && ATOMheap(b->ttype, &th, cap) < 0) { + if (b->T->vheap && + b->T->vheap->free > 0 && _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list