Changeset: c21d9793079e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/c21d9793079e Modified Files: gdk/gdk.h gdk/gdk_heap.c gdk/gdk_utils.c Branch: async-heap-remove Log Message:
Add async heap file remove Currently since the heap files seem to be reused, this solution might free files currently being used diffs (124 lines): diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -576,6 +576,17 @@ typedef struct { bat parentid; /* cache id of VIEW parent bat */ } Heap; +/* + * Instead of removing the heap files straight away, which incurs some impact on response time, + * we add the path to a buffer and asynchronously remove them. + */ +extern char **HEAPfreeBuffer; /* stores the heap filenames to remove */ +extern MT_Lock HEAPfreeBufferLock; /* controls concurrent accesses to the heap free buffer */ +extern int HEAPfreeBufferCount; /* current number of files stored in the heap free buffer */ +extern void HEAPfreeWorker(void*); +#define HEAP_FREE_BUFFER_SIZE 1024 /* maximum heap free buffer size */ +#define HEAP_FREE_WORKER_DELTA_MS 1024 /* sleep time between worker executions (in milliseconds) */ + typedef struct Hash Hash; typedef struct Imprints Imprints; typedef struct Strimps Strimps; diff --git a/gdk/gdk_heap.c b/gdk/gdk_heap.c --- a/gdk/gdk_heap.c +++ b/gdk/gdk_heap.c @@ -568,6 +568,49 @@ HEAPcopy(Heap *dst, Heap *src, size_t of return GDK_FAIL; } +char **HEAPfreeBuffer; +MT_Lock HEAPfreeBufferLock; +int HEAPfreeBufferCount = 0; + +/* + * Asynchronously frees heap files + */ +__attribute__((__noreturn__)) +void +HEAPfreeWorker(void* _) { + (void)_; + while (true) { + /* make a copy of the buffer and clean it to avoid blocking transactions for too long */ + MT_lock_set(&HEAPfreeBufferLock); + char** bufferCopy = malloc(HEAPfreeBufferCount * sizeof(char*)); + int count = HEAPfreeBufferCount; + for (int i = 0; i < count; i++) { + bufferCopy[i] = HEAPfreeBuffer[i]; + } + HEAPfreeBufferCount = 0; /* clean the buffer */ + MT_lock_unset(&HEAPfreeBufferLock); + + /* free the heap files */ + for (int i = 0; i < count; i++) { + char *path = bufferCopy[i]; + if (path && MT_remove(path) != 0 && errno != ENOENT) { + perror(path); + } + char *pathNew = malloc((strlen(path) + 4) * sizeof(char)); + snprintf(pathNew, sizeof(*pathNew), "%s.new", path); + if (MT_remove(pathNew) != 0 && errno != ENOENT) { + perror(pathNew); + } + GDKfree(path); + free(pathNew); + } + + free(bufferCopy); + + MT_sleep_ms(HEAP_FREE_WORKER_DELTA_MS); + } +} + /* Free the memory associated with the heap H. * Unlinks (removes) the associated file if the rmheap flag is set. */ void @@ -604,13 +647,25 @@ HEAPfree(Heap *h, bool rmheap) #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); + MT_lock_set(&HEAPfreeBufferLock); + /* check if the buffer has space */ + if (HEAPfreeBufferCount < HEAP_FREE_BUFFER_SIZE) { + HEAPfreeBuffer[HEAPfreeBufferCount++] = path; + MT_lock_unset(&HEAPfreeBufferLock); + } + /* in case there is no space on the buffer, free the heap synchronously */ + else { + MT_lock_unset(&HEAPfreeBufferLock); + 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); + } } } diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c --- a/gdk/gdk_utils.c +++ b/gdk/gdk_utils.c @@ -893,6 +893,13 @@ GDKinit(opt *set, int setlen, bool embed int i, nlen = 0; char buf[16]; + /* heapfree related initialization */ + HEAPfreeBuffer = malloc(HEAP_FREE_BUFFER_SIZE * sizeof(char*)); + MT_lock_init(&HEAPfreeBufferLock, "heap_free_buffer_lock"); + HEAPfreeBufferCount = 0; + MT_Id tid; + MT_create_thread(&tid, HEAPfreeWorker, NULL, MT_THR_DETACHED, "HEAPfreeWorker"); + ATOMIC_SET(&GDKstopped, 0); mainpid = MT_getpid(); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org