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]