/* -*-pgsql-c-*- */ /* * * $Header$ * * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of the * author not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. The author makes no representations about the * suitability of this software for any purpose. It is provided "as * is" without express or implied warranty. * * pool_memqcache.h: on memory query cache related definitions * */ #ifndef POOL_MEMQCACHE_H #define POOL_MEMQCACHE_H #include "pool.h" #include #define NO_QUERY_CACHE "/*NO QUERY CACHE*/" #define NO_QUERY_CACHE_COMMENT_SZ (sizeof(NO_QUERY_CACHE)-1) #define POOL_MD5_HASHKEYLEN 32 /* MD5 hash key length */ /* * On memory query cache on shmem is divided into fixed length "cache * block". Each block is assigned a "cache block id", which is * starting with 0. */ typedef char *POOL_CACH_BLOCK; /* pointer to cache block */ typedef unsigned int POOL_CACHE_BLOCKID; /* cache block id */ typedef unsigned int POOL_CACHE_ITEMID; /* cache item id */ /* * "Cache id" represents "absolute address" of a cache item. */ typedef struct { POOL_CACHE_BLOCKID blockid; POOL_CACHE_ITEMID itemid; } POOL_CACHEID; /* cache id */ /* * Each block has management space called "cache block header" at the * very beginning of the cache block. */ #define POOL_BLOCK_USED 0x0001 /* is this block used? */ typedef struct { unsigned char flags; /* flags. see above */ unsigned int num_items; /* number of items */ unsigned int free_bytes; /* total free space in bytes */ } POOL_CACHE_BLOCK_HEADER; typedef struct { char query_hash[POOL_MD5_HASHKEYLEN]; } POOL_QUERY_HASH; #define POOL_ITEM_USED 0x0001 /* is this item used? */ #define POOL_ITEM_HAS_NEXT 0x0002 /* is this item has "next" item? */ #define POOL_ITEM_DELETED 0x0004 /* is this item deleted? */ typedef struct { POOL_QUERY_HASH query_hash; /* md5 hashed query signature */ POOL_CACHEID next; /* next cache item if any */ unsigned int offset; /* item offset in this block */ unsigned char flags; /* flags. see above */ } POOL_CACHE_ITEM_POINTER; /* * Each block holds several "cache item", which consists of variable * length of Data(header plus RowDescription packet and DataRow * packet). Each cache item is assigned "cache item id", which * represents the cache item order in a block. */ /* * "Cache Item" structure holds a SELECT result having several row * data in memory cache. Cache item can be used with either shmem or * memcached. */ /* * "Cache Item header" structure is used to manage each cache item. */ typedef struct { unsigned int total_length; /* total length in bytes including myself */ time_t timestamp; /* cache creation time */ } POOL_CACHE_ITEM_HEADER; typedef struct { POOL_CACHE_ITEM_HEADER header; /* cache item header */ char data[1]; /* variable length data follows */ } POOL_CACHE_ITEM; /* * Possible the largest free space size in bytes */ #define POOL_MAX_FREE_SPACE (pool_config->memqcache_cache_block_size - sizeof(POOL_CACHE_BLOCK_HEADER)) #define POOL_FSMM_RATIO (pool_config->memqcache_cache_block_size/256) #define MAX_VALUE 8192 #define MAX_KEY 256 extern int memcached_connect(void); extern void memcached_disconnect(void); extern void memqcache_register(char kind, POOL_CONNECTION *frontend, char *data, int data_len); /* * Cache key */ typedef union { POOL_CACHEID cacheid; /* cache key (shmem configuration) */ char hashkey[POOL_MD5_HASHKEYLEN]; /* cache key (memcached configuration) */ } POOL_CACHEKEY; /* * Internal buffer structure */ typedef struct { size_t bufsize; /* buffer size */ size_t buflen; /* used length */ char *buf; /* buffer */ } POOL_INTERNAL_BUFFER; /* * Temporary query cache buffer */ typedef struct { bool is_exceeded; /* true if data size exceeds memqcache_maxcache */ bool is_discarded; /* true if this cache entry is discarded */ char *query; /* SELECT query */ POOL_INTERNAL_BUFFER *buffer; int num_oids; POOL_INTERNAL_BUFFER *oids; } POOL_TEMP_QUERY_CACHE; /* * Temporary query cache buffer array */ typedef struct { int num_caches; int array_size; POOL_TEMP_QUERY_CACHE *caches[1]; /* actual data continues... */ } POOL_QUERY_CACHE_ARRAY; /* * Query cache statistics structure. This area must be placed on shared * memory and protected by QUERY_CACHE_STATS_SEM. */ typedef struct { time_t start_time; /* start time when the statistics begins */ long long int num_selects; /* number of successful SELECTs */ long long int num_cache_hits; /* number of SELECTs extracted from cache */ } POOL_QUERY_CACHE_STATS; /* * Shared memory cache stats interface. */ typedef struct { int num_hash_entries; /* number of total hash entries */ int used_hash_entries; /* number of used hash entries */ int num_cache_entries; /* number of used cache entries */ long used_cache_entries_size; /* total size of used cache entries */ long free_cache_entries_size; /* total size of free(usable) cache entries */ long fragment_cache_entries_size; /* total size of fragment(unusable) cache entries */ POOL_QUERY_CACHE_STATS cache_stats; } POOL_SHMEM_STATS; /*-------------------------------------------------------------------------------- * On shared memory hash table implementation *-------------------------------------------------------------------------------- */ /* Hash element */ typedef struct POOL_HASH_ELEMENT { struct POOL_HASH_ELEMENT *next; /* link to next entry */ POOL_QUERY_HASH hashkey; /* MD5 hash key */ POOL_CACHEID cacheid; /* logical location of this cache element */ } POOL_HASH_ELEMENT; typedef uint32 POOL_HASH_KEY; /* Hash header element */ typedef struct { POOL_HASH_KEY hashkey; /* hash key */ POOL_HASH_ELEMENT *element; /* hash element */ } POOL_HEADER_ELEMENT; /* Hash header */ typedef struct { long nhash; /* number of hash keys (power of 2) */ uint32 mask; /* mask for hash function */ POOL_HEADER_ELEMENT elements[1]; /* actual hash elements follows */ } POOL_HASH_HEADER; extern int pool_hash_init(int nelements); extern POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key); extern int pool_hash_delete(POOL_QUERY_HASH *key); extern uint32 hash_any(unsigned char *k, int keylen); extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *contents, bool *foundp); extern bool pool_is_likely_select(char *query); extern bool pool_is_table_in_black_list(const char *table_name); extern bool pool_is_table_in_white_list(const char *table_name); extern bool pool_is_allow_to_cache(Node *node, char *query); extern int pool_extract_table_oids(Node *node, int **oidsp); extern void pool_add_dml_table_oid(int oid); extern void pool_discard_oid_maps(void); extern int pool_get_database_oid_from_dbname(char *dbname); extern void pool_discard_oid_maps_by_db(int dboid); extern bool pool_is_shmem_cache(void); extern size_t pool_shared_memory_cache_size(void); extern int pool_init_memory_cache(size_t size); extern void pool_clear_memory_cache(void); extern size_t pool_shared_memory_fsmm_size(void); extern int pool_init_fsmm(size_t size); extern void pool_allocate_fsmm_clock_hand(void); extern POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void); extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array); extern POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query); extern void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state); extern int pool_init_memqcache_stats(void); extern POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void); extern void pool_reset_memqcache_stats(void); extern long long int pool_stats_count_up_num_selects(long long int num); extern long long int pool_stats_count_up_num_cache_hits(void); extern long long int pool_tmp_stats_count_up_num_selects(void); extern long long int pool_tmp_stats_get_num_selects(void); extern void pool_tmp_stats_reset_num_selects(void); extern POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void); extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache); extern void pool_shmem_lock(void); extern void pool_shmem_unlock(void); #endif /* POOL_MEMQCACHE_H */