|
Packit Service |
584ef9 |
#ifndef EXTSTORE_H
|
|
Packit Service |
584ef9 |
#define EXTSTORE_H
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
/* A safe-to-read dataset for determining compaction.
|
|
Packit Service |
584ef9 |
* id is the array index.
|
|
Packit Service |
584ef9 |
*/
|
|
Packit Service |
584ef9 |
struct extstore_page_data {
|
|
Packit Service |
584ef9 |
uint64_t version;
|
|
Packit Service |
584ef9 |
uint64_t bytes_used;
|
|
Packit Service |
584ef9 |
unsigned int bucket;
|
|
Packit Service |
584ef9 |
unsigned int free_bucket;
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
/* Pages can have objects deleted from them at any time. This creates holes
|
|
Packit Service |
584ef9 |
* that can't be reused until the page is either evicted or all objects are
|
|
Packit Service |
584ef9 |
* deleted.
|
|
Packit Service |
584ef9 |
* bytes_fragmented is the total bytes for all of these holes.
|
|
Packit Service |
584ef9 |
* It is the size of all used pages minus each page's bytes_used value.
|
|
Packit Service |
584ef9 |
*/
|
|
Packit Service |
584ef9 |
struct extstore_stats {
|
|
Packit Service |
584ef9 |
uint64_t page_allocs;
|
|
Packit Service |
584ef9 |
uint64_t page_count; /* total page count */
|
|
Packit Service |
584ef9 |
uint64_t page_evictions;
|
|
Packit Service |
584ef9 |
uint64_t page_reclaims;
|
|
Packit Service |
584ef9 |
uint64_t page_size; /* size in bytes per page (supplied by caller) */
|
|
Packit Service |
584ef9 |
uint64_t pages_free; /* currently unallocated/unused pages */
|
|
Packit Service |
584ef9 |
uint64_t pages_used;
|
|
Packit Service |
584ef9 |
uint64_t objects_evicted;
|
|
Packit Service |
584ef9 |
uint64_t objects_read;
|
|
Packit Service |
584ef9 |
uint64_t objects_written;
|
|
Packit Service |
584ef9 |
uint64_t objects_used; /* total number of objects stored */
|
|
Packit Service |
584ef9 |
uint64_t bytes_evicted;
|
|
Packit Service |
584ef9 |
uint64_t bytes_written;
|
|
Packit Service |
584ef9 |
uint64_t bytes_read; /* wbuf - read -> bytes read from storage */
|
|
Packit Service |
584ef9 |
uint64_t bytes_used; /* total number of bytes stored */
|
|
Packit Service |
584ef9 |
uint64_t bytes_fragmented; /* see above comment */
|
|
Packit Service |
584ef9 |
uint64_t io_queue;
|
|
Packit Service |
584ef9 |
struct extstore_page_data *page_data;
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
// TODO: Temporary configuration structure. A "real" library should have an
|
|
Packit Service |
584ef9 |
// extstore_set(enum, void *ptr) which hides the implementation.
|
|
Packit Service |
584ef9 |
// this is plenty for quick development.
|
|
Packit Service |
584ef9 |
struct extstore_conf {
|
|
Packit Service |
584ef9 |
unsigned int page_size; // ideally 64-256M in size
|
|
Packit Service |
584ef9 |
unsigned int page_count;
|
|
Packit Service |
584ef9 |
unsigned int page_buckets; // number of different writeable pages
|
|
Packit Service |
584ef9 |
unsigned int free_page_buckets; // buckets of dedicated pages (see code)
|
|
Packit Service |
584ef9 |
unsigned int wbuf_size; // must divide cleanly into page_size
|
|
Packit Service |
584ef9 |
unsigned int wbuf_count; // this might get locked to "2 per active page"
|
|
Packit Service |
584ef9 |
unsigned int io_threadcount;
|
|
Packit Service |
584ef9 |
unsigned int io_depth; // with normal I/O, hits locks less. req'd for AIO
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
struct extstore_conf_file {
|
|
Packit Service |
584ef9 |
unsigned int page_count;
|
|
Packit Service |
584ef9 |
char *file;
|
|
Packit Service |
584ef9 |
int fd; // internal usage
|
|
Packit Service |
584ef9 |
uint64_t offset; // internal usage
|
|
Packit Service |
584ef9 |
unsigned int bucket; // free page bucket
|
|
Packit Service |
584ef9 |
unsigned int free_bucket; // specialized free bucket
|
|
Packit Service |
584ef9 |
struct extstore_conf_file *next;
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
enum obj_io_mode {
|
|
Packit Service |
584ef9 |
OBJ_IO_READ = 0,
|
|
Packit Service |
584ef9 |
OBJ_IO_WRITE,
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
typedef struct _obj_io obj_io;
|
|
Packit Service |
584ef9 |
typedef void (*obj_io_cb)(void *e, obj_io *io, int ret);
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
/* An object for both reads and writes to the storage engine.
|
|
Packit Service |
584ef9 |
* Once an IO is submitted, ->next may be changed by the IO thread. It is not
|
|
Packit Service |
584ef9 |
* safe to further modify the IO stack until the entire request is completed.
|
|
Packit Service |
584ef9 |
*/
|
|
Packit Service |
584ef9 |
struct _obj_io {
|
|
Packit Service |
584ef9 |
void *data; /* user supplied data pointer */
|
|
Packit Service |
584ef9 |
struct _obj_io *next;
|
|
Packit Service |
584ef9 |
char *buf; /* buffer of data to read or write to */
|
|
Packit Service |
584ef9 |
struct iovec *iov; /* alternatively, use this iovec */
|
|
Packit Service |
584ef9 |
unsigned int iovcnt; /* number of IOV's */
|
|
Packit Service |
584ef9 |
unsigned int page_version; /* page version for read mode */
|
|
Packit Service |
584ef9 |
unsigned int len; /* for both modes */
|
|
Packit Service |
584ef9 |
unsigned int offset; /* for read mode */
|
|
Packit Service |
584ef9 |
unsigned short page_id; /* for read mode */
|
|
Packit Service |
584ef9 |
enum obj_io_mode mode;
|
|
Packit Service |
584ef9 |
/* callback pointers? */
|
|
Packit Service |
584ef9 |
obj_io_cb cb;
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
enum extstore_res {
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_BAD_WBUF_SIZE = 1,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_NEED_MORE_WBUF,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_NEED_MORE_BUCKETS,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_PAGE_WBUF_ALIGNMENT,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_TOO_MANY_PAGES,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_OOM,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_OPEN_FAIL,
|
|
Packit Service |
584ef9 |
EXTSTORE_INIT_THREAD_FAIL
|
|
Packit Service |
584ef9 |
};
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
const char *extstore_err(enum extstore_res res);
|
|
Packit Service |
584ef9 |
void *extstore_init(struct extstore_conf_file *fh, struct extstore_conf *cf, enum extstore_res *res);
|
|
Packit Service |
584ef9 |
int extstore_write_request(void *ptr, unsigned int bucket, unsigned int free_bucket, obj_io *io);
|
|
Packit Service |
584ef9 |
void extstore_write(void *ptr, obj_io *io);
|
|
Packit Service |
584ef9 |
int extstore_submit(void *ptr, obj_io *io);
|
|
Packit Service |
584ef9 |
/* count are the number of objects being removed, bytes are the original
|
|
Packit Service |
584ef9 |
* length of those objects. Bytes is optional but you can't track
|
|
Packit Service |
584ef9 |
* fragmentation without it.
|
|
Packit Service |
584ef9 |
*/
|
|
Packit Service |
584ef9 |
int extstore_check(void *ptr, unsigned int page_id, uint64_t page_version);
|
|
Packit Service |
584ef9 |
int extstore_delete(void *ptr, unsigned int page_id, uint64_t page_version, unsigned int count, unsigned int bytes);
|
|
Packit Service |
584ef9 |
void extstore_get_stats(void *ptr, struct extstore_stats *st);
|
|
Packit Service |
584ef9 |
/* add page data array to a stats structure.
|
|
Packit Service |
584ef9 |
* caller must allocate its stats.page_data memory first.
|
|
Packit Service |
584ef9 |
*/
|
|
Packit Service |
584ef9 |
void extstore_get_page_data(void *ptr, struct extstore_stats *st);
|
|
Packit Service |
584ef9 |
void extstore_run_maint(void *ptr);
|
|
Packit Service |
584ef9 |
void extstore_close_page(void *ptr, unsigned int page_id, uint64_t page_version);
|
|
Packit Service |
584ef9 |
|
|
Packit Service |
584ef9 |
#endif
|