165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
#ifndef LSM_STORE_INTERNAL
|
|
#define LSM_STORE_INTERNAL
|
|
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
|
|
#include "lsm/store.h"
|
|
#include "lsm/str_internal.h"
|
|
#include "lsm/trie.h"
|
|
|
|
#define LSM_DB_FILE_NAME "lsm.db"
|
|
#define LSM_IDX_FILE_NAME "lsm.idx"
|
|
#define LSM_DATA_FILE_SUFFIX ".data"
|
|
|
|
typedef struct lsm_attr {
|
|
uint8_t type;
|
|
lsm_str *str;
|
|
} lsm_attr;
|
|
|
|
/**
|
|
* An entry inside an LSM store.
|
|
*
|
|
* Each entry consists of the key it's stored behind, zero or more attributes
|
|
* (metadata) and a data file.
|
|
*/
|
|
typedef struct lsm_entry {
|
|
lsm_str *key;
|
|
struct {
|
|
uint64_t bitmap[4];
|
|
uint8_t count;
|
|
lsm_attr *items;
|
|
} attrs;
|
|
uint64_t data_len;
|
|
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.
|
|
*
|
|
* @param ptr where to store newly allocated pointer
|
|
*/
|
|
lsm_error lsm_entry_init(lsm_entry **ptr);
|
|
|
|
/**
|
|
* Deallocate an existing entry
|
|
*
|
|
* @param entry pointer to entry
|
|
*/
|
|
void lsm_entry_free(lsm_entry *entry);
|
|
|
|
/**
|
|
* Deallocate an existing lsm_entry object.
|
|
*
|
|
* @param entry object to deallocate
|
|
*/
|
|
void lsm_entry_free(lsm_entry *entry);
|
|
|
|
typedef struct lsm_entry_wrapper {
|
|
pthread_rwlock_t lock;
|
|
lsm_entry *entry;
|
|
} lsm_entry_wrapper;
|
|
|
|
lsm_error lsm_entry_wrapper_init(lsm_entry_wrapper **ptr);
|
|
void lsm_entry_wrapper_free(lsm_entry_wrapper *wrapper);
|
|
|
|
typedef enum lsm_entry_handle_state : uint8_t {
|
|
lsm_entry_handle_state_new = 1 << 0,
|
|
lsm_entry_handle_state_updated = 1 << 1,
|
|
lsm_entry_handle_state_removed = 1 << 2,
|
|
} lsm_entry_handle_state;
|
|
|
|
struct lsm_entry_handle {
|
|
lsm_entry_wrapper *wrapper;
|
|
lsm_store *store;
|
|
// Either read or append, depending on how it was opened
|
|
FILE *f;
|
|
// Current position in the file pointer
|
|
uint64_t pos;
|
|
// Required to determine in what way the database files need to be synced
|
|
uint64_t states;
|
|
};
|
|
|
|
lsm_error lsm_entry_handle_init(lsm_entry_handle **out);
|
|
|
|
struct lsm_store {
|
|
lsm_trie *trie;
|
|
lsm_str *data_path;
|
|
|
|
struct {
|
|
FILE *f;
|
|
uint64_t size;
|
|
pthread_mutex_t lock;
|
|
} db;
|
|
|
|
struct {
|
|
FILE *f;
|
|
uint64_t size;
|
|
uint64_t block_count;
|
|
pthread_mutex_t lock;
|
|
} idx;
|
|
};
|
|
|
|
/**
|
|
* Read in the database and construct the in-memory trie index. This function
|
|
* assumes the provided store is a newly initialized empty store with the
|
|
* database files opened.
|
|
*
|
|
* @param store store to read
|
|
*/
|
|
lsm_error lsm_store_load_db(lsm_store *store);
|
|
|
|
/**
|
|
* Write a new insert to the database.
|
|
*
|
|
* @param handle handle to added entry
|
|
*/
|
|
lsm_error lsm_entry_disk_insert(lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Remove an entry from the database.
|
|
*
|
|
* @param handle handle to the removed entry
|
|
*/
|
|
lsm_error lsm_entry_disk_remove(lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Update an existing entry already in the store.
|
|
*
|
|
* @param handle to updated entry
|
|
*/
|
|
lsm_error lsm_entry_disk_update(lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Return the length of the path to this entry's data file
|
|
*/
|
|
uint64_t lsm_entry_data_path_len(const lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Fill in the entry's data file path in the provided buffer. Use
|
|
* `lsm_entry_data_path_len` to allocate an appropriately-sized buffer
|
|
*/
|
|
void lsm_entry_data_path(char *buf, const lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Open the entry's data file for reading
|
|
*
|
|
* @param handle handle to the entry
|
|
*/
|
|
lsm_error lsm_entry_data_open_read(lsm_entry_handle *handle);
|
|
|
|
/**
|
|
* Open the entry's data file for writing. The file and all subdirectories in
|
|
* the data dir are created as needed.
|
|
*
|
|
* @param handle handle to the entry
|
|
*/
|
|
lsm_error lsm_entry_data_open_write(lsm_entry_handle *handle);
|
|
|
|
#endif
|