| 
Macros | 
| #define | STRUCT_PTR(TYPE, MEMBER, a)   (TYPE *) ((char *) (a) - offsetof(TYPE, MEMBER)) | 
| #define | COND_FOR_REQUESTED   0 | 
| #define | COND_FOR_SAVED   1 | 
| #define | COND_FOR_READERS   2 | 
| #define | BLOCK_ERROR   1 /* an error occured when performing file i/o */ | 
| #define | BLOCK_READ   2 /* file block is in the block buffer         */ | 
| #define | BLOCK_IN_SWITCH   4 /* block is preparing to read new page       */ | 
| #define | BLOCK_REASSIGNED   8 /* blk does not accept requests for old page */ | 
| #define | BLOCK_IN_FLUSH   16 /* block is selected for flush               */ | 
| #define | BLOCK_CHANGED   32 /* block buffer contains a dirty page        */ | 
| #define | BLOCK_IN_USE   64 /* block is not free                         */ | 
| #define | BLOCK_IN_EVICTION   128 /* block is selected for eviction            */ | 
| #define | BLOCK_IN_FLUSHWRITE   256 /* block is in write to file                 */ | 
| #define | BLOCK_FOR_UPDATE   512 /* block is selected for buffer modification */ | 
| #define | PAGE_READ   0 | 
| #define | PAGE_TO_BE_READ   1 | 
| #define | PAGE_WAIT_TO_BE_READ   2 | 
| #define | FLUSH_CACHE   2000            /* sort this many blocks at once */ | 
| #define | KEYCACHE_HASH(f, pos) | 
| #define | FILE_HASH(f)   ((uint) (f) & (CHANGED_BLOCKS_HASH-1)) | 
| #define | DEFAULT_KEYCACHE_DEBUG_LOG   "keycache_debug.log" | 
| #define | KEYCACHE_DEBUG_OPEN | 
| #define | KEYCACHE_DEBUG_CLOSE | 
| #define | KEYCACHE_DBUG_PRINT(l, m)   DBUG_PRINT(l, m) | 
| #define | KEYCACHE_DBUG_ASSERT(a)   DBUG_ASSERT(a) | 
| #define | KEYCACHE_THREAD_TRACE(l)   KEYCACHE_DBUG_PRINT(l,("|thread %ld",keycache_thread_id)) | 
| #define | KEYCACHE_THREAD_TRACE_BEGIN(l) | 
| #define | KEYCACHE_THREAD_TRACE_END(l)   KEYCACHE_DBUG_PRINT(l,("]thread %ld",keycache_thread_id)) | 
| #define | BLOCK_NUMBER(b)   ((uint) (((char*)(b)-(char *) keycache->block_root)/sizeof(BLOCK_LINK))) | 
| #define | HASH_LINK_NUMBER(h)   ((uint) (((char*)(h)-(char *) keycache->hash_link_root)/sizeof(HASH_LINK))) | 
| #define | keycache_pthread_cond_wait(C, M)   mysql_cond_wait(C, M) | 
| #define | keycache_pthread_mutex_lock(M)   mysql_mutex_lock(M) | 
| #define | keycache_pthread_mutex_unlock(M)   mysql_mutex_unlock(M) | 
| #define | keycache_pthread_cond_signal(C)   mysql_cond_signal(C) | 
| #define | inline   /* disabled inline for easier debugging */ | 
| #define | F_B_PRT(_f_, _v_)   DBUG_PRINT("assert_fail", (_f_, _v_)) | 
| 
Functions | 
| int | init_key_cache (KEY_CACHE *keycache, uint key_cache_block_size, size_t use_mem, uint division_limit, uint age_threshold) | 
| int | resize_key_cache (KEY_CACHE *keycache, uint key_cache_block_size, size_t use_mem, uint division_limit, uint age_threshold) | 
| void | change_key_cache_param (KEY_CACHE *keycache, uint division_limit, uint age_threshold) | 
| void | end_key_cache (KEY_CACHE *keycache, my_bool cleanup) | 
| uchar * | key_cache_read (KEY_CACHE *keycache, File file, my_off_t filepos, int level, uchar *buff, uint length, uint block_length __attribute__((unused)), int return_buffer __attribute__((unused))) | 
| int | key_cache_insert (KEY_CACHE *keycache, File file, my_off_t filepos, int level, uchar *buff, uint length) | 
| int | key_cache_write (KEY_CACHE *keycache, File file, my_off_t filepos, int level, uchar *buff, uint length, uint block_length __attribute__((unused)), int dont_write) | 
| int | flush_key_blocks (KEY_CACHE *keycache, File file, enum flush_type type) | 
| int | reset_key_cache_counters (const char *name __attribute__((unused)), KEY_CACHE *key_cache) | 
These functions handle keyblock cacheing for ISAM and MyISAM tables.
One cache can handle many files. It must contain buffers of the same blocksize. init_key_cache() should be used to init cache handler.
The free list (free_block_list) is a stack like structure. When a block is freed by free_block(), it is pushed onto the stack. When a new block is required it is first tried to pop one from the stack. If the stack is empty, it is tried to get a never-used block from the pool. If this is empty too, then a block is taken from the LRU ring, flushing it to disk, if neccessary. This is handled in find_key_block(). With the new free list, the blocks can have three temperatures: hot, warm and cold (which is free). This is remembered in the block header by the enum BLOCK_TEMPERATURE temperature variable. Remembering the temperature is neccessary to correctly count the number of warm blocks, which is required to decide when blocks are allowed to become hot. Whenever a block is inserted to another (sub-)chain, we take the old and new temperature into account to decide if we got one more or less warm block. blocks_unused is the sum of never used blocks in the pool and of currently free blocks. blocks_used is the number of blocks fetched from the pool and as such gives the maximum number of in-use blocks at any time. 
Definition in file mf_keycache.c.