#ifndef CACHE_H
#define CACHE_H
#include <sys/types.h>
/*
* The interface to the internal caching mechanism.
*
* This presents a pretty generic API, which allows the actual implementation to change, or to compare multiple
* different implementations.
*
*/
/*
* The handle used to access the global cache.
*/
struct cache;
/*
* A cache request/operation.
*/
struct cache_req;
/*
* The actual implementation of the cache.
*/
struct cache_engine;
/*
* What we use as keys in the cache. Key is a pointer to an arbitrary char buffer, length is the size of the key
* in bytes. If this is given as zero, it will be calcuated using strlen(). Zero-length keys are invalid.
*/
struct cache_key {
char *buf;
size_t length;
};
/*
* The various states that a cache request can be in
*/
enum cache_req_state {
CACHE_STATE_INVALID,
CACHE_STATE_LOOKUP,
CACHE_STATE_WRITE_BEGIN,
CACHE_STATE_READ_BEGIN,
CACHE_STATE_WRITE,
CACHE_STATE_WRITE_PAUSE,
CACHE_STATE_READ,
CACHE_STATE_DONE,
CACHE_STATE_ERROR,
};
/*
/ *
* Transitions between states
* /
enum cache_req_event {
// LOOKUP -> OPEN
CACHE_EVENT_HIT,
CACHE_EVENT_MISS,
// OPEN -> WRITE
CACHE_EVENT_BEGIN_WRITE,
// OPEN -> READ
CACHE_EVENT_BEGIN_READ,
// WRITE -> PAUSE_WRITE
CACHE_EVENT_PAUSE_WRITE,
// PAUSE_WRITE -> WRITE
CACHE_EVENT_RESUME_WRITE,
// READ -> READ
CACHE_EVENT_DATA_AVAILABLE,
// READ -> DONE
CACHE_EVENT_DONE,
// * -> ERROR
CACHE_EVENT_ERROR,
};
*/
/*
* The callback used for cache_reqs
*/
//typedef int (*cache_callback) (struct cache_req *, enum cache_req_event, void *arg);
typedef int (*cache_callback) (struct cache_req *, void *arg);
/*
* Open up a cache using the given engine (which can be configured with engine-specific params).
*/
struct cache *cache_open (struct cache_engine *engine);
/*
* Create a new request. The given callback function will be called at the various stages in the request, and can then
* drive the request forward.
*/
struct cache_req *cache_req (struct cache *cache, const struct cache_key *key, cache_callback cb_func, void *cb_data);
/*
* Get the request's state.
*/
enum cache_req_state cache_req_state (struct cache_req *req);
/*
* Get the rquest's key
*/
const struct cache_key *cache_req_key (struct cache_req *req);
/*
* Get information about the amount of data in this cache entry.
* size - the total size of the cache entry. -1 if unknown
* offset - how many bytes of data the cache entry contains
* available - how many unread bytes are available
*/
void cache_req_available (struct cache_req *req, ssize_t *size, ssize_t *offset, ssize_t *available);
/*
* Prepare this cache req for writing in the data. Hint, if nonzero, is used to pre-allocate resources for the entry.
*/
int cache_req_begin_write(struct cache_req *req, size_t hint);
/*
* Add some data into this cache entry, reading from the given fd. This is only valid for cache_req's in
* CACHE_REQ_WRITE mode.
*
* If you know the amount of data that should be pushed, you can supply it in size. If size is given as 0, all
* available data will be consumed. Size will be updated to the number of bytes pushed into the cache.
*
* (size == 0) is valid if req is in the WRITE_PAUSE state (either before or after the call).
*/
int cache_req_push (struct cache_req *req, int fd, size_t *size);
/*
* Get some data from this cache entry, writing it into the given fd. This is valid for all cache_req's in
* CACHE_REQ_READ and CACHE_REQ_WRITE mode.
*
* If the value of size is given (nonzero), then the given amount of data will be written to the fd from the cache.
* If the cache contains less data than given, this is an error. If the value of size is zero, as much data as possible
* will be written to the fd. Size will be updated to the number of bytes pulled from the cache.
*/
int cache_req_pull (struct cache_req *req, int fd, size_t *size);
/*
* Abort the given cache request (external failure). This is only needed for CACHE_REQ_WRITE requests, and is invalid
* for other requests. Any dependant cache requests will fail.
*/
void cache_req_abort (struct cache_req *req);
/*
* Indicate that the given cache write request is complete. This is only valid for CACHE_REQ_WRITE requests, and is
* invalid for other requests. Any dependant cache requests will complete.
*/
int cache_req_done (struct cache_req *req);
/*
* Release the given cache request. Only valid after calling req_abort/req_done, or getting EVENT_DONE/EVENT_ERROR.
*/
void cache_req_release (struct cache_req *req);
#endif /* CACHE_H */