Changeset: 0437910a8737 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/0437910a8737
Modified Files:
        gdk/gdk.h
        gdk/gdk_bbp.c
        gdk/gdk_hash.c
        gdk/gdk_heap.c
        gdk/gdk_imprints.c
        gdk/gdk_orderidx.c
        gdk/gdk_strimps.c
Branch: default
Log Message:

Avoid unlinking heap files that were never saved to disk.


diffs (231 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -570,7 +570,8 @@ typedef struct {
        bool cleanhash;         /* string heaps must clean hash */
        bool dirty;             /* specific heap dirty marker */
        bool remove;            /* remove storage file when freeing */
-       bool wasempty;      /* heap was empty when last saved/created */
+       bool wasempty;          /* heap was empty when last saved/created */
+       bool hasfile;           /* .filename exists on disk */
        storage_t storage;      /* storage mode (mmap/malloc). */
        storage_t newstorage;   /* new desired storage mode at re-allocation. */
        bat parentid;           /* cache id of VIEW parent bat */
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -449,6 +449,7 @@ vheapinit(BAT *b, const char *buf, unsig
                .dirty = false,
                .parentid = b->batCacheid,
                .farmid = BBPselectfarm(PERSISTENT, b->ttype, varheap),
+               .hasfile = free > 0,
        };
        strconcat_len(b->tvheap->filename, sizeof(b->tvheap->filename),
                      filename, ".theap", NULL);
@@ -560,6 +561,7 @@ heapinit(BAT *b, const char *buf,
        /* (properties & 0x0200) is the old tdense flag */
        b->tseqbase = (properties & 0x0200) == 0 || base >= (uint64_t) oid_nil 
? oid_nil : (oid) base;
        b->theap->free = (size_t) free;
+       b->theap->hasfile = free > 0;
        /* set heap size to match capacity */
        if (b->ttype == TYPE_msk) {
                /* round up capacity to multiple of 32 */
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -549,6 +549,8 @@ BATcheckhash(BAT *b)
                                                                
h->heaplink.dirty = false;
                                                                
h->heapbckt.dirty = false;
                                                                b->thash = h;
+                                                               
h->heapbckt.hasfile = true;
+                                                               
h->heaplink.hasfile = true;
                                                                
TRC_DEBUG(ACCELERATOR,
                                                                          
ALGOBATFMT ": reusing persisted hash\n", ALGOBATPAR(b));
                                                                
MT_rwlock_wrunlock(&b->thashlock);
@@ -582,6 +584,8 @@ BATcheckhash(BAT *b)
                                        /* unlink unusable file */
                                        GDKunlink(h->heaplink.farmid, BATDIR, 
nme, "thashl");
                                        GDKunlink(h->heapbckt.farmid, BATDIR, 
nme, "thashb");
+                                       h->heapbckt.hasfile = false;
+                                       h->heaplink.hasfile = false;
                                }
                        }
                        GDKfree(h);
@@ -605,8 +609,6 @@ BAThashsave_intern(BAT *b, bool dosync)
        TRC_DEBUG_IF(ACCELERATOR) t0 = GDKusec();
 
        if ((h = b->thash) != NULL) {
-               Heap *hp = &h->heapbckt;
-
 #ifndef PERSISTENTHASH
                /* no need to sync if not persistent */
                dosync = false;
@@ -617,12 +619,14 @@ BAThashsave_intern(BAT *b, bool dosync)
                if (!b->theap->dirty &&
                    ((size_t *) h->heapbckt.base)[4] == BATcount(b) &&
                    HEAPsave(&h->heaplink, h->heaplink.filename, NULL, dosync, 
h->heaplink.free, NULL) == GDK_SUCCEED &&
-                   HEAPsave(hp, hp->filename, NULL, dosync, hp->free, NULL) == 
GDK_SUCCEED) {
+                   HEAPsave(&h->heapbckt, h->heapbckt.filename, NULL, dosync, 
h->heapbckt.free, NULL) == GDK_SUCCEED) {
                        h->heaplink.dirty = false;
-                       hp->dirty = false;
+                       h->heapbckt.dirty = false;
+                       h->heaplink.hasfile = true;
+                       h->heapbckt.hasfile = true;
                        gdk_return rc = HASHfix(h, true, dosync);
                        TRC_DEBUG(ACCELERATOR,
-                                 ALGOBATFMT ": persisting hash %s%s (" LLFMT " 
usec)%s\n", ALGOBATPAR(b), hp->filename, dosync ? "" : " no sync", GDKusec() - 
t0, rc == GDK_SUCCEED ? "" : " failed");
+                                 ALGOBATFMT ": persisting hash %s%s (" LLFMT " 
usec)%s\n", ALGOBATPAR(b), h->heapbckt.filename, dosync ? "" : " no sync", 
GDKusec() - t0, rc == GDK_SUCCEED ? "" : " failed");
                }
                GDKclrerr();
        }
diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c
--- a/gdk/gdk_heap.c
+++ b/gdk/gdk_heap.c
@@ -171,6 +171,7 @@ HEAPalloc(Heap *h, size_t nitems, size_t
                if (itemsizemmap > itemsize)
                        h->size = MAX(1, nitems) * itemsizemmap;
                h->base = HEAPcreatefile(NOFARM, &h->size, nme);
+               h->hasfile = true;
                GDKfree(nme);
        }
        if (h->base == NULL) {
@@ -221,6 +222,7 @@ HEAPextend(Heap *h, size_t size, bool ma
                char *p;
                char *path;
 
+               assert(h->hasfile);
                TRC_DEBUG(HEAP, "Extending %s mmapped heap (%s)\n", h->storage 
== STORE_MMAP ? "shared" : "privately", h->filename);
                /* extend memory mapped file */
                if ((path = GDKfilepath(h->farmid, BATDIR, nme, ext)) == NULL) {
@@ -280,12 +282,14 @@ HEAPextend(Heap *h, size_t size, bool ma
                         * new and we can use STORE_MMAP */
                        int fd = GDKfdlocate(h->farmid, nme, "rb", ext);
                        if (fd >= 0) {
+                               assert(h->hasfile);
                                existing = true;
                                close(fd);
                        } else {
                                /* no pre-existing heap file, so create a new
                                 * one */
                                h->base = HEAPcreatefile(h->farmid, &h->size, 
h->filename);
+                               h->hasfile = true;
                                if (h->base) {
                                        h->newstorage = h->storage = STORE_MMAP;
                                        memcpy(h->base, bak.base, bak.free);
@@ -363,6 +367,7 @@ HEAPshrink(Heap *h, size_t size)
        } else {
                char *path;
 
+               assert(h->hasfile);
                /* shrink memory mapped file */
                /* round up to multiple of GDK_mmap_pagesize with
                 * minimum of one */
@@ -603,14 +608,36 @@ HEAPfree(Heap *h, bool rmheap)
        } else
 #endif
        if (rmheap && !GDKinmemory(h->farmid)) {
-               char *path = GDKfilepath(h->farmid, BATDIR, h->filename, NULL);
-               if (path && MT_remove(path) != 0 && errno != ENOENT)
-                       perror(path);
-               GDKfree(path);
-               path = GDKfilepath(h->farmid, BATDIR, h->filename, "new");
-               if (path && MT_remove(path) != 0 && errno != ENOENT)
-                       perror(path);
-               GDKfree(path);
+               if (h->hasfile) {
+                       char *path = GDKfilepath(h->farmid, BATDIR, 
h->filename, NULL);
+                       if (path) {
+                               int ret = MT_remove(path);
+                               if (ret == -1) {
+                                       /* unexpectedly not present */
+                                       perror(path);
+                               }
+                               assert(ret == 0);
+                               GDKfree(path);
+                               h->hasfile = false;
+                       }
+                       path = GDKfilepath(h->farmid, BATDIR, h->filename, 
"new");
+                       if (path) {
+                               /* in practice, should never be present */
+                               int ret = MT_remove(path);
+                               if (ret == -1 && errno != ENOENT)
+                                       perror(path);
+                               assert(ret == -1 && errno == ENOENT);
+                               GDKfree(path);
+                       }
+#ifndef NDEBUG
+               } else {
+                       char *path = GDKfilepath(h->farmid, BATDIR, 
h->filename, NULL);
+                       /* should not be present */
+                       struct stat st;
+                       assert(stat(path, &st) == -1 && errno == ENOENT);
+                       GDKfree(path);
+#endif
+               }
        }
 }
 
@@ -801,6 +828,7 @@ HEAPsave_intern(Heap *h, const char *nme
        if (lock)
                MT_lock_set(lock);
        if (rc == GDK_SUCCEED) {
+               h->hasfile = true;
                h->dirty = free != h->free;
                h->wasempty = false;
        } else {
diff --git a/gdk/gdk_imprints.c b/gdk/gdk_imprints.c
--- a/gdk/gdk_imprints.c
+++ b/gdk/gdk_imprints.c
@@ -354,6 +354,7 @@ BATcheckimprints(BAT *b)
                                                imprints->dict = (void *) 
((uintptr_t) ((char *) imprints->imps + pages * (imprints->bits / 8) + 
sizeof(uint64_t)) & ~(sizeof(uint64_t) - 1));
                                                close(fd);
                                                imprints->imprints.parentid = 
b->batCacheid;
+                                               imprints->imprints.hasfile = 
true;
                                                
ATOMIC_INIT(&imprints->imprints.refs, 1);
                                                b->timprints = imprints;
                                                TRC_DEBUG(ACCELERATOR, 
ALGOBATFMT " reusing persisted imprints\n", ALGOBATPAR(b));
@@ -364,6 +365,7 @@ BATcheckimprints(BAT *b)
                                        close(fd);
                                        /* unlink unusable file */
                                        GDKunlink(imprints->imprints.farmid, 
BATDIR, nme, "timprints");
+                                       imprints->imprints.hasfile = false;
                                }
                        }
                        GDKfree(imprints);
diff --git a/gdk/gdk_orderidx.c b/gdk/gdk_orderidx.c
--- a/gdk/gdk_orderidx.c
+++ b/gdk/gdk_orderidx.c
@@ -110,6 +110,7 @@ BATcheckorderidx(BAT *b)
                                        close(fd);
                                        ATOMIC_INIT(&hp->refs, 1);
                                        b->torderidx = hp;
+                                       hp->hasfile = true;
                                        TRC_DEBUG(ACCELERATOR, 
"BATcheckorderidx(" ALGOBATFMT "): reusing persisted orderidx\n", 
ALGOBATPAR(b));
                                        MT_lock_unset(&b->batIdxLock);
                                        return true;
@@ -117,6 +118,7 @@ BATcheckorderidx(BAT *b)
                                close(fd);
                                /* unlink unusable file */
                                GDKunlink(hp->farmid, BATDIR, nme, "torderidx");
+                               hp->hasfile = false;
                        }
                }
                GDKfree(hp);
diff --git a/gdk/gdk_strimps.c b/gdk/gdk_strimps.c
--- a/gdk/gdk_strimps.c
+++ b/gdk/gdk_strimps.c
@@ -471,12 +471,14 @@ BATcheckstrimps(BAT *b)
                                        ATOMIC_INIT(&hp->strimps.refs, 1);
                                        hp->strimps.parentid = b->batCacheid;
                                        b->tstrimps = hp;
+                                       hp->strimps.hasfile = true;
                                        TRC_DEBUG(ACCELERATOR, 
"BATcheckstrimps(" ALGOBATFMT "): reusing persisted strimp\n", ALGOBATPAR(b));
                                        return true;
                                }
                                close(fd);
                                /* unlink unusable file */
                                GDKunlink(hp->strimps.farmid, BATDIR, nme, 
"tstrimps");
+                               hp->strimps.hasfile = false;
 
                        }
                }
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to