diff --git a/lsm/src/store/lsm_store.c b/lsm/src/store/lsm_store.c index 42643b9..cd6a45b 100644 --- a/lsm/src/store/lsm_store.c +++ b/lsm/src/store/lsm_store.c @@ -195,7 +195,14 @@ lsm_error lsm_entry_data_append(lsm_store *store, lsm_entry_handle *handle, // Data is in memory and still fits -> keep it in memory if ((new_len <= LSM_STORE_DISK_THRESHOLD) && (!entry->data.on_disk)) { - char *buf = realloc(entry->data.value.ptr, new_len * sizeof(char)); + char *buf; + + // Entries with no data do not have an allocated buffer yet + if (entry->data.len == 0) { + buf = malloc(new_len * sizeof(char)); + } else { + buf = realloc(entry->data.value.ptr, new_len * sizeof(char)); + } if (buf == NULL) { return lsm_error_failed_alloc; @@ -218,17 +225,23 @@ lsm_error lsm_entry_data_append(lsm_store *store, lsm_entry_handle *handle, return lsm_error_failed_io; } - size_t written = 0; + // If there was data present in memory already, we sync this to disk. + // This check is required because it's possible that more than the + // treshold is written to an empty entry immediately, meaning there's no + // allocated memory buffer present. + if (entry->data.len > 0) { + size_t written = 0; - // Write original in-memory data to file - while (written < entry->data.len) { - written += fwrite(&entry->data.value.ptr[written], sizeof(char), - entry->data.len - written, f); + // Write original in-memory data to file + while (written < entry->data.len) { + written += fwrite(&entry->data.value.ptr[written], sizeof(char), + entry->data.len - written, f); + } + + free(entry->data.value.ptr); + entry->data.value.ptr = NULL; } - free(entry->data.value.ptr); - entry->data.value.ptr = NULL; - handle->f = f; entry->data.on_disk = true; }