fix(lsm): account for empty entries when appending data

lsm
Jef Roosens 2023-10-29 13:41:16 +01:00
parent f19a8814f5
commit 8b2117a66c
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
1 changed files with 22 additions and 9 deletions

View File

@ -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 // Data is in memory and still fits -> keep it in memory
if ((new_len <= LSM_STORE_DISK_THRESHOLD) && (!entry->data.on_disk)) { 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) { if (buf == NULL) {
return lsm_error_failed_alloc; 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; 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 // Write original in-memory data to file
while (written < entry->data.len) { while (written < entry->data.len) {
written += fwrite(&entry->data.value.ptr[written], sizeof(char), written += fwrite(&entry->data.value.ptr[written], sizeof(char),
entry->data.len - written, f); 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; handle->f = f;
entry->data.on_disk = true; entry->data.on_disk = true;
} }