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

Reply via email to