feat(lsm): store iterators

ltm
Jef Roosens 2023-12-23 14:29:33 +01:00
parent f4d711365d
commit 222b277eef
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 100 additions and 0 deletions

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* LSM
* Binary tree iterators
* Trie iterators
* Store iterators
## Removed

View File

@ -228,4 +228,40 @@ lsm_error lsm_entry_data_read(uint64_t *out, char *buf,
*/
uint64_t lsm_entry_data_len(lsm_entry_handle *handle);
/**
* Represents an in-flight iterator over an LSM store.
*/
typedef struct lsm_store_iterator lsm_store_iterator;
/**
* Initialize an iterator to iterate over all entries with keys starting
* with the given prefix.
*
* @param out pointer to store iterator pointer in
* @param trie trie to iterate
* @param prefix prefix of the keys; a zero-length string means iterating over
* the entire trie; NULL is interpreted as a zero-length string
*/
lsm_error lsm_store_iter(lsm_store_iterator **out, lsm_store *store,
const lsm_str *prefix);
/**
* Advance the iterator, returning a read handle to the next entry. The caller
* is responsible for closing this handle.
*/
lsm_error lsm_store_iter_next_read(lsm_entry_handle **out,
lsm_store_iterator *iter);
/**
* Advance the iterator, returning a write handle to the next entry. The caller
* is responsible for closing this handle.
*/
/* lsm_error lsm_store_iter_next_write(lsm_entry_handle **out,
* lsm_store_iterator *iter); */
/**
* Free the given iterator.
*/
void lsm_store_iter_free(lsm_store_iterator *iter);
#endif

View File

@ -34,6 +34,11 @@ typedef struct lsm_entry {
uint64_t idx_file_offset;
} lsm_entry;
struct lsm_store_iterator {
lsm_trie_iterator *iter;
lsm_store *store;
};
/**
* Allocate and initialize a new lsm_entry object.
*

View File

@ -0,0 +1,58 @@
#include "lsm/store.h"
#include "lsm/store_internal.h"
lsm_error lsm_store_iter(lsm_store_iterator **out, lsm_store *store,
const lsm_str *prefix) {
lsm_trie_iterator *trie_iter;
LSM_RES(lsm_trie_iter(&trie_iter, store->trie, prefix));
lsm_store_iterator *iter = calloc(1, sizeof(lsm_store_iterator));
if (iter == NULL) {
lsm_trie_iter_free(trie_iter);
return lsm_error_failed_alloc;
}
iter->iter = trie_iter;
iter->store = store;
*out = iter;
return lsm_error_ok;
}
lsm_error lsm_store_iter_next_read(lsm_entry_handle **out,
lsm_store_iterator *iter) {
lsm_entry_wrapper *wrapper = NULL;
// Traverse through the trie until a node is found with a filled data field
do {
// Exits function if iterator is done
LSM_RES(lsm_trie_iter_next((void **)&wrapper, iter->iter));
// TODO error handling?
pthread_rwlock_rdlock(&wrapper->lock);
if (wrapper->entry == NULL) {
pthread_rwlock_unlock(&wrapper->lock);
wrapper = NULL;
}
} while (wrapper == NULL);
lsm_entry_handle *handle;
LSM_RES2(lsm_entry_handle_init(&handle),
pthread_rwlock_unlock(&wrapper->lock));
handle->wrapper = wrapper;
handle->store = iter->store;
*out = handle;
return lsm_error_ok;
}
void lsm_store_iter_free(lsm_store_iterator *iter) {
lsm_trie_iter_free(iter->iter);
free(iter);
}