feat(lsm): store iterators
parent
f4d711365d
commit
222b277eef
|
@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
* LSM
|
* LSM
|
||||||
* Binary tree iterators
|
* Binary tree iterators
|
||||||
* Trie iterators
|
* Trie iterators
|
||||||
|
* Store iterators
|
||||||
|
|
||||||
## Removed
|
## Removed
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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
|
#endif
|
||||||
|
|
|
@ -34,6 +34,11 @@ typedef struct lsm_entry {
|
||||||
uint64_t idx_file_offset;
|
uint64_t idx_file_offset;
|
||||||
} lsm_entry;
|
} lsm_entry;
|
||||||
|
|
||||||
|
struct lsm_store_iterator {
|
||||||
|
lsm_trie_iterator *iter;
|
||||||
|
lsm_store *store;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate and initialize a new lsm_entry object.
|
* Allocate and initialize a new lsm_entry object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue