Changeset: d84e1e05ac04 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d84e1e05ac04
Modified Files:
        gdk/gdk.h
        gdk/gdk_bbp.c
        gdk/gdk_logger.c
Branch: geo
Log Message:

Move WKB upgrade to BBPinit.
This is a better place, since it can be done more safely in the face
of crashes.


diffs (truncated from 313 to 300 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -895,7 +895,8 @@ typedef struct {
 #define GDKLIBRARY_INET_COMPARE        061026  /* version with missing inet 
cmp func */
 #define GDKLIBRARY_64_BIT_INT  061027  /* version that had no 128-bit integer 
option, yet */
 #define GDKLIBRARY_SORTEDPOS   061030  /* version where we can't trust 
no(rev)sorted */
-#define GDKLIBRARY             061031
+#define GDKLIBRARY_OLDWKB      061031  /* old geom WKB format */
+#define GDKLIBRARY             061032
 
 typedef struct BAT {
        /* static bat properties */
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -772,6 +772,132 @@ fixsorted(void)
        GDKdebug = dbg;
 }
 
+#ifdef GDKLIBRARY_OLDWKB
+/* "Danger, Will Robinson".
+ *
+ * Upgrade the Well-known Binary (WKB) from older geom versions to the
+ * one in current use.  This function must be called before the SQL
+ * Write-ahead Log (WAL) is processed, and in order to be able to
+ * recover safely, we call it here.  The WAL may create new BATs with
+ * the WKB type, or append values to an existing BAT.  In the first
+ * case it is hard, and in the second impossible, to upgrade the BAT
+ * later.
+ *
+ * This function is located here, since it needs to be called early
+ * (as discussed), and because it calls functions that are GDK only.
+ * There is a little knowledge about the MonetDB WKB type, but nothing
+ * about the internals of the type.  The only knowledge is the layout
+ * of the old and new structures.
+ *
+ * All errors are fatal.
+ */
+static void
+fixwkbheap(void)
+{
+       bat bid, bbpsize = getBBPsize();
+       BATstore *bs;
+       BAT *b;
+       int utypewkb = ATOMunknown_find("wkb");
+       const char *nme, *bnme;
+       char filename[64];
+       Heap h1, h2;
+       const var_t *restrict old;
+       var_t *restrict new;
+       BUN i;
+       struct old_wkb {
+               int len;
+               char data[FLEXIBLE_ARRAY_MEMBER];
+       } *owkb;
+       struct new_wkb {
+               int len;
+               int srid;
+               char data[FLEXIBLE_ARRAY_MEMBER];
+       } *nwkb;
+       char *oldname, *newname;
+
+       for (bid = 1; bid < bbpsize; bid++) {
+               if ((bs = BBP_desc(bid)) == NULL)
+                       continue; /* not a valid BAT */
+               b = (BAT *) bs;   /* bit of a hack: BATstore contents not known 
*/
+               if (b->T->type != utypewkb || b->batCount == 0)
+                       continue; /* nothing to do for this BAT */
+               assert(b->T->vheap);
+               assert(b->T->width == SIZEOF_VAR_T);
+
+               nme = BBP_physical(bid);
+               if ((bnme = strrchr(nme, DIR_SEP)) == NULL)
+                       bnme = nme;
+               else
+                       bnme++;
+               snprintf(filename, sizeof(filename), "BACKUP%c%s", DIR_SEP, 
bnme);
+               if ((oldname = GDKfilepath(b->T->heap.farmid, BATDIR, nme, 
"tail")) == NULL ||
+                   (newname = GDKfilepath(b->T->heap.farmid, BAKDIR, bnme, 
"tail")) == NULL ||
+                   GDKcreatedir(newname) != GDK_SUCCEED ||
+                   rename(oldname, newname) < 0)
+                       GDKfatal("fixwkbheap: cannot make backup of %s.tail\n", 
nme);
+               GDKfree(oldname);
+               GDKfree(newname);
+               if ((oldname = GDKfilepath(b->T->vheap->farmid, BATDIR, nme, 
"theap")) == NULL ||
+                   (newname = GDKfilepath(b->T->vheap->farmid, BAKDIR, bnme, 
"theap")) == NULL ||
+                   rename(oldname, newname) < 0)
+                       GDKfatal("fixwkbheap: cannot make backup of 
%s.theap\n", nme);
+               GDKfree(oldname);
+               GDKfree(newname);
+
+               h1 = b->T->heap;
+               h1.filename = NULL;
+               h1.base = NULL;
+               h1.dirty = 0;
+               h2 = *b->T->vheap;
+               h2.filename = NULL;
+               h2.base = NULL;
+               h2.dirty = 0;
+
+               /* load old heaps */
+               if (HEAPload(&h1, filename, "tail", 0) != GDK_SUCCEED ||
+                   HEAPload(&h2, filename, "theap", 0) != GDK_SUCCEED)
+                       GDKfatal("fixwkbheap: cannot load old heaps for BAT 
%d\n", bid);
+               /* create new heaps */
+               if ((b->T->heap.filename = GDKfilepath(NOFARM, NULL, nme, 
"tail")) == NULL ||
+                   (b->T->vheap->filename = GDKfilepath(NOFARM, NULL, nme, 
"theap")) == NULL)
+                       GDKfatal("fixwkbheap: out of memory\n");
+               if (HEAPalloc(&b->T->heap, b->batCapacity, SIZEOF_VAR_T) != 
GDK_SUCCEED)
+                       GDKfatal("fixwkbheap: cannot allocate heap\n");
+               b->T->heap.dirty = TRUE;
+               b->T->heap.free = h1.free;
+               HEAP_initialize(b->T->vheap, b->batCapacity, 0, (int) 
sizeof(var_t));
+               if (b->T->vheap->base == NULL)
+                       GDKfatal("fixwkbheap: cannot allocate heap\n");
+               b->T->vheap->parentid = bid;
+
+               /* do the conversion */
+               b->T->heap.dirty = TRUE;
+               b->T->vheap->dirty = TRUE;
+               old = (const var_t *) h1.base + BUNfirst(b);
+               new = (var_t *) Tloc(b, BUNfirst(b));
+               for (i = 0; i < b->batCount; i++) {
+                       int len;
+                       owkb = (struct old_wkb *) (h2.base + old[i]);
+                       if ((len = owkb->len) == ~0)
+                               len = 0;
+                       if ((new[i] = HEAP_malloc(b->T->vheap, offsetof(struct 
new_wkb, data) + len)) == 0)
+                               GDKfatal("fixwkbheap: cannot allocate heap 
space\n");
+                       nwkb = (struct new_wkb *) (b->T->vheap->base + (new[i] 
<< GDK_VARSHIFT));
+                       nwkb->len = owkb->len;
+                       nwkb->srid = 0;
+                       if (len > 0)
+                               memcpy(nwkb->data, owkb->data, len);
+               }
+               HEAPfree(&h1, 0);
+               HEAPfree(&h2, 0);
+               HEAPsave(&b->T->heap, nme, "tail");
+               HEAPfree(&b->T->heap, 0);
+               HEAPsave(b->T->vheap, nme, "theap");
+               HEAPfree(b->T->vheap, 0);
+       }
+}
+#endif
+
 /*
  * A read only BAT can be shared in a file system by reading its
  * descriptor separately.  The default src=0 is to read the full
@@ -1233,6 +1359,10 @@ BBPinit(void)
 #endif
        if (bbpversion <= GDKLIBRARY_SORTEDPOS)
                fixsorted();
+#ifdef GDKLIBRARY_OLDWKB
+       if (bbpversion <= GDKLIBRARY_OLDWKB)
+               fixwkbheap();
+#endif
        if (bbpversion < GDKLIBRARY || needcommit)
                TMcommit();
 
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -1124,8 +1124,6 @@ logger_commit(logger *lg)
        return bm_commit(lg);
 }
 
-static void geom_upgrade_wkb(void);
-
 static gdk_return
 check_version(logger *lg, FILE *fp)
 {
@@ -1147,8 +1145,6 @@ check_version(logger *lg, FILE *fp)
 
                        return GDK_FAIL;
                }
-               if (geomisoldversion)
-                       geom_upgrade_wkb();
        } else
                lg->postfuncp = NULL;    /* don't call */
        if (fgetc(fp) != '\n' ||         /* skip \n */
@@ -2872,131 +2868,3 @@ int geomversion_get(void)
 {
        return geomisoldversion;
 }
-
-/* "Danger, Will Robinson".
- *
- * Upgrade the Well-known Binary (WKB) from older geom versions to the
- * one in current use.  This function should only be called when the
- * geom module has been loaded, and it should be called before the
- * Write-ahead Log (WAL) is processed.  The WAL may create new BATs
- * with the WKB type, or append values to an existing BAT.  In the
- * first case it is hard, and in the second impossible, to upgrade the
- * BAT later.
- *
- * This function is located here, since it needs to be called early
- * (as discussed), and because it calls functions that are GDK only.
- * There is a little knowledge about the MonetDB WKB type, but nothing
- * about the internals of the type.
- *
- * All errors are fatal.
- */
-static void
-geom_upgrade_wkb(void)
-{
-       bat bid, bbpsize = getBBPsize();
-       BATstore *bs;
-       BAT *b;
-       int typewkb = ATOMindex("wkb");
-       int utypewkb = ATOMunknown_find("wkb");
-       const char *nme, *bnme;
-       char filename[64];
-       Heap h1, h2;
-       const var_t *restrict old;
-       var_t *restrict new;
-       BUN i;
-       struct old_wkb {
-               int len;
-               char data[FLEXIBLE_ARRAY_MEMBER];
-       } *owkb;
-       struct new_wkb {
-               int len;
-               int srid;
-               char data[FLEXIBLE_ARRAY_MEMBER];
-       } *nwkb;
-       char *oldname, *newname;
-
-       assert(typewkb > 0);
-       for (bid = 1; bid < bbpsize; bid++) {
-               if ((bs = BBP_desc(bid)) == NULL)
-                       continue; /* not a valid BAT */
-               b = (BAT *) bs;   /* bit of a hack: BATstore contents not known 
*/
-               if ((b->T->type != typewkb && b->T->type != utypewkb) ||
-                   b->batCount == 0)
-                       continue; /* nothing to do for this BAT */
-               assert(b->T->vheap);
-               assert(b->T->width == SIZEOF_VAR_T);
-
-               nme = BBP_physical(bid);
-               if ((bnme = strrchr(nme, DIR_SEP)) == NULL)
-                       bnme = nme;
-               else
-                       bnme++;
-               snprintf(filename, sizeof(filename), "BACKUP%c%s", DIR_SEP, 
bnme);
-               if ((oldname = GDKfilepath(b->T->heap.farmid, BATDIR, nme, 
"tail")) == NULL ||
-                   (newname = GDKfilepath(b->T->heap.farmid, BAKDIR, bnme, 
"tail")) == NULL ||
-                   GDKcreatedir(newname) != GDK_SUCCEED ||
-                   rename(oldname, newname) < 0)
-                       GDKfatal("geom_upgrade_wkb: cannot make backup of 
%s.tail\n", nme);
-               GDKfree(oldname);
-               GDKfree(newname);
-               if ((oldname = GDKfilepath(b->T->vheap->farmid, BATDIR, nme, 
"theap")) == NULL ||
-                   (newname = GDKfilepath(b->T->vheap->farmid, BAKDIR, bnme, 
"theap")) == NULL ||
-                   rename(oldname, newname) < 0)
-                       GDKfatal("geom_upgrade_wkb: cannot make backup of 
%s.theap\n", nme);
-               GDKfree(oldname);
-               GDKfree(newname);
-
-               h1 = b->T->heap;
-               h1.filename = NULL;
-               h1.base = NULL;
-               h1.dirty = 0;
-               h2 = *b->T->vheap;
-               h2.filename = NULL;
-               h2.base = NULL;
-               h2.dirty = 0;
-
-               /* load old heaps */
-               if (HEAPload(&h1, filename, "tail", 0) != GDK_SUCCEED ||
-                   HEAPload(&h2, filename, "theap", 0) != GDK_SUCCEED)
-                       GDKfatal("geom_upgrade_wkb: cannot load old heaps for 
BAT %d\n", bid);
-               /* create new heaps */
-               if ((b->T->heap.filename = GDKfilepath(NOFARM, NULL, nme, 
"tail")) == NULL ||
-                   (b->T->vheap->filename = GDKfilepath(NOFARM, NULL, nme, 
"theap")) == NULL)
-                       GDKfatal("geom_upgrade_wkb: out of memory\n");
-               if (HEAPalloc(&b->T->heap, b->batCapacity, SIZEOF_VAR_T) != 
GDK_SUCCEED)
-                       GDKfatal("geom_upgrade_wkb: cannot allocate heap\n");
-               b->T->heap.dirty = TRUE;
-               b->T->heap.free = h1.free;
-               HEAP_initialize(b->T->vheap, b->batCapacity, 0, (int) 
sizeof(var_t));
-               if (b->T->vheap->base == NULL)
-                       GDKfatal("geom_upgrade_wkb: cannot allocate heap\n");
-               b->T->vheap->parentid = bid;
-
-               /* do the conversion */
-               b->T->heap.dirty = TRUE;
-               b->T->vheap->dirty = TRUE;
-               old = (const var_t *) h1.base + BUNfirst(b);
-               new = (var_t *) Tloc(b, BUNfirst(b));
-               for (i = 0; i < b->batCount; i++) {
-                       int len;
-                       owkb = (struct old_wkb *) (h2.base + old[i]);
-                       if ((len = owkb->len) == ~0)
-                               len = 0;
-                       if ((new[i] = HEAP_malloc(b->T->vheap, offsetof(struct 
new_wkb, data) + len)) == 0)
-                               GDKfatal("geom_upgrade_wkb: cannot allocate 
heap space\n");
-                       nwkb = (struct new_wkb *) (b->T->vheap->base + (new[i] 
<< GDK_VARSHIFT));
-                       nwkb->len = owkb->len;
-                       nwkb->srid = 0;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to