feat(lsm): add some attr & data support functions; fix str bug

lsm
Jef Roosens 2023-11-03 13:23:46 +01:00
parent fbf6557c05
commit 8b6d1f6e91
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 91 additions and 11 deletions

View File

@ -44,6 +44,16 @@ bool lsm_entry_attr_present(lsm_entry_handle *handle, lsm_attr_type type);
lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry_handle *handle, lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry_handle *handle,
lsm_attr_type type); lsm_attr_type type);
/**
* Convenience wrapper around `lsm_entry_attr_get` that can be used if we know
* beforehand the attribute value is a 64-bit number.
*
* @param out where to store attribute data
* @param entry entry to search for
* @param type type of attribute to return
*/
lsm_error lsm_entry_attr_get_num(uint64_t *out, lsm_entry_handle *handle, lsm_attr_type type);
/** /**
* Add a new attribute to the entry. * Add a new attribute to the entry.
* *
@ -54,6 +64,16 @@ lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry_handle *handle,
lsm_error lsm_entry_attr_insert(lsm_entry_handle *handle, lsm_attr_type type, lsm_error lsm_entry_attr_insert(lsm_entry_handle *handle, lsm_attr_type type,
lsm_str *data); lsm_str *data);
/**
* Convenience wrapper around `lsm_entry_attr_insert` that can be used if the
* data to be stored is a 64-bit number.
*
* @param entry entry to modify
* @param type type of attribute to add
* @param data data of attribute
*/
lsm_error lsm_entry_attr_insert_num(lsm_entry_handle *handle, lsm_attr_type type, uint64_t data);
/** /**
* Remove an atribute from the given entry, if present. * Remove an atribute from the given entry, if present.
* *
@ -151,6 +171,16 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store,
lsm_error lsm_entry_data_append(lsm_store *store, lsm_entry_handle *handle, lsm_error lsm_entry_data_append(lsm_store *store, lsm_entry_handle *handle,
lsm_str *data); lsm_str *data);
/**
* Same as `lsm_entry_data_append`, except that it takes a direct char array.
*
* @param store store the entry is stored in
* @param entry entry to append data to
* @param data data to append
* @param len length of data array
*/
lsm_error lsm_entry_data_append_raw(lsm_store *store, lsm_entry_handle *handle, char *data, uint64_t len);
/** /**
* Read a number of bytes from the entry's data field. The position from which * Read a number of bytes from the entry's data field. The position from which
* data is read is dependent on previous read calls. * data is read is dependent on previous read calls.
@ -163,4 +193,12 @@ lsm_error lsm_entry_data_append(lsm_store *store, lsm_entry_handle *handle,
lsm_error lsm_entry_data_read(uint64_t *out, char *buf, lsm_error lsm_entry_data_read(uint64_t *out, char *buf,
lsm_entry_handle *handle, uint64_t len); lsm_entry_handle *handle, uint64_t len);
/**
* Return the length of the entry's data.
*
* @param handle entry handle to return length for
* @return length of the data
*/
uint64_t lsm_entry_data_len(lsm_entry_handle *handle);
#endif #endif

View File

@ -153,6 +153,10 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store,
lsm_str *key) { lsm_str *key) {
// TODO what happens when two inserts to the same key happen at the same time? // TODO what happens when two inserts to the same key happen at the same time?
lsm_entry_wrapper *wrapper; lsm_entry_wrapper *wrapper;
// If a key was previously removed from the trie, the wrapper will already be
// present in the trie
if (lsm_trie_search((void **)&wrapper, store->trie, key) == 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);
@ -164,6 +168,16 @@ lsm_error lsm_store_insert(lsm_entry_handle **out, lsm_store *store,
return res; return res;
} }
} else {
pthread_rwlock_wrlock(&wrapper->lock);
if (wrapper->entry != NULL) {
pthread_rwlock_unlock(&wrapper->lock);
return lsm_error_already_present;
}
}
lsm_entry *entry; lsm_entry *entry;
LSM_RES(lsm_entry_init(&entry)); LSM_RES(lsm_entry_init(&entry));

View File

@ -5,6 +5,7 @@
#include "lsm.h" #include "lsm.h"
#include "lsm/store_internal.h" #include "lsm/store_internal.h"
#include "lsm/str.h"
lsm_error lsm_entry_init(lsm_entry **ptr) { lsm_error lsm_entry_init(lsm_entry **ptr) {
lsm_entry *entry = calloc(1, sizeof(lsm_entry)); lsm_entry *entry = calloc(1, sizeof(lsm_entry));
@ -77,6 +78,22 @@ lsm_error lsm_entry_attr_get(lsm_str **out, lsm_entry_handle *handle,
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_entry_attr_get_num(uint64_t *out, lsm_entry_handle *handle, lsm_attr_type type) {
lsm_str *s;
LSM_RES(lsm_entry_attr_get(&s, handle, type));
uint64_t num;
for (uint8_t i = 0; i < sizeof(uint64_t) / sizeof(char); i++) {
((char *)&num)[i] = lsm_str_char(s, i);
}
*out = num;
return lsm_error_ok;
}
lsm_error lsm_entry_attr_remove(lsm_str **out, lsm_entry_handle *handle, lsm_error lsm_entry_attr_remove(lsm_str **out, lsm_entry_handle *handle,
lsm_attr_type type) { lsm_attr_type type) {
if (!lsm_entry_attr_present(handle, type)) { if (!lsm_entry_attr_present(handle, type)) {
@ -149,3 +166,14 @@ lsm_error lsm_entry_attr_insert(lsm_entry_handle *handle, lsm_attr_type type,
return lsm_error_ok; return lsm_error_ok;
} }
lsm_error lsm_entry_attr_insert_num(lsm_entry_handle *handle, lsm_attr_type type, uint64_t data) {
lsm_str *s;
LSM_RES(lsm_str_init_copy_n(&s, (char *)&data, sizeof(uint64_t) / sizeof(char)));
return lsm_entry_attr_insert(handle, type, s);
}
uint64_t lsm_entry_data_len(lsm_entry_handle *handle) {
return handle->wrapper->entry->data.len;
}

View File

@ -77,16 +77,16 @@ lsm_error lsm_str_overwrite_copy(lsm_str *str, char *s) {
} }
lsm_error lsm_str_overwrite_copy_n(lsm_str *str, char *s, uint64_t len) { lsm_error lsm_str_overwrite_copy_n(lsm_str *str, char *s, uint64_t len) {
if (str->len <= 8) { if (len <= 8) {
memcpy(str->data.val, s, str->len); memcpy(str->data.val, s, len);
} else { } else {
char *buf = malloc(str->len * sizeof(char)); char *buf = malloc(len * sizeof(char));
if (buf == NULL) { if (buf == NULL) {
return lsm_error_failed_alloc; return lsm_error_failed_alloc;
} }
memcpy(buf, s, str->len); memcpy(buf, s, len);
str->data.ptr = buf; str->data.ptr = buf;
} }