1 /* Copyright (c) 2003, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /* Key cache variable structures */
24 
25 #ifndef _keycache_h
26 #define _keycache_h
27 
28 #include "my_sys.h"                             /* flush_type */
29 
30 C_MODE_START
31 
32 /* declare structures that is used by st_key_cache */
33 
34 struct st_block_link;
35 typedef struct st_block_link BLOCK_LINK;
36 struct st_hash_link;
37 typedef struct st_hash_link HASH_LINK;
38 
39 /* Thread specific variables */
40 typedef struct st_keycache_thread_var
41 {
42   mysql_cond_t suspend;
43   struct st_keycache_thread_var *next,**prev;
44   void *opt_info;
45 } st_keycache_thread_var;
46 
47 /* info about requests in a waiting queue */
48 typedef struct st_keycache_wqueue
49 {
50   st_keycache_thread_var *last_thread;  /* circular list of waiting threads */
51 } KEYCACHE_WQUEUE;
52 
53 #define CHANGED_BLOCKS_HASH 128             /* must be power of 2 */
54 
55 /*
56   The key cache structure
57   It also contains read-only statistics parameters.
58 */
59 
60 typedef struct st_key_cache
61 {
62   my_bool key_cache_inited;
63   my_bool in_resize;             /* true during resize operation             */
64   my_bool resize_in_flush;       /* true during flush of resize operation    */
65   my_bool can_be_used;           /* usage of cache for read/write is allowed */
66   size_t key_cache_mem_size;      /* specified size of the cache memory       */
67   uint key_cache_block_size;     /* size of the page buffer of a cache block */
68   ulonglong min_warm_blocks;     /* min number of warm blocks;               */
69   ulonglong age_threshold;       /* age threshold for hot blocks             */
70   ulonglong keycache_time;       /* total number of block link operations    */
71   uint hash_entries;             /* max number of entries in the hash table  */
72   int hash_links;                /* max number of hash links                 */
73   int hash_links_used;           /* number of hash links currently used      */
74   int disk_blocks;               /* max number of blocks in the cache        */
75   ulong blocks_used; /* maximum number of concurrently used blocks */
76   ulong blocks_unused; /* number of currently unused blocks */
77   ulong blocks_changed;          /* number of currently dirty blocks         */
78   ulong warm_blocks;             /* number of blocks in warm sub-chain       */
79   ulong cnt_for_resize_op;       /* counter to block resize operation        */
80   long blocks_available;      /* number of blocks available in the LRU chain */
81   HASH_LINK **hash_root;         /* arr. of entries into hash table buckets  */
82   HASH_LINK *hash_link_root;     /* memory for hash table links              */
83   HASH_LINK *free_hash_list;     /* list of free hash links                  */
84   BLOCK_LINK *free_block_list;   /* list of free blocks */
85   BLOCK_LINK *block_root;        /* memory for block links                   */
86   uchar *block_mem;              /* memory for block buffers                 */
87   BLOCK_LINK *used_last;         /* ptr to the last block of the LRU chain   */
88   BLOCK_LINK *used_ins;          /* ptr to the insertion block in LRU chain  */
89   mysql_mutex_t cache_lock;      /* to lock access to the cache structure    */
90   KEYCACHE_WQUEUE resize_queue;  /* threads waiting during resize operation  */
91   /*
92     Waiting for a zero resize count. Using a queue for symmetry though
93     only one thread can wait here.
94   */
95   KEYCACHE_WQUEUE waiting_for_resize_cnt;
96   KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link     */
97   KEYCACHE_WQUEUE waiting_for_block;    /* requests waiting for a free block */
98   BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
99   BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH];    /* hash for other file bl.*/
100 
101   /*
102     The following variables are and variables used to hold parameters for
103     initializing the key cache.
104   */
105 
106   ulonglong param_buff_size;      /* size the memory allocated for the cache  */
107   ulonglong param_block_size;     /* size of the blocks in the key cache      */
108   ulonglong param_division_limit; /* min. percentage of warm blocks           */
109   ulonglong param_age_threshold;  /* determines when hot block is downgraded  */
110 
111   /* Statistics variables. These are reset in reset_key_cache_counters(). */
112   ulong global_blocks_changed;	/* number of currently dirty blocks         */
113   ulonglong global_cache_w_requests;/* number of write requests (write hits) */
114   ulonglong global_cache_write;     /* number of writes from cache to files  */
115   ulonglong global_cache_r_requests;/* number of read requests (read hits)   */
116   ulonglong global_cache_read;      /* number of reads from files to cache   */
117 
118   int blocks;                   /* max number of blocks in the cache        */
119   my_bool in_init;		/* Set to 1 in MySQL during init/resize     */
120 } KEY_CACHE;
121 
122 /* The default key cache */
123 extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache;
124 
125 extern int init_key_cache(KEY_CACHE *keycache, ulonglong key_cache_block_size,
126 			  size_t use_mem, ulonglong division_limit,
127 			  ulonglong age_threshold);
128 extern int resize_key_cache(KEY_CACHE *keycache,
129                             st_keycache_thread_var *thread_var,
130                             ulonglong key_cache_block_size,
131 			    size_t use_mem, ulonglong division_limit,
132 			    ulonglong age_threshold);
133 extern uchar *key_cache_read(KEY_CACHE *keycache,
134                              st_keycache_thread_var *thread_var,
135                              File file, my_off_t filepos, int level,
136                              uchar *buff, uint length,
137                              uint block_length,int return_buffer);
138 extern int key_cache_insert(KEY_CACHE *keycache,
139                             st_keycache_thread_var *thread_var,
140                             File file, my_off_t filepos, int level,
141                             uchar *buff, uint length);
142 extern int key_cache_write(KEY_CACHE *keycache,
143                            st_keycache_thread_var *thread_var,
144                            File file, my_off_t filepos, int level,
145                            uchar *buff, uint length,
146 			   uint block_length,int force_write);
147 extern int flush_key_blocks(KEY_CACHE *keycache,
148                             st_keycache_thread_var *thread_var,
149                             int file, enum flush_type type);
150 extern void end_key_cache(KEY_CACHE *keycache, my_bool cleanup);
151 
152 /* Functions to handle multiple key caches */
153 extern my_bool multi_keycache_init(void);
154 extern void multi_keycache_free(void);
155 extern KEY_CACHE *multi_key_cache_search(uchar *key, uint length);
156 extern my_bool multi_key_cache_set(const uchar *key, uint length,
157 				   KEY_CACHE *key_cache);
158 extern void multi_key_cache_change(KEY_CACHE *old_data,
159 				   KEY_CACHE *new_data);
160 extern int reset_key_cache_counters(const char *name,
161                                     KEY_CACHE *key_cache);
162 C_MODE_END
163 #endif /* _keycache_h */
164