chore(lsm): some refactoring
ci/woodpecker/push/docker Pipeline was successful Details

release/0.2.0
Jef Roosens 2023-11-16 21:52:20 +01:00
parent e3aad2b5e4
commit 881f2defbe
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
9 changed files with 60 additions and 76 deletions

View File

@ -10,6 +10,15 @@
return res; \ return res; \
} }
#define LSM_RES2(x, e) \
{ \
lsm_error res = x; \
if (res != lsm_error_ok) { \
e; \
return res; \
} \
}
typedef enum lsm_error { typedef enum lsm_error {
lsm_error_ok = 0, lsm_error_ok = 0,
lsm_error_failed_alloc = 1, lsm_error_failed_alloc = 1,

View File

@ -37,7 +37,7 @@ uint64_t lsm_bt_size(const lsm_bt *bt);
* @param bt binary tree to search * @param bt binary tree to search
* @param key key to search * @param key key to search
*/ */
lsm_error lsm_bt_search(void **out, lsm_bt *bt, char key); lsm_error lsm_bt_search(void **out, const lsm_bt *bt, char key);
/** /**
* Insert a new data value into the tree with the given key. * Insert a new data value into the tree with the given key.

View File

@ -143,7 +143,7 @@ void lsm_store_free(lsm_store *store);
* @param key key to search * @param key key to search
*/ */
lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store, lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
lsm_str *key); const lsm_str *key);
/** /**
* Open a write handle to the given entry. This handle should only be used for * Open a write handle to the given entry. This handle should only be used for
@ -155,7 +155,7 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
* @param key key to search * @param key key to search
*/ */
lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store, lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store,
lsm_str *key); const lsm_str *key);
/** /**
* Close an open entry handle. * Close an open entry handle.
@ -193,7 +193,7 @@ void lsm_entry_remove(lsm_entry_handle *handle);
* @param entry entry to append data to * @param entry entry to append data to
* @param data data to append * @param data data to append
*/ */
lsm_error lsm_entry_data_append(lsm_entry_handle *handle, lsm_str *data); lsm_error lsm_entry_data_append(lsm_entry_handle *handle, const lsm_str *data);
/** /**
* Same as `lsm_entry_data_append`, except that it takes a direct char array. * Same as `lsm_entry_data_append`, except that it takes a direct char array.

View File

@ -107,14 +107,14 @@ uint64_t lsm_str_len(const lsm_str *str);
* *
* @param str string to return pointer for * @param str string to return pointer for
*/ */
const char *lsm_str_ptr(lsm_str *str); const char *lsm_str_ptr(const lsm_str *str);
/** /**
* Returns the character at the specified position. * Returns the character at the specified position.
* *
* @index index of character to return * @index index of character to return
*/ */
char lsm_str_char(lsm_str *str, uint64_t index); char lsm_str_char(const lsm_str *str, uint64_t index);
/** /**
* Take a substring and copy it to a provided string object. * Take a substring and copy it to a provided string object.
@ -127,7 +127,7 @@ char lsm_str_char(lsm_str *str, uint64_t index);
* or equal to the string's length, out will be a zero-length string. * or equal to the string's length, out will be a zero-length string.
* @param end exclusive end index for the substring * @param end exclusive end index for the substring
*/ */
lsm_error lsm_str_substr(lsm_str *out, lsm_str *str, uint64_t start, lsm_error lsm_str_substr(lsm_str *out, const lsm_str *str, uint64_t start,
uint64_t end); uint64_t end);
/** /**
@ -141,7 +141,7 @@ lsm_error lsm_str_substr(lsm_str *out, lsm_str *str, uint64_t start,
* @param s2 string to compare s1 to * @param s2 string to compare s1 to
* @param s2_offset offset inside s2 to start comparing from * @param s2_offset offset inside s2 to start comparing from
*/ */
uint64_t lsm_str_cmp(lsm_str *s1, uint64_t s1_offset, lsm_str *s2, uint64_t lsm_str_cmp(const lsm_str *s1, uint64_t s1_offset, const lsm_str *s2,
uint64_t s2_offset); uint64_t s2_offset);
/** /**
@ -151,7 +151,7 @@ uint64_t lsm_str_cmp(lsm_str *s1, uint64_t s1_offset, lsm_str *s2,
* @param s2 second string to compare * @param s2 second string to compare
* @return true if their values are equal, false otherwise * @return true if their values are equal, false otherwise
*/ */
bool lsm_str_eq(lsm_str *s1, lsm_str *s2); bool lsm_str_eq(const lsm_str *s1, const lsm_str *s2);
/** /**
* Truncate an already initialized string in-place. * Truncate an already initialized string in-place.

View File

@ -30,16 +30,16 @@ void lsm_trie_free(lsm_trie *trie);
* @param key key to insert data with * @param key key to insert data with
* @param data data to insert * @param data data to insert
*/ */
lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data); lsm_error lsm_trie_insert(lsm_trie *trie, const lsm_str *key, void *data);
/** /**
* Search for an element in the trie. * Search for an element in the trie.
* *
* @param out where to store data opinter, if present * @param out where to store data pointer, if present
* @param trie trie to search in * @param trie trie to search in
* @param key key to search with * @param key key to search with
*/ */
lsm_error lsm_trie_search(void **data, lsm_trie *trie, lsm_str *key); lsm_error lsm_trie_search(void **out, const lsm_trie *trie, const lsm_str *key);
/** /**
* Remove an element from the trie. * Remove an element from the trie.
@ -48,7 +48,7 @@ lsm_error lsm_trie_search(void **data, lsm_trie *trie, lsm_str *key);
* @param trie trie to remove from * @param trie trie to remove from
* @param key key to remove * @param key key to remove
*/ */
lsm_error lsm_trie_remove(void **data, lsm_trie *trie, lsm_str *key); lsm_error lsm_trie_remove(void **out, lsm_trie *trie, const lsm_str *key);
/** /**
* Return the size of a trie * Return the size of a trie

View File

@ -71,19 +71,16 @@ lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data) {
return lsm_error_already_present; return lsm_error_already_present;
} }
lsm_bt_node *node; if (lsm_bt_node_init(dest, key, data) != lsm_error_ok) {
if (lsm_bt_node_init(&node, key, data) != lsm_error_ok) {
return lsm_error_failed_alloc; return lsm_error_failed_alloc;
} }
*dest = node;
bt->size++; bt->size++;
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_bt_search(void **out, lsm_bt *bt, char key) { lsm_error lsm_bt_search(void **out, const lsm_bt *bt, char key) {
lsm_bt_node *node = bt->root; lsm_bt_node *node = bt->root;
while ((node != NULL) && (node->key != key)) { while ((node != NULL) && (node->key != key)) {

View File

@ -14,13 +14,7 @@ lsm_error lsm_store_init(lsm_store **ptr) {
return lsm_error_failed_alloc; return lsm_error_failed_alloc;
} }
lsm_error res = lsm_trie_init(&store->trie); LSM_RES2(lsm_trie_init(&store->trie), free(store));
if (res != lsm_error_ok) {
free(store);
return res;
}
pthread_mutex_init(&store->db.lock, NULL); pthread_mutex_init(&store->db.lock, NULL);
pthread_mutex_init(&store->idx.lock, NULL); pthread_mutex_init(&store->idx.lock, NULL);
@ -35,7 +29,7 @@ uint64_t lsm_store_size(const lsm_store *store) {
} }
lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store, lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
lsm_str *key) { const lsm_str *key) {
lsm_entry_wrapper *wrapper; lsm_entry_wrapper *wrapper;
LSM_RES(lsm_trie_search((void **)&wrapper, store->trie, key)); LSM_RES(lsm_trie_search((void **)&wrapper, store->trie, key));
@ -54,13 +48,7 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
} }
lsm_entry_handle *handle; lsm_entry_handle *handle;
lsm_error res = lsm_entry_handle_init(&handle); LSM_RES2(lsm_entry_handle_init(&handle), pthread_rwlock_unlock(&wrapper->lock));
if (res != lsm_error_ok) {
pthread_rwlock_unlock(&wrapper->lock);
return res;
}
handle->wrapper = wrapper; handle->wrapper = wrapper;
handle->store = store; handle->store = store;
@ -70,9 +58,8 @@ lsm_error lsm_store_open_read(lsm_entry_handle **out, lsm_store *store,
} }
lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store, lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store,
lsm_str *key) { const lsm_str *key) {
lsm_entry_wrapper *wrapper; lsm_entry_wrapper *wrapper;
LSM_RES(lsm_trie_search((void **)&wrapper, store->trie, key)); LSM_RES(lsm_trie_search((void **)&wrapper, store->trie, key));
// Try to get a write lock on the entry's lock // Try to get a write lock on the entry's lock
@ -90,13 +77,7 @@ lsm_error lsm_store_open_write(lsm_entry_handle **out, lsm_store *store,
} }
lsm_entry_handle *handle; lsm_entry_handle *handle;
lsm_error res = lsm_entry_handle_init(&handle); LSM_RES2(lsm_entry_handle_init(&handle), pthread_rwlock_unlock(&wrapper->lock));
if (res != lsm_error_ok) {
pthread_rwlock_unlock(&wrapper->lock);
return res;
}
handle->wrapper = wrapper; handle->wrapper = wrapper;
handle->store = store; handle->store = store;
@ -115,16 +96,11 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store,
if (lsm_trie_search((void **)&wrapper, store->trie, key) == if (lsm_trie_search((void **)&wrapper, store->trie, key) ==
lsm_error_not_found) { lsm_error_not_found) {
LSM_RES(lsm_entry_wrapper_init(&wrapper)); LSM_RES(lsm_entry_wrapper_init(&wrapper));
pthread_rwlock_wrlock(&wrapper->lock); pthread_rwlock_wrlock(&wrapper->lock);
lsm_error res = lsm_trie_insert(store->trie, key, wrapper); LSM_RES2(lsm_trie_insert(store->trie, key, wrapper),
lsm_entry_wrapper_free(wrapper));
// Check if entry isn't already present in advance
if (res != lsm_error_ok) {
lsm_entry_wrapper_free(wrapper);
return res;
}
} else { } else {
pthread_rwlock_wrlock(&wrapper->lock); pthread_rwlock_wrlock(&wrapper->lock);
@ -136,13 +112,14 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store,
} }
lsm_entry *entry; lsm_entry *entry;
LSM_RES(lsm_entry_init(&entry)); LSM_RES2(lsm_entry_init(&entry), pthread_rwlock_unlock(&wrapper->lock));
entry->key = key; entry->key = key;
wrapper->entry = entry; wrapper->entry = entry;
lsm_entry_handle *handle; lsm_entry_handle *handle;
LSM_RES(lsm_entry_handle_init(&handle)); LSM_RES2(lsm_entry_handle_init(&handle),
pthread_rwlock_unlock(&wrapper->lock));
// No need to set the handle's file, as the entry doesn't have any data yet // No need to set the handle's file, as the entry doesn't have any data yet
handle->wrapper = wrapper; handle->wrapper = wrapper;
@ -160,7 +137,7 @@ void lsm_entry_remove(lsm_entry_handle *handle) {
handle->states |= lsm_entry_handle_state_removed; handle->states |= lsm_entry_handle_state_removed;
} }
lsm_error lsm_entry_data_append(lsm_entry_handle *handle, lsm_str *data) { lsm_error lsm_entry_data_append(lsm_entry_handle *handle, const lsm_str *data) {
if (lsm_str_len(data) == 0) { if (lsm_str_len(data) == 0) {
return lsm_error_ok; return lsm_error_ok;
} }

View File

@ -110,7 +110,7 @@ void lsm_str_free(lsm_str *str) {
uint64_t lsm_str_len(const lsm_str *str) { return str->len; } uint64_t lsm_str_len(const lsm_str *str) { return str->len; }
const char *lsm_str_ptr(lsm_str *str) { const char *lsm_str_ptr(const lsm_str *str) {
if (str->len <= 8) { if (str->len <= 8) {
return str->data.val; return str->data.val;
} else { } else {
@ -118,7 +118,7 @@ const char *lsm_str_ptr(lsm_str *str) {
} }
} }
char lsm_str_char(lsm_str *str, uint64_t index) { char lsm_str_char(const lsm_str *str, uint64_t index) {
if (str->len <= 8) { if (str->len <= 8) {
return str->data.val[index]; return str->data.val[index];
} else { } else {
@ -126,7 +126,7 @@ char lsm_str_char(lsm_str *str, uint64_t index) {
} }
} }
lsm_error lsm_str_substr(lsm_str *out, lsm_str *str, uint64_t start, lsm_error lsm_str_substr(lsm_str *out, const lsm_str *str, uint64_t start,
uint64_t end) { uint64_t end) {
// A substring that starts past the string's length will have length 0 // A substring that starts past the string's length will have length 0
uint64_t len = start < str->len ? end - start : 0; uint64_t len = start < str->len ? end - start : 0;
@ -153,7 +153,7 @@ lsm_error lsm_str_substr(lsm_str *out, lsm_str *str, uint64_t start,
return lsm_error_ok; return lsm_error_ok;
} }
uint64_t lsm_str_cmp(lsm_str *s1, uint64_t s1_offset, lsm_str *s2, uint64_t lsm_str_cmp(const lsm_str *s1, uint64_t s1_offset, const lsm_str *s2,
uint64_t s2_offset) { uint64_t s2_offset) {
uint64_t index = 0; uint64_t index = 0;
uint64_t max_len = MIN(s1->len - s1_offset, s2->len - s2_offset); uint64_t max_len = MIN(s1->len - s1_offset, s2->len - s2_offset);
@ -207,7 +207,7 @@ lsm_error lsm_str_split(lsm_str *s, lsm_str *s2, uint64_t index) {
return lsm_str_truncate(s, index); return lsm_str_truncate(s, index);
} }
bool lsm_str_eq(lsm_str *s1, lsm_str *s2) { bool lsm_str_eq(const lsm_str *s1, const lsm_str *s2) {
if (s1->len != s2->len) { if (s1->len != s2->len) {
return false; return false;
} }

View File

@ -45,7 +45,7 @@ lsm_error lsm_trie_init(lsm_trie **ptr) {
uint64_t lsm_trie_size(const lsm_trie *trie) { return trie->size; } uint64_t lsm_trie_size(const lsm_trie *trie) { return trie->size; }
lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data) { lsm_error lsm_trie_insert(lsm_trie *trie, const lsm_str *key, void *data) {
// NULL is not allowed as a data value, as it's used to indicate a lack of // NULL is not allowed as a data value, as it's used to indicate a lack of
// data // data
if (data == NULL) { if (data == NULL) {
@ -78,18 +78,22 @@ lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data) {
// here // here
if (res == lsm_error_not_found) { if (res == lsm_error_not_found) {
lsm_trie_node *new_node; lsm_trie_node *new_node;
res = lsm_trie_node_init(&new_node); LSM_RES(lsm_trie_node_init(&new_node));
new_node->data = data;
lsm_str_substr(&new_node->skip, key, index + 1, key_len);
res = lsm_bt_insert(&node->bt, c, new_node);
if (res != lsm_error_ok) { if (res != lsm_error_ok) {
lsm_trie_node_free(new_node);
return res; return res;
} }
new_node->data = data;
trie->size++; trie->size++;
lsm_str_substr(&new_node->skip, key, index + 1, key_len); return lsm_error_ok;
return lsm_bt_insert(&node->bt, c, new_node);
} }
index++; index++;
@ -101,11 +105,7 @@ lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data) {
if (cmp < lsm_str_len(&next_node->skip)) { if (cmp < lsm_str_len(&next_node->skip)) {
lsm_trie_node *split_node; lsm_trie_node *split_node;
res = lsm_trie_node_init(&split_node); LSM_RES(lsm_trie_node_init(&split_node));
if (res != lsm_error_ok) {
return res;
}
// split_node replaces the original node as the new child node // split_node replaces the original node as the new child node
// bottom_node here is always the same value as next_node // bottom_node here is always the same value as next_node
@ -118,7 +118,7 @@ lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data) {
// split_node's skip has not been initialized yet, so we can simply // split_node's skip has not been initialized yet, so we can simply
// overwrite it with bottom_node's skip // overwrite it with bottom_node's skip
split_node->skip = next_node->skip; split_node->skip = bottom_node->skip;
// The new node splits the edge into two parts, so the new split node will // The new node splits the edge into two parts, so the new split node will
// have the first part of the skip (minus the one character) as its // have the first part of the skip (minus the one character) as its
@ -148,7 +148,8 @@ lsm_error lsm_trie_insert(lsm_trie *trie, lsm_str *key, void *data) {
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_trie_search(void **out, lsm_trie *trie, lsm_str *key) { lsm_error lsm_trie_search(void **out, const lsm_trie *trie,
const lsm_str *key) {
uint64_t key_len = lsm_str_len(key); uint64_t key_len = lsm_str_len(key);
if (key_len == 0) { if (key_len == 0) {
@ -199,13 +200,13 @@ lsm_error lsm_trie_search(void **out, lsm_trie *trie, lsm_str *key) {
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_trie_remove(void **data, lsm_trie *trie, lsm_str *key) { lsm_error lsm_trie_remove(void **out, lsm_trie *trie, const lsm_str *key) {
uint64_t key_len = lsm_str_len(key); uint64_t key_len = lsm_str_len(key);
if (key_len == 0) { if (key_len == 0) {
if (trie->root->data != NULL) { if (trie->root->data != NULL) {
if (data != NULL) { if (out != NULL) {
*data = trie->root->data; *out = trie->root->data;
} }
trie->root->data = NULL; trie->root->data = NULL;
@ -250,8 +251,8 @@ lsm_error lsm_trie_remove(void **data, lsm_trie *trie, lsm_str *key) {
return lsm_error_not_found; return lsm_error_not_found;
} }
if (data != NULL) { if (out != NULL) {
*data = child->data; *out = child->data;
} }
child->data = NULL; child->data = NULL;