2007-07-13 19:37:47 +00:00
|
|
|
#ifndef CACHETABLE_H
|
|
|
|
#define CACHETABLE_H
|
2007-09-21 17:55:49 +00:00
|
|
|
|
2008-01-24 15:10:32 +00:00
|
|
|
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
|
2007-11-29 14:18:54 +00:00
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
#include <fcntl.h>
|
2007-11-14 17:58:38 +00:00
|
|
|
#include "brttypes.h"
|
2013-04-16 23:57:38 -04:00
|
|
|
#include "workqueue.h"
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Maintain a cache mapping from cachekeys to values (void*)
|
|
|
|
// Some of the keys can be pinned. Don't pin too many or for too long.
|
|
|
|
// If the cachetable is too full, it will call the flush_callback() function with the key, the value, and the otherargs
|
|
|
|
// and then remove the key-value pair from the cache.
|
|
|
|
// The callback won't be any of the currently pinned keys.
|
|
|
|
// Also when flushing an object, the cachetable drops all references to it,
|
|
|
|
// so you may need to free() it.
|
|
|
|
// Note: The cachetable should use a common pool of memory, flushing things across cachetables.
|
|
|
|
// (The first implementation doesn't)
|
|
|
|
// If you pin something twice, you must unpin it twice.
|
|
|
|
// table_size is the initial size of the cache table hash table (in number of entries)
|
|
|
|
// size limit is the upper bound of the sum of size of the entries in the cache table (total number of bytes)
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
typedef BLOCKNUM CACHEKEY;
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2007-11-19 23:47:44 +00:00
|
|
|
int toku_create_cachetable(CACHETABLE */*result*/, long size_limit, LSN initial_lsn, TOKULOGGER);
|
2013-04-16 23:57:18 -04:00
|
|
|
// Create a new cachetable.
|
|
|
|
// Effects: a new cachetable is created and initialized.
|
|
|
|
// The cachetable pointer is stored into result.
|
|
|
|
// The sum of the sizes of the memory objects is set to size_limit, in whatever
|
|
|
|
// units make sense to the user of the cachetable.
|
|
|
|
// Returns: If success, returns 0 and result points to the new cachetable. Otherwise,
|
|
|
|
// returns an error number.
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:17 -04:00
|
|
|
// What is the cachefile that goes with a particular filenum?
|
|
|
|
// During a transaction, we cannot reuse a filenum.
|
|
|
|
int toku_cachefile_of_filenum (CACHETABLE t, FILENUM filenum, CACHEFILE *cf);
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Checkpoint the cachetable.
|
|
|
|
// Effects: ?
|
2013-04-16 23:57:17 -04:00
|
|
|
int toku_cachetable_checkpoint (CACHETABLE ct);
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Close the cachetable.
|
|
|
|
// Effects: All of the memory objects are flushed to disk, and the cachetable is
|
|
|
|
// destroyed.
|
2013-04-16 23:57:17 -04:00
|
|
|
int toku_cachetable_close (CACHETABLE*); /* Flushes everything to disk, and destroys the cachetable. */
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Open a file and bind the file to a new cachefile object.
|
2008-04-09 02:45:27 +00:00
|
|
|
int toku_cachetable_openf (CACHEFILE *,CACHETABLE, const char */*fname*/, int flags, mode_t mode);
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Bind a file to a new cachefile object.
|
2008-04-17 03:11:55 +00:00
|
|
|
int toku_cachetable_openfd (CACHEFILE *,CACHETABLE, int /*fd*/, const char */*fname (used for logging)*/);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:38 -04:00
|
|
|
// Get access to the asynchronous work queue
|
|
|
|
// Returns: a pointer to the work queue
|
2013-04-16 23:57:38 -04:00
|
|
|
WORKQUEUE toku_cachetable_get_workqueue (CACHETABLE);
|
2013-04-16 23:57:38 -04:00
|
|
|
|
2013-04-16 23:57:38 -04:00
|
|
|
void toku_cachefile_get_workqueue_load (CACHEFILE, int *n_in_queue, int *n_threads);
|
2013-04-16 23:57:38 -04:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// The flush callback is called when a key value pair is being written to storage and possibly removed from the cachetable.
|
|
|
|
// When write_me is true, the value should be written to storage.
|
|
|
|
// When keep_me is false, the value should be freed.
|
|
|
|
// Returns: 0 if success, otherwise an error number.
|
2013-04-16 23:57:18 -04:00
|
|
|
typedef void (*CACHETABLE_FLUSH_CALLBACK)(CACHEFILE, CACHEKEY key, void *value, void *extraargs, long size, BOOL write_me, BOOL keep_me, LSN modified_lsn, BOOL rename_p);
|
2007-09-17 16:23:05 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// The fetch callback is called when a thread is attempting to get and pin a memory
|
|
|
|
// object and it is not in the cachetable.
|
|
|
|
// Returns: 0 if success, otherwise an error number. The address and size of the object
|
|
|
|
// associated with the key are returned.
|
2013-04-16 23:57:17 -04:00
|
|
|
typedef int (*CACHETABLE_FETCH_CALLBACK)(CACHEFILE, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep, void *extraargs, LSN *written_lsn);
|
|
|
|
|
2013-04-16 23:57:38 -04:00
|
|
|
void toku_cachefile_set_userdata(CACHEFILE cf, void *userdata, int (*close_userdata)(CACHEFILE, void*, char **/*error_string*/), int (*checkpoint_userdata)(CACHEFILE, void*));
|
2013-04-16 23:57:29 -04:00
|
|
|
// Effect: Store some cachefile-specific user data. When the last reference to a cachefile is closed, we call close_userdata().
|
|
|
|
// When the cachefile needs to be checkpointed, we call checkpoint_userdata().
|
2013-04-16 23:57:18 -04:00
|
|
|
// If userdata is already non-NULL, then we simply overwrite it.
|
2013-04-16 23:57:38 -04:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
void *toku_cachefile_get_userdata(CACHEFILE);
|
2013-04-16 23:57:38 -04:00
|
|
|
// Effect: Get the user data.
|
2013-04-16 23:57:18 -04:00
|
|
|
|
|
|
|
// Put a memory object into the cachetable.
|
|
|
|
// Effects: Lookup the key in the cachetable. If the key is not in the cachetable,
|
|
|
|
// then insert the pair and pin it. Otherwise return an error. Some of the key
|
|
|
|
// value pairs may be evicted from the cachetable when the cachetable gets too big.
|
|
|
|
// Returns: 0 if the memory object is placed into the cachetable, otherwise an
|
|
|
|
// error number.
|
2008-06-17 17:05:19 +00:00
|
|
|
int toku_cachetable_put(CACHEFILE cf, CACHEKEY key, u_int32_t fullhash,
|
2013-04-16 23:57:17 -04:00
|
|
|
void *value, long size,
|
|
|
|
CACHETABLE_FLUSH_CALLBACK flush_callback,
|
|
|
|
CACHETABLE_FETCH_CALLBACK fetch_callback, void *extraargs);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Get and pin a memory object.
|
|
|
|
// Effects: If the memory object is in the cachetable, acquire a read lock on it.
|
|
|
|
// Otherwise, fetch it from storage by calling the fetch callback. If the fetch
|
|
|
|
// succeeded, add the memory object to the cachetable with a read lock on it.
|
|
|
|
// Returns: 0 if the memory object is in memory, otherwise an error number.
|
2008-06-17 17:05:19 +00:00
|
|
|
int toku_cachetable_get_and_pin(CACHEFILE, CACHEKEY, u_int32_t /*fullhash*/,
|
2013-04-16 23:57:17 -04:00
|
|
|
void **/*value*/, long *sizep,
|
|
|
|
CACHETABLE_FLUSH_CALLBACK flush_callback,
|
|
|
|
CACHETABLE_FETCH_CALLBACK fetch_callback, void *extraargs);
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Maybe get and pin a memory object.
|
|
|
|
// Effects: This function is identical to the get_and_pin function except that it
|
|
|
|
// will not attempt to fetch a memory object that is not in the cachetable.
|
|
|
|
// Returns: If the the item is already in memory, then return 0 and store it in the
|
|
|
|
// void**. If the item is not in memory, then return a nonzero error number.
|
2008-06-17 17:05:19 +00:00
|
|
|
int toku_cachetable_maybe_get_and_pin (CACHEFILE, CACHEKEY, u_int32_t /*fullhash*/, void**);
|
2007-10-19 14:07:41 +00:00
|
|
|
|
2013-04-16 23:57:38 -04:00
|
|
|
// cachetable pair clean or dirty WRT external memory
|
|
|
|
enum cachetable_dirty {
|
2013-04-16 23:57:38 -04:00
|
|
|
CACHETABLE_CLEAN=0, // the cached object is clean WRT the cachefile
|
|
|
|
CACHETABLE_DIRTY=1, // the cached object is dirty WRT the cachefile
|
|
|
|
};
|
2007-10-19 14:07:41 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Unpin a memory object
|
|
|
|
// Effects: If the memory object is in the cachetable, then OR the dirty flag,
|
|
|
|
// update the size, and release the read lock on the memory object.
|
|
|
|
// Returns: 0 if success, otherwise returns an error number.
|
2013-04-16 23:57:38 -04:00
|
|
|
int toku_cachetable_unpin(CACHEFILE, CACHEKEY, u_int32_t fullhash, enum cachetable_dirty dirty, long size);
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2013-04-16 23:57:24 -04:00
|
|
|
int toku_cachetable_unpin_and_remove (CACHEFILE, CACHEKEY); /* Removing something already present is OK. */
|
|
|
|
// Effect: Remove an object from the cachetable. Don't write it back.
|
2013-04-16 23:57:24 -04:00
|
|
|
// Requires: The object must be pinned exactly once.
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2013-04-16 23:57:38 -04:00
|
|
|
// Prefetch a memory object for a given key into the cachetable
|
|
|
|
// Returns: 0 if success
|
|
|
|
int toku_cachefile_prefetch(CACHEFILE cf, CACHEKEY key, u_int32_t fullhash,
|
|
|
|
CACHETABLE_FLUSH_CALLBACK flush_callback,
|
|
|
|
CACHETABLE_FETCH_CALLBACK fetch_callback,
|
|
|
|
void *extraargs);
|
|
|
|
|
2007-11-19 23:47:44 +00:00
|
|
|
int toku_cachetable_assert_all_unpinned (CACHETABLE);
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2007-11-19 23:47:44 +00:00
|
|
|
int toku_cachefile_count_pinned (CACHEFILE, int /*printthem*/ );
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Rename whatever is at oldkey to be newkey. Requires that the object be pinned.
|
2007-11-19 23:47:44 +00:00
|
|
|
int toku_cachetable_rename (CACHEFILE cachefile, CACHEKEY oldkey, CACHEKEY newkey);
|
2007-11-14 17:58:38 +00:00
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
//int cachetable_fsync_all (CACHETABLE); /* Flush everything to disk, but keep it in cache. */
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Close the cachefile.
|
|
|
|
// Effects: All of the cached object associated with the cachefile are evicted from
|
|
|
|
// the cachetable. The flush callback is called for each of these objects. The
|
|
|
|
// close function does not return until all of the objects are evicted. The cachefile
|
|
|
|
// object is freed.
|
|
|
|
// Returns: 0 if success, otherwise returns an error number.
|
2013-04-16 23:57:38 -04:00
|
|
|
int toku_cachefile_close (CACHEFILE*, TOKULOGGER, char **error_string);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Flush the cachefile.
|
|
|
|
// Effect: Flush everything owned by the cachefile from the cachetable. All dirty
|
|
|
|
// blocks are written. All unpinned blocks are evicted from the cachetable.
|
|
|
|
// Returns: 0 if success, otherwise returns an error number.
|
2008-07-21 02:34:13 +00:00
|
|
|
int toku_cachefile_flush (CACHEFILE);
|
|
|
|
|
|
|
|
// Increment the reference count. Use close to decrement it.
|
2013-04-16 23:57:18 -04:00
|
|
|
void toku_cachefile_refup (CACHEFILE cfp);
|
2008-04-09 02:45:27 +00:00
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
// Return on success (different from pread and pwrite)
|
2013-04-16 23:57:27 -04:00
|
|
|
//int cachefile_pwrite (CACHEFILE, const void *buf, size_t count, toku_off_t offset);
|
|
|
|
//int cachefile_pread (CACHEFILE, void *buf, size_t count, toku_off_t offset);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Get the file descriptor associated with the cachefile
|
|
|
|
// Return the file descriptor
|
2007-11-19 23:47:44 +00:00
|
|
|
int toku_cachefile_fd (CACHEFILE);
|
2008-07-21 02:34:13 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Set the cachefile's fd and fname.
|
|
|
|
// Effect: Bind the cachefile to a new fd and fname. The old fd is closed.
|
|
|
|
// Returns: 0 if success, otherwise an error number
|
2008-07-21 02:34:13 +00:00
|
|
|
int toku_cachefile_set_fd (CACHEFILE cf, int fd, const char *fname);
|
2007-07-13 19:37:47 +00:00
|
|
|
|
2013-04-16 23:57:27 -04:00
|
|
|
// Equivalent to toku_cachefile_set_fd to /dev/null but without
|
|
|
|
// closing the user data.
|
|
|
|
int toku_cachefile_redirect_nullfd (CACHEFILE cf);
|
|
|
|
|
2013-04-16 23:57:27 -04:00
|
|
|
// Truncate a cachefile
|
|
|
|
// Effect: set the cachefile size to 0
|
|
|
|
int toku_cachefile_truncate0 (CACHEFILE cf);
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Return the logger associated with the cachefile
|
2007-11-19 23:47:44 +00:00
|
|
|
TOKULOGGER toku_cachefile_logger (CACHEFILE);
|
2007-11-14 17:58:38 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Return the filenum associated with the cachefile
|
2013-04-16 23:57:17 -04:00
|
|
|
FILENUM toku_cachefile_filenum (CACHEFILE);
|
2008-03-21 20:43:39 +00:00
|
|
|
|
2008-06-17 17:05:19 +00:00
|
|
|
// Effect: Return a 32-bit hash key. The hash key shall be suitable for using with bitmasking for a table of size power-of-two.
|
2013-04-16 23:57:18 -04:00
|
|
|
u_int32_t toku_cachetable_hash (CACHEFILE cachefile, CACHEKEY key);
|
2008-06-17 17:05:19 +00:00
|
|
|
|
|
|
|
u_int32_t toku_cachefile_fullhash_of_header (CACHEFILE cachefile);
|
|
|
|
|
2013-04-16 23:57:17 -04:00
|
|
|
// debug functions
|
2013-04-16 23:57:18 -04:00
|
|
|
|
|
|
|
// Print the contents of the cachetable. This is mainly used from gdb
|
2013-04-16 23:57:17 -04:00
|
|
|
void toku_cachetable_print_state (CACHETABLE ct);
|
2013-04-16 23:57:18 -04:00
|
|
|
|
|
|
|
// Get the state of the cachetable. This is used to verify the cachetable
|
2013-04-16 23:57:17 -04:00
|
|
|
void toku_cachetable_get_state(CACHETABLE ct, int *num_entries_ptr, int *hash_size_ptr, long *size_current_ptr, long *size_limit_ptr);
|
2013-04-16 23:57:18 -04:00
|
|
|
|
|
|
|
// Get the state of a cachetable entry by key. This is used to verify the cachetable
|
2013-04-16 23:57:17 -04:00
|
|
|
int toku_cachetable_get_key_state(CACHETABLE ct, CACHEKEY key, CACHEFILE cf,
|
|
|
|
void **value_ptr,
|
|
|
|
int *dirty_ptr,
|
|
|
|
long long *pin_ptr,
|
|
|
|
long *size_ptr);
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
// Verify the whole cachetable that the cachefile is in. Slow.
|
|
|
|
void toku_cachefile_verify (CACHEFILE cf);
|
|
|
|
|
|
|
|
// Verify the cachetable. Slow.
|
|
|
|
void toku_cachetable_verify (CACHETABLE t);
|
2013-04-16 23:57:17 -04:00
|
|
|
|
2013-04-16 23:57:20 -04:00
|
|
|
// Not for use in production, but useful for testing.
|
|
|
|
void print_hash_histogram (void) __attribute__((__visibility__("default")));
|
|
|
|
|
2013-04-16 23:57:39 -04:00
|
|
|
int toku_graceful_open(const char *db_fname, BOOL *is_dirtyp);
|
|
|
|
int toku_graceful_close(CACHEFILE cf);
|
|
|
|
int toku_graceful_dirty(CACHEFILE cf);
|
|
|
|
int toku_graceful_delete(const char *db_fname);
|
|
|
|
void toku_graceful_lock_init(void);
|
|
|
|
void toku_graceful_lock_destroy(void);
|
|
|
|
|
2013-04-16 23:57:41 -04:00
|
|
|
#define TOKU_CACHETABLE_DO_EVICT_FROM_WRITER 0
|
2013-04-16 23:57:39 -04:00
|
|
|
|
2013-04-16 23:57:41 -04:00
|
|
|
void toku_cachetable_maybe_flush_some(CACHETABLE ct);
|
2013-04-16 23:57:39 -04:00
|
|
|
|
2007-07-13 19:37:47 +00:00
|
|
|
#endif
|