From 115ee12f040d3fbbceef4b81aba639d72315b27e Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Tue, 17 Oct 2023 11:25:51 +0200 Subject: [PATCH] feat(lsm): start store entry implementation --- lsm/include/lsm/store.h | 84 +++++++++++++++++++++++++++ lsm/src/_include/lsm/store_internal.h | 22 +++++++ lsm/src/store/lsm_store_entry.c | 37 ++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 lsm/include/lsm/store.h create mode 100644 lsm/src/_include/lsm/store_internal.h create mode 100644 lsm/src/store/lsm_store_entry.c diff --git a/lsm/include/lsm/store.h b/lsm/include/lsm/store.h new file mode 100644 index 0000000..d0fab21 --- /dev/null +++ b/lsm/include/lsm/store.h @@ -0,0 +1,84 @@ +#ifndef LSM_STORE +#define LSM_STORE + +#include +#include + +#include "lsm.h" +#include "lsm/str.h" + +/** + * The type of an entry attribute. + * + * Each type is represented as a single bit of an + * integer, so they can be easily combined into a bitmap. + */ +typedef enum lsm_attr_type : uint64_t { + lsm_attr_type_entry_type = 1 << 0, + lsm_attr_type_content_type = 1 << 1 +} lsm_attr_type; + +/** + * An entry inside an LSM store. + * + * Each entry consists of the key it's stored behind, zero or more attributes + * (metadata) and a data field. The data field can be stored on disk or + * in-memory, depending on the size. + */ +typedef struct lsm_entry lsm_entry; + +/** + * Allocate and initialize a new lsm_entry object. + * + * @param ptr where to store newly allocated pointer + */ +lsm_error lsm_entry_init(lsm_entry **ptr); + +/** + * Deallocate an existing lsm_entry object. + * + * @param entry object to deallocate + */ +void lsm_entry_free(lsm_entry *entry); + +/** + * Checks whether the entry has an attribute with the specified type. + * + * @param entry entry to check + * @param type type of attribute to check for + */ +bool lsm_entry_attr_present(lsm_entry *entry, lsm_attr_type type); + +/** + * Retrieve the contents of an attribute from an entry, if present + * + * @param out where to store pointer to attribute data + * @param entry entry to search for + * @param type type of attribute to return + */ +lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry *entry, + lsm_attr_type type); + +/** + * A store consisting of LSM entries. + * + * A store manages both an in-memory data structure for quick lookup, and a + * database file for persistent storage of the contained entries. + */ +typedef struct lsm_store lsm_store; + +/** + * Allocate and initialize a new lsm_store object. + * + * @param ptr where to store newly allocated pointer + */ +lsm_error lsm_store_init(lsm_store **ptr); + +/** + * Dealocate an existing lsm_store object. + * + * @param store object to deallocate + */ +void lsm_store_free(lsm_store *store); + +#endif diff --git a/lsm/src/_include/lsm/store_internal.h b/lsm/src/_include/lsm/store_internal.h new file mode 100644 index 0000000..d0aaed0 --- /dev/null +++ b/lsm/src/_include/lsm/store_internal.h @@ -0,0 +1,22 @@ +#ifndef LSM_STORE_INTERNAL +#define LSM_STORE_INTERNAL + +#include "lsm/store.h" +#include "lsm/str_internal.h" + +typedef struct lsm_attr { + lsm_attr_type type; + lsm_str str; +} lsm_attr; + +struct lsm_entry { + lsm_str key; + struct { + uint64_t count; + uint64_t bitmap; + lsm_attr *items; + } attrs; + lsm_str data; +}; + +#endif diff --git a/lsm/src/store/lsm_store_entry.c b/lsm/src/store/lsm_store_entry.c new file mode 100644 index 0000000..99a2b30 --- /dev/null +++ b/lsm/src/store/lsm_store_entry.c @@ -0,0 +1,37 @@ +#include + +#include "lsm.h" +#include "lsm/store_internal.h" + +lsm_error lsm_entry_init(lsm_entry **ptr) { + lsm_entry *entry = calloc(1, sizeof(lsm_entry)); + + if (entry == NULL) { + return lsm_error_failed_alloc; + } + + *ptr = entry; + + return lsm_error_ok; +} + +bool lsm_entry_attr_present(lsm_entry *entry, lsm_attr_type type) { + return (entry->attrs.bitmap & type) != 0; +} + +lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry *entry, + lsm_attr_type type) { + if (!lsm_entry_attr_present(entry, type)) { + return lsm_error_not_found; + } + + for (uint64_t i = 0; i < entry->attrs.count; i++) { + if (entry->attrs.items[i].type == type) { + *out = &entry->attrs.items[i].str; + + return lsm_error_ok; + } + } + + return lsm_error_not_found; +}