1 /* -*-pgsql-c-*- */
2 /*
3  *
4  * $Header$
5  *
6  * pgpool: a language independent connection pool server for PostgreSQL
7  * written by Tatsuo Ishii
8  *
9  * Copyright (c) 2003-2012	PgPool Global Development Group
10  *
11  * Permission to use, copy, modify, and distribute this software and
12  * its documentation for any purpose and without fee is hereby
13  * granted, provided that the above copyright notice appear in all
14  * copies and that both that copyright notice and this permission
15  * notice appear in supporting documentation, and that the name of the
16  * author not be used in advertising or publicity pertaining to
17  * distribution of the software without specific, written prior
18  * permission. The author makes no representations about the
19  * suitability of this software for any purpose.  It is provided "as
20  * is" without express or implied warranty.
21  *
22  * pool_memqcache.h: on memory query cache related definitions
23  *
24  */
25 
26 #ifndef POOL_MEMQCACHE_H
27 #define POOL_MEMQCACHE_H
28 
29 #include "pool.h"
30 #include <sys/time.h>
31 
32 #define NO_QUERY_CACHE "/*NO QUERY CACHE*/"
33 #define NO_QUERY_CACHE_COMMENT_SZ (sizeof(NO_QUERY_CACHE)-1)
34 
35 #define POOL_MD5_HASHKEYLEN		32		/* MD5 hash key length */
36 
37 /*
38  * On memory query cache on shmem is divided into fixed length "cache
39  * block". Each block is assigned a "cache block id", which is
40  * starting with 0.
41  */
42 typedef char *POOL_CACH_BLOCK;		/* pointer to cache block */
43 typedef unsigned int POOL_CACHE_BLOCKID;		/* cache block id */
44 typedef unsigned int POOL_CACHE_ITEMID;		/* cache item id */
45 
46 /*
47  * "Cache id" represents "absolute address" of a cache item.
48  */
49 typedef struct {
50 	POOL_CACHE_BLOCKID	blockid;
51 	POOL_CACHE_ITEMID	itemid;
52 } POOL_CACHEID;	/* cache id */
53 
54 /*
55  * Each block has management space called "cache block header" at the
56  * very beginning of the cache block.
57  */
58 
59 #define POOL_BLOCK_USED	0x0001		/* is this block used? */
60 
61 typedef struct {
62 	unsigned char flags;		/* flags. see above */
63 	unsigned int num_items;		/* number of items */
64 	unsigned int free_bytes;		/* total free space in bytes */
65 } POOL_CACHE_BLOCK_HEADER;
66 
67 typedef struct {
68 	char query_hash[POOL_MD5_HASHKEYLEN];
69 } POOL_QUERY_HASH;
70 
71 #define POOL_ITEM_USED	0x0001		/* is this item used? */
72 #define POOL_ITEM_HAS_NEXT	0x0002		/* is this item has "next" item? */
73 #define POOL_ITEM_DELETED	0x0004		/* is this item deleted? */
74 
75 typedef struct {
76 	POOL_QUERY_HASH query_hash;	/* md5 hashed query signature */
77 	POOL_CACHEID next;			/* next cache item if any */
78 	unsigned int offset;		/* item offset in this block */
79 	unsigned char flags;		/* flags. see above */
80 } POOL_CACHE_ITEM_POINTER;
81 
82 /*
83  * Each block holds several "cache item", which consists of variable
84  * length of Data(header plus RowDescription packet and DataRow
85  * packet).  Each cache item is assigned "cache item id", which
86  * represents the cache item order in a block.
87  */
88 
89 /*
90  * "Cache Item" structure holds a SELECT result having several row
91  * data in memory cache.  Cache item can be used with either shmem or
92  * memcached.
93  */
94 
95 /*
96  * "Cache Item header" structure is used to manage each cache item.
97  */
98 typedef struct {
99 	unsigned int total_length;	/* total length in bytes including myself */
100 	time_t timestamp;	/* cache creation time */
101 } POOL_CACHE_ITEM_HEADER;
102 
103 typedef struct {
104 	POOL_CACHE_ITEM_HEADER header;		/* cache item header */
105 	char data[1];	/* variable length data follows */
106 } POOL_CACHE_ITEM;
107 
108 /*
109  * Possible the largest free space size in bytes
110  */
111 #define POOL_MAX_FREE_SPACE (pool_config->memqcache_cache_block_size - sizeof(POOL_CACHE_BLOCK_HEADER))
112 
113 #define POOL_FSMM_RATIO (pool_config->memqcache_cache_block_size/256)
114 
115 #define MAX_VALUE 8192
116 #define MAX_KEY 256
117 
118 extern int memcached_connect(void);
119 extern void memcached_disconnect(void);
120 extern void memqcache_register(char kind, POOL_CONNECTION *frontend, char *data, int data_len);
121 
122 /*
123  * Cache key
124  */
125 typedef union
126 {
127 	POOL_CACHEID		cacheid;		/* cache key (shmem configuration) */
128 	char hashkey[POOL_MD5_HASHKEYLEN];	/* cache key (memcached configuration) */
129 } POOL_CACHEKEY;
130 
131 /*
132  * Internal buffer structure
133  */
134 typedef struct
135 {
136 	size_t bufsize;		/* buffer size */
137 	size_t buflen;		/* used length */
138 	char *buf;	/* buffer */
139 } POOL_INTERNAL_BUFFER;
140 
141 /*
142  * Temporary query cache buffer
143  */
144 typedef struct
145 {
146 	bool is_exceeded;		/* true if data size exceeds memqcache_maxcache */
147 	bool is_discarded;	/* true if this cache entry is discarded */
148 	char *query;		/* SELECT query */
149 	POOL_INTERNAL_BUFFER *buffer;
150 	int num_oids;
151 	POOL_INTERNAL_BUFFER *oids;
152 } POOL_TEMP_QUERY_CACHE;
153 
154 /*
155  * Temporary query cache buffer array
156  */
157 typedef struct
158 {
159 	int num_caches;
160 	int array_size;
161 	POOL_TEMP_QUERY_CACHE *caches[1];	/* actual data continues... */
162 } POOL_QUERY_CACHE_ARRAY;
163 
164 /*
165  * Query cache statistics structure. This area must be placed on shared
166  * memory and protected by QUERY_CACHE_STATS_SEM.
167  */
168 typedef struct
169 {
170 	time_t		start_time;		/* start time when the statistics begins */
171 	long long int num_selects;	/* number of successful SELECTs */
172 	long long int num_cache_hits;		/* number of SELECTs extracted from cache */
173 } POOL_QUERY_CACHE_STATS;
174 
175 /*
176  * Shared memory cache stats interface.
177  */
178 typedef struct
179 {
180 	int num_hash_entries;		/* number of total hash entries */
181 	int used_hash_entries;	/* number of used hash entries */
182 	int num_cache_entries;	/* number of used cache entries */
183 	long used_cache_entries_size;	/* total size of used cache entries */
184 	long free_cache_entries_size;	/* total size of free(usable) cache entries */
185 	long fragment_cache_entries_size;	/* total size of fragment(unusable) cache entries */
186 	POOL_QUERY_CACHE_STATS cache_stats;
187 } POOL_SHMEM_STATS;
188 
189 /*--------------------------------------------------------------------------------
190  * On shared memory hash table implementation
191  *--------------------------------------------------------------------------------
192  */
193 
194 /* Hash element */
195 typedef struct POOL_HASH_ELEMENT
196 {
197 	struct POOL_HASH_ELEMENT *next;		/* link to next entry */
198 	POOL_QUERY_HASH		hashkey;		/* MD5 hash key */
199 	POOL_CACHEID		cacheid;		/* logical location of this cache element */
200 } POOL_HASH_ELEMENT;
201 
202 typedef uint32 POOL_HASH_KEY;
203 
204 /* Hash header element */
205 typedef struct
206 {
207 	POOL_HASH_KEY hashkey;		/* hash key */
208 	POOL_HASH_ELEMENT *element;	/* hash element */
209 } POOL_HEADER_ELEMENT;
210 
211 /* Hash header */
212 typedef struct
213 {
214 	long nhash;			/* number of hash keys (power of 2) */
215 	uint32 mask;		/* mask for hash function */
216 	POOL_HEADER_ELEMENT elements[1];	/* actual hash elements follows */
217 } POOL_HASH_HEADER;
218 
219 extern int pool_hash_init(int nelements);
220 extern POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key);
221 extern int pool_hash_delete(POOL_QUERY_HASH *key);
222 extern uint32 hash_any(unsigned char *k, int keylen);
223 
224 extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend,
225 												POOL_CONNECTION_POOL *backend,
226 												char *contents, bool *foundp);
227 
228 extern bool pool_is_likely_select(char *query);
229 extern bool pool_is_table_in_black_list(const char *table_name);
230 extern bool pool_is_table_in_white_list(const char *table_name);
231 extern bool pool_is_allow_to_cache(Node *node, char *query);
232 extern int	pool_extract_table_oids(Node *node, int **oidsp);
233 extern int	pool_extract_withclause_oids(Node *with, int *oidsp);
234 extern void pool_add_dml_table_oid(int oid);
235 extern void pool_discard_oid_maps(void);
236 extern int pool_get_database_oid_from_dbname(char *dbname);
237 extern void pool_discard_oid_maps_by_db(int dboid);
238 extern bool pool_is_shmem_cache(void);
239 extern size_t pool_shared_memory_cache_size(void);
240 extern int pool_init_memory_cache(size_t size);
241 extern void pool_clear_memory_cache(void);
242 extern size_t pool_shared_memory_fsmm_size(void);
243 extern int pool_init_fsmm(size_t size);
244 extern void pool_allocate_fsmm_clock_hand(void);
245 
246 extern POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void);
247 extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array);
248 
249 extern POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query);
250 extern void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state);
251 
252 extern int pool_init_memqcache_stats(void);
253 extern POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void);
254 extern void pool_reset_memqcache_stats(void);
255 extern long long int pool_stats_count_up_num_selects(long long int num);
256 extern long long int pool_stats_count_up_num_cache_hits(void);
257 extern long long int pool_tmp_stats_count_up_num_selects(void);
258 extern long long int pool_tmp_stats_get_num_selects(void);
259 extern void pool_tmp_stats_reset_num_selects(void);
260 extern POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void);
261 
262 extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void);
263 extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void);
264 extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache);
265 
266 extern void pool_shmem_lock(void);
267 extern void pool_shmem_unlock(void);
268 
269 #endif /* POOL_MEMQCACHE_H */
270