From 715e1f9a5880cd84d371437b212ff6f0bdaa2f8a Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 9 Nov 2023 21:07:51 +0100 Subject: [PATCH] refactor(lsm): clean up disk write code --- include/lander.h | 2 +- lsm/src/store/lsm_store_disk_write.c | 88 +++++++++++++++------------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/include/lander.h b/include/lander.h index 5abea75..3c812c1 100644 --- a/include/lander.h +++ b/include/lander.h @@ -24,7 +24,7 @@ typedef enum lander_attr_type : uint8_t { lander_attr_type_url = 2, } lander_attr_type; -typedef enum lander_entry_type { +typedef enum lander_entry_type : uint8_t { lander_entry_type_redirect = 0, lander_entry_type_paste = 1, } lander_entry_type; diff --git a/lsm/src/store/lsm_store_disk_write.c b/lsm/src/store/lsm_store_disk_write.c index eb60c22..b79a78b 100644 --- a/lsm/src/store/lsm_store_disk_write.c +++ b/lsm/src/store/lsm_store_disk_write.c @@ -1,31 +1,39 @@ #include "lsm/store_internal.h" -static lsm_error lsm_entry_write_single(FILE *f, uint64_t size, void *val) { - size_t res = fwrite(val, size, 1, f); +static lsm_error lsm_fwrite(uint64_t *sum, FILE *f, uint64_t size, + uint64_t count, void *val) { + size_t res = fwrite(val, size, count, f); - if (res == 0) { + if (res < count) { return lsm_error_failed_io; } + if (sum != NULL) { + *sum += size * count; + } + return lsm_error_ok; } -static lsm_error lsm_entry_write_uint64_t(FILE *f, uint64_t num) { - return lsm_entry_write_single(f, sizeof(uint64_t), &num); -} +static lsm_error lsm_write_str(uint64_t *sum, FILE *f, lsm_str *s) { + uint64_t len = lsm_str_len(s); + + LSM_RES(lsm_fwrite(sum, f, sizeof(uint64_t), 1, &len)); -static lsm_error lsm_entry_write_str(FILE *f, lsm_str *s) { - uint64_t to_write = lsm_str_len(s); uint64_t written = 0; do { - written += fwrite(lsm_str_ptr(s), sizeof(char), to_write - written, f); - } while (written < to_write); + written += fwrite(lsm_str_ptr(s), sizeof(char), len - written, f); + } while (written < len); + + if (sum != NULL) { + *sum += len * sizeof(char); + } return lsm_error_ok; } -static lsm_error lsm_seek(FILE *f, uint64_t pos) { +static lsm_error lsm_fseek(FILE *f, uint64_t pos) { if (fseek(f, pos, SEEK_SET) != 0) { return lsm_error_failed_io; } @@ -35,24 +43,17 @@ static lsm_error lsm_seek(FILE *f, uint64_t pos) { lsm_error lsm_entry_write_db(uint64_t *size, FILE *db_file, lsm_entry *entry, uint64_t pos) { - LSM_RES(lsm_seek(db_file, pos)); + *size = 0; - LSM_RES(lsm_entry_write_uint64_t(db_file, entry->data_len)); + LSM_RES(lsm_fseek(db_file, pos)); - LSM_RES( - lsm_entry_write_single(db_file, sizeof(uint8_t), &entry->attrs.count)); - *size = sizeof(uint64_t) + sizeof(uint8_t); + LSM_RES(lsm_fwrite(size, db_file, sizeof(uint64_t), 1, &entry->data_len)); + LSM_RES(lsm_fwrite(size, db_file, sizeof(uint8_t), 1, &entry->attrs.count)); for (uint8_t i = 0; i < entry->attrs.count; i++) { - // Write attribute type, length & value - LSM_RES(lsm_entry_write_single(db_file, sizeof(uint8_t), - &entry->attrs.items[i].type)); - LSM_RES(lsm_entry_write_uint64_t(db_file, - lsm_str_len(entry->attrs.items[i].str))); - LSM_RES(lsm_entry_write_str(db_file, entry->attrs.items[i].str)); - - *size += sizeof(uint8_t) + sizeof(uint64_t) + - lsm_str_len(entry->attrs.items[i].str) * sizeof(char); + LSM_RES(lsm_fwrite(size, db_file, sizeof(uint8_t), 1, + &entry->attrs.items[i].type)); + LSM_RES(lsm_write_str(size, db_file, entry->attrs.items[i].str)); } return lsm_error_ok; @@ -60,13 +61,13 @@ lsm_error lsm_entry_write_db(uint64_t *size, FILE *db_file, lsm_entry *entry, lsm_error lsm_entry_write_idx(uint64_t *size, FILE *idx_file, lsm_entry *entry, uint64_t offset, uint64_t len, uint64_t pos) { - LSM_RES(lsm_seek(idx_file, pos)); - LSM_RES(lsm_entry_write_uint64_t(idx_file, lsm_str_len(entry->key))); - LSM_RES(lsm_entry_write_str(idx_file, entry->key)); - LSM_RES(lsm_entry_write_uint64_t(idx_file, offset)); - LSM_RES(lsm_entry_write_uint64_t(idx_file, len)); + *size = 0; - *size = 3 * sizeof(uint64_t) + lsm_str_len(entry->key) * sizeof(char); + LSM_RES(lsm_fseek(idx_file, pos)); + + LSM_RES(lsm_write_str(size, idx_file, entry->key)); + LSM_RES(lsm_fwrite(size, idx_file, sizeof(uint64_t), 1, &offset)); + LSM_RES(lsm_fwrite(size, idx_file, sizeof(uint64_t), 1, &len)); return lsm_error_ok; } @@ -74,9 +75,10 @@ lsm_error lsm_entry_write_idx(uint64_t *size, FILE *idx_file, lsm_entry *entry, lsm_error lsm_entry_sync(lsm_store *store, lsm_entry_handle *handle) { pthread_mutex_lock(&store->db_lock); - uint64_t entry_size; - lsm_error res = lsm_entry_write_db( - &entry_size, store->db_file, handle->wrapper->entry, store->db_file_size); + uint64_t db_entry_size; + lsm_error res = + lsm_entry_write_db(&db_entry_size, store->db_file, handle->wrapper->entry, + store->db_file_size); fflush(store->db_file); if (res != lsm_error_ok) { @@ -85,17 +87,17 @@ lsm_error lsm_entry_sync(lsm_store *store, lsm_entry_handle *handle) { return res; } - uint64_t entry_index = store->db_file_size; - store->db_file_size += entry_size; + uint64_t db_entry_index = store->db_file_size; pthread_mutex_unlock(&store->db_lock); // Append entry to index file pthread_mutex_lock(&store->idx_lock); - res = - lsm_entry_write_idx(&entry_size, store->idx_file, handle->wrapper->entry, - entry_index, entry_size, store->idx_file_size); + uint64_t idx_entry_size; + res = lsm_entry_write_idx(&idx_entry_size, store->idx_file, + handle->wrapper->entry, db_entry_index, + db_entry_size, store->idx_file_size); if (res == lsm_error_ok) { // Update the counter at the beginning of the file @@ -103,14 +105,16 @@ lsm_error lsm_entry_sync(lsm_store *store, lsm_entry_handle *handle) { uint64_t new_block_count = store->idx_file_block_count + 1; - res = lsm_entry_write_uint64_t(store->idx_file, new_block_count); + res = lsm_fwrite(NULL, store->idx_file, sizeof(uint64_t), 1, + &new_block_count); if (res == lsm_error_ok) { // Only if we successfully updated the on-disk counter do we make the code - // aware that the file's size has increased. This way, if a write to the + // aware that the files' sizes have increased. This way, if a write to the // counter fails, the code will simply reuse the already written content. - store->idx_file_size += entry_size; + store->idx_file_size += idx_entry_size; store->idx_file_block_count = new_block_count; + store->db_file_size += db_entry_size; } }