diff --git a/lsm/src/_include/lsm/store_internal.h b/lsm/src/_include/lsm/store_internal.h index cebb41b..ccafe99 100644 --- a/lsm/src/_include/lsm/store_internal.h +++ b/lsm/src/_include/lsm/store_internal.h @@ -59,8 +59,12 @@ void lsm_entry_wrapper_free(lsm_entry_wrapper *wrapper); struct lsm_entry_handle { lsm_entry_wrapper *wrapper; lsm_store *store; + // Either read or append, depending on how it was opened FILE *f; + // Current position in the file pointer uint64_t pos; + // Whether the entry's metadata has changed + bool dirty; }; lsm_error lsm_entry_handle_init(lsm_entry_handle **out); @@ -88,13 +92,6 @@ struct lsm_store { */ lsm_error lsm_store_load_db(lsm_store *store); -/** - * Close & free the handle without updating the database - * - * @param handle handle to close - */ -void lsm_entry_close_no_disk(lsm_entry_handle *handle); - /** * Write a new insert to the database. * diff --git a/lsm/src/store/lsm_store.c b/lsm/src/store/lsm_store.c index 2da7c51..022e68b 100644 --- a/lsm/src/store/lsm_store.c +++ b/lsm/src/store/lsm_store.c @@ -150,6 +150,9 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store, handle->wrapper = wrapper; handle->store = store; + // Newly inserted entries are always dirty + handle->dirty = true; + *out = handle; return lsm_error_ok; @@ -189,6 +192,7 @@ lsm_error lsm_entry_data_append(lsm_entry_handle *handle, lsm_str *data) { } entry->data_len = new_len; + handle->dirty = true; return lsm_error_ok; } diff --git a/lsm/src/store/lsm_store_disk_read.c b/lsm/src/store/lsm_store_disk_read.c index 040708a..5c71dee 100644 --- a/lsm/src/store/lsm_store_disk_read.c +++ b/lsm/src/store/lsm_store_disk_read.c @@ -172,7 +172,11 @@ lsm_error lsm_store_load_db(lsm_store *store) { LSM_RES(lsm_entry_read_attrs(NULL, handle, store->db_file)); handle->wrapper->entry->idx_file_offset = idx_file_offset; - lsm_entry_close_no_disk(handle); + + // We explicitely set the dirty flag here to prevent writing to the datase + // when reading it in + handle->dirty = false; + lsm_entry_close(handle); store->db_file_size += db_dim[1]; } diff --git a/lsm/src/store/lsm_store_entry.c b/lsm/src/store/lsm_store_entry.c index 45ead55..4623f36 100644 --- a/lsm/src/store/lsm_store_entry.c +++ b/lsm/src/store/lsm_store_entry.c @@ -47,19 +47,18 @@ lsm_error lsm_entry_handle_init(lsm_entry_handle **out) { return lsm_error_ok; } -void lsm_entry_close_no_disk(lsm_entry_handle *handle) { - pthread_rwlock_unlock(&handle->wrapper->lock); - free(handle); -} - void lsm_entry_close(lsm_entry_handle *handle) { if (handle->f != NULL) { fclose(handle->f); } // TODO handle errors here - lsm_entry_disk_insert(handle); - lsm_entry_close_no_disk(handle); + if (handle->dirty) { + lsm_entry_disk_insert(handle); + } + + pthread_rwlock_unlock(&handle->wrapper->lock); + free(handle); } bool lsm_entry_attr_present(lsm_entry_handle *handle, uint8_t type) { @@ -158,6 +157,8 @@ lsm_error lsm_entry_attr_remove(lsm_str **out, lsm_entry_handle *handle, entry->attrs.count--; entry->attrs.bitmap[type / 64] &= ~(((uint64_t)1) << (type % 64)); + handle->dirty = true; + return lsm_error_ok; } @@ -183,6 +184,8 @@ lsm_error lsm_entry_attr_insert(lsm_entry_handle *handle, uint8_t type, entry->attrs.count++; entry->attrs.bitmap[type / 64] |= ((uint64_t)1) << (type % 64); + handle->dirty = true; + return lsm_error_ok; }