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