diff options
author | unknown <monty@hundin.mysql.fi> | 2001-12-02 14:34:01 +0200 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2001-12-02 14:34:01 +0200 |
commit | 7c999bb03223114a4d07f23db2842363d32d1859 (patch) | |
tree | 8e30a64d5c7aaa0ba8554c4c316cc9b76a6724ca /sql/sql_cache.h | |
parent | 95e94560eac0ee72bbc566517ca70f14128a01e8 (diff) | |
download | mariadb-git-7c999bb03223114a4d07f23db2842363d32d1859.tar.gz |
Query cache.
Remove some warnings
Docs/manual.texi:
Solaris and gcc
include/ft_global.h:
Remove warnings
include/myisam.h:
Query cache
include/myisammrg.h:
Query cache
include/mysql_com.h:
Query cache
libmysqld/lib_sql.cc:
Query cache
myisam/ft_boolean_search.c:
Remove warnings
myisam/ft_dump.c:
Remove warnings
myisam/ft_parser.c:
Remove warnings
myisam/ft_static.c:
Remove warnings
myisam/ft_update.c:
Remove warnings
myisam/ftdefs.h:
Remove warnings
myisam/mi_delete.c:
Query cache
myisam/mi_locking.c:
Query cache
myisam/mi_update.c:
Query cache
myisam/myisamdef.h:
Optimize for Ia64
myisammrg/myrg_extra.c:
Query cache
mysys/mf_keycache.c:
DBUG statements
regex/cclass.h:
Remove warnings
regex/cname.h:
Remove warnings
regex/main.c:
Remove warnings
regex/regcomp.c:
Remove warnings
regex/regcomp.ih:
Remove warnings
regex/regerror.c:
Remove warnings
regex/reginit.c:
Remove warnings
regex/split.c:
Remove warnings
sql-bench/test-connect.sh:
Make tests query-cache safe.
sql-bench/test-transactions.sh:
Fix for old perl versions
sql/convert.cc:
Query cache
sql/ha_myisammrg.cc:
Query cache
sql/ha_myisammrg.h:
Query cache
sql/handler.cc:
Query cache
sql/item_create.cc:
Query cache
sql/item_func.cc:
Remove warnings
sql/item_func.h:
Remove warnings
sql/lex.h:
Query cache
sql/mysql_priv.h:
Query cache
sql/mysqld.cc:
Query cache
sql/net_serv.cc:
Query cache
sql/sql_cache.cc:
Query cache
sql/sql_class.cc:
Query cache
sql/sql_class.h:
Query cache
sql/sql_db.cc:
Query cache
sql/sql_delete.cc:
Query cache
sql/sql_insert.cc:
Query cache
sql/sql_parse.cc:
Query cache
sql/sql_select.cc:
Query cache
sql/sql_table.cc:
Query cache
sql/sql_update.cc:
Query cache
sql/sql_yacc.yy:
Query cache
Diffstat (limited to 'sql/sql_cache.h')
-rw-r--r-- | sql/sql_cache.h | 402 |
1 files changed, 402 insertions, 0 deletions
diff --git a/sql/sql_cache.h b/sql/sql_cache.h new file mode 100644 index 00000000000..0b786fb1560 --- /dev/null +++ b/sql/sql_cache.h @@ -0,0 +1,402 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _SQL_CACHE_H +#define _SQL_CACHE_H + +#include <semaphore.h> + +/* Query cache */ + +/* + Can't create new free memory block if unused memory in block less + then QUERY_CACHE_MIN_ALLOCATION_UNIT. + if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then + QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly +*/ +#define QUERY_CACHE_MIN_ALLOCATION_UNIT 0 + +/* inittial size of hashes */ +#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024 +#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024 + +/* minimal result data size when data allocated */ +#define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024 + +/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */ +#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4 +#define QUERY_CACHE_MEM_BIN_STEP_PWR2 2 +#define QUERY_CACHE_MEM_BIN_PARTS_INC 1 +#define QUERY_CACHE_MEM_BIN_PARTS_MUL 1.2 +#define QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2 3 + +/* query flags masks */ +#define QUERY_CACHE_CLIENT_LONG_FLAG_MASK 0x80 +#define QUERY_CACHE_CHARSET_CONVERT_MASK 0x7F + +/* packing parameters */ +#define QUERY_CACHE_PACK_ITERATION 2 +#define QUERY_CACHE_PACK_LIMIT (512*1024L) + +#define TABLE_COUNTER_TYPE uint8 + +struct Query_cache_block; +struct Query_cache_block_table; +struct Query_cache_table; +struct Query_cache_query; +struct Query_cache_result; +class Query_cache; + + +struct Query_cache_block_table +{ + TABLE_COUNTER_TYPE n; // numbr in table (from 0) + Query_cache_block_table *next, *prev; + Query_cache_table *parent; + inline Query_cache_block * block(); +}; + + +struct Query_cache_block +{ + enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG, + RES_INCOMPLETE, TABLE, INCOMPLETE}; + + ulong length; // length of all block + ulong used; // length of data + /* + Not used **pprev, **prev because really needed access to pervious block: + *pprev to join free blocks + *prev to access to opposite side of list in cyclic sorted list + */ + Query_cache_block + *pnext,*pprev, // physical next/previous block + *next,*prev; // logical next/previous block + block_type type; + TABLE_COUNTER_TYPE n_tables; // number of tables in query + + inline my_bool is_free(void) { return type == FREE; } + + void init(ulong length); + void destroy(); + inline uint headers_len(); + inline gptr data(void); + inline Query_cache_query * query(); + inline Query_cache_table * table(); + inline Query_cache_result * result(); + inline Query_cache_block_table * table(TABLE_COUNTER_TYPE n); +}; + + +struct Query_cache_query +{ + ulonglong limit_found_rows; + Query_cache_block * res; + NET * wri; + ulong len; + sem_t lock; // R/W lock of block + pthread_mutex_t clients_guard; + uint clients; + + inline void init_n_lock(); + void unlock_n_destroy(); + inline ulonglong found_rows() { return limit_found_rows; } + inline void found_rows(ulonglong rows) { limit_found_rows = rows; } + inline Query_cache_block * result() { return res; } + inline void result(Query_cache_block *p) { res=p; } + inline NET * writer() { return wri; } + inline void writer(NET *p) { wri=p; } + inline ulong length() { return len; } + inline ulong add(ulong packet_len) { return(len += packet_len); } + inline void length(ulong length) { len = length; } + inline gptr query() + { + return (gptr)(((byte*)this)+ + ALIGN_SIZE(sizeof(Query_cache_query))); + } + void lock_writing(); + void lock_reading(); + my_bool try_lock_writing(); + void unlock_writing(); + void unlock_reading(); + static byte * cache_key(const byte *record, uint *length, + my_bool not_used); + static void free_cache(void *entry); +}; + + +struct Query_cache_table +{ + enum query_cache_table_type {OTHER=0, INNODB=1, TYPES_NUMBER=2}; + inline static query_cache_table_type type_convertion(db_type type) + { + return (type == DB_TYPE_INNODB ? INNODB : OTHER); + } + + char * tbl; + query_cache_table_type tp; + + inline query_cache_table_type type() { return tp; } + inline void type(query_cache_table_type t) { tp = t;} + inline char * db() { return (char *) data(); } + inline char * table() { return tbl; } + inline void table(char * table) { tbl = table; } + inline gptr data() + { + return (gptr)(((byte*)this)+ + ALIGN_SIZE(sizeof(Query_cache_table))); + } + + static byte * cache_key(const byte *record, uint *length, + my_bool not_used); + static void free_cache(void *entry); +}; + + +struct Query_cache_result +{ + Query_cache_block *query; + + inline gptr data(){return (gptr)(((byte*)this)+ + ALIGN_SIZE(sizeof(Query_cache_result)));} + + /* data_continue (if not whole packet contained by this block) */ + inline Query_cache_block * parent() { return query; } + inline void parent (Query_cache_block *p) { query=p; } +}; + + +extern "C" { + void query_cache_insert(THD *thd, const char *packet, ulong length); + void query_cache_end_of_result(THD *thd); + void query_cache_abort(THD *thd); + void query_cache_invalidate_by_MyISAM_filename(char* filename); +} + +struct Query_cache_memory_bin +{ +#ifndef DBUG_OFF + ulong size; +#endif + uint number; + Query_cache_block * free_blocks; + + inline void init(ulong size) + { +#ifndef DBUG_OFF + this->size = size; +#endif + number = 0; + free_blocks = 0; + } +}; + +struct Query_cache_memory_bin_step +{ + ulong size; + ulong increment; + uint idx; + inline void init(ulong size, uint idx, ulong increment) + { + this->size = size; + this->idx = idx; + this->increment = increment; + } +}; + +class Query_cache +{ + protected: + byte * cache; // cache memory + Query_cache_block *first_block; // physical location block list + Query_cache_block *queries_blocks; // query list (LIFO) + Query_cache_block *tables_blocks[Query_cache_table::TYPES_NUMBER]; + + Query_cache_memory_bin * bins; // free block lists + Query_cache_memory_bin_step * steps; // bins spacing info + uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin + + /* options */ + ulong query_cache_size, query_cache_limit, + min_allocation_unit, min_result_data_size; + uint def_query_hash_size, def_table_hash_size; + + /* statistics */ +public: + ulong free_memory, queries_in_cache, hits, inserts, refused; +protected: + my_bool initialized; + + /* + Locked when searched or changed global query or + tables lists or hashes. When operate inside + query structure locked own query block mutex + LOCK SEQUENCE (to prevent clinch): + 1. structure_guard_mutex + 2. query block / table block / free block + 3. results blocks (only when must become free). + */ + pthread_mutex_t structure_guard_mutex; + + HASH queries, tables; + + /* Exclude/include from cyclic double linked list */ + static void double_linked_list_exclude(Query_cache_block * point, + Query_cache_block * &list_pointer); + static void double_linked_list_simple_include(Query_cache_block * point, + Query_cache_block * + &list_pointer); + static void double_linked_list_join(Query_cache_block *head_tail, + Query_cache_block *tail_head); + + /* Table key generation */ + static uint filename_2_table_key (char * key, char *filename); + + /* Following function work properly only when structure_guard_mutex locked */ + void flush_cache(); + my_bool free_old_query(); + void free_query(Query_cache_block * point); + my_bool allocate_data_chain(Query_cache_block * &result_block, + ulong data_len, + Query_cache_block * query_block); + void invalidate_table(TABLE_LIST *table); + void invalidate_table(TABLE *table); + void invalidate_table_in_db(Query_cache_block *table_block, + char * db); + void invalidate_table(Query_cache_block *table_block); + my_bool register_all_tables(Query_cache_block * block, + TABLE_LIST * tables_used, + TABLE_COUNTER_TYPE tables); + my_bool insert_table(uint key_len, char * key, + Query_cache_block_table * node, + Query_cache_table::query_cache_table_type type); + void unlink_table(Query_cache_block_table * node); + Query_cache_block * get_free_block (ulong len, my_bool not_less, + ulong min); + void free_memory_block(Query_cache_block * point); + void split_block(Query_cache_block *block, ulong len); + Query_cache_block * join_free_blocks(Query_cache_block *first_block, + Query_cache_block * block_in_list); + my_bool append_next_free_block(Query_cache_block * block, + ulong add_size); + void exclude_from_free_memory_list(Query_cache_block * free_block); + void insert_into_free_memory_list(Query_cache_block * new_block); + my_bool move_by_type(byte * &border, Query_cache_block * &before, + ulong &gap, Query_cache_block * i); + uint find_bin(ulong size); + void move_to_query_list_end(Query_cache_block * block); + void insert_into_free_memory_sorted_list(Query_cache_block * new_block, + Query_cache_block * &list); + void pack_cache(); + void relink(Query_cache_block * oblock, + Query_cache_block * nblock, + Query_cache_block * next, + Query_cache_block * prev, + Query_cache_block * pnext, + Query_cache_block * pprev); + my_bool join_results(ulong join_limit); + + /* + Following function control structure_guard_mutex + by themself or don't need structure_guard_mutex + */ + void init(); + ulong init_cache(); + void make_disabled(); + void free_cache(my_bool destruction); + Query_cache_block * write_block_data(ulong data_len, gptr data, + ulong header_len, + Query_cache_block::block_type type, + TABLE_COUNTER_TYPE ntab = 0, + my_bool under_guard=0); + my_bool append_result_data(Query_cache_block * &result, + ulong data_len, gptr data, + Query_cache_block * parent, + Query_cache_block * first_data_block); + my_bool write_result_data(Query_cache_block * &result, + ulong data_len, gptr data, + Query_cache_block * parent, + Query_cache_block::block_type + type=Query_cache_block::RESULT); + Query_cache_block * allocate_block(ulong len, my_bool not_less, + ulong min, + my_bool under_guard=0); + /* + If query is cachable return numder tables in query + (query without tables not cached) + */ + TABLE_COUNTER_TYPE is_cachable(THD *thd, uint query_len, char *query, + LEX *lex, + TABLE_LIST *tables_used); + public: + + Query_cache(ulong query_cache_limit = ULONG_MAX, + ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT, + ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE, + uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE, + uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE + ); + + /* resize query cache (return real query size, 0 if disabled) */ + ulong resize(ulong query_cache_size); + inline void result_size_limit(ulong limit){query_cache_limit=limit;} + + /* register query in cache */ + void store_query(THD *thd, TABLE_LIST *used_tables); + + /* + Check if the query is in the cache and if this is true send the + data to client. + */ + my_bool send_result_to_client(THD *thd, char *query, uint query_length); + + /* Remove all queries that uses any of the listed following tables */ + void invalidate(TABLE_LIST *tables_used); + void invalidate(TABLE *table); + + /* Remove all queries that uses tables of pointed type*/ + void invalidate(Query_cache_table::query_cache_table_type type); + + /* Remove all queries that uses any of the tables in following database */ + void invalidate(char * db); + + /* Remove all queries that uses any of the listed following table */ + void invalidate_by_MyISAM_filename(char * filename); + + /* Remove all queries from cache */ + void flush(); + + /* Join result in cache in 1 block (if result length > join_limit) */ + void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT, + uint iteration_limit = QUERY_CACHE_PACK_ITERATION); + + void destroy(); + +#ifndef DBUG_OFF + void wreck(uint line, const char * message); + void bins_dump(); + void cache_dump(); + void queries_dump(); + void tables_dump(); +#endif + friend void query_cache_insert(NET *net, const char *packet, ulong length); + friend void query_cache_end_of_result(NET *net); + friend void query_cache_abort(NET *net); +}; + +extern Query_cache query_cache; + +#endif |