Commit afd0b378 authored by hf@deer.(none)'s avatar hf@deer.(none)

SCRUM

WL#1246 (Query cache in embedded library)
parent 3ee75849
......@@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \
noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc
libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c
noinst_HEADERS = embedded_priv.h
noinst_HEADERS = embedded_priv.h emb_qcache.h
sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
......
This diff is collapsed.
/* 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 */
class Querycache_stream
{
byte *cur_data;
byte *data_end;
Query_cache_block *block;
uint headers_len;
public:
#ifndef DBUG_OFF
uint stored_size;
#endif
Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) :
block(ini_block), headers_len(ini_headers_len)
{
use_next_block();
#ifndef DBUG_OFF
stored_size= 0;
#endif
}
void use_next_block()
{
cur_data= ((byte*)block)+headers_len;
data_end= cur_data + (block->used-headers_len);
}
void store_char(char c);
void store_short(ushort s);
void store_int(uint i);
void store_ll(ulonglong ll);
void store_str_only(const char *str, uint str_len);
void store_str(const char *str, uint str_len);
void store_safe_str(const char *str, uint str_len);
char load_char();
ushort load_short();
uint load_int();
ulonglong load_ll();
void load_str_only(char *buffer, uint str_len);
char *load_str(MEM_ROOT *alloc, uint *str_len);
int load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len);
int load_column(MEM_ROOT *alloc, char **column);
};
uint emb_count_querycache_size(THD *thd);
int emb_load_querycache_result(THD *thd, Querycache_stream *src);
void emb_store_querycache_result(Querycache_stream *dst, THD* thd);
......@@ -573,6 +573,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr;
client_field->catalog= strdup_root(field_alloc, "std");
client_field->catalog_length= 3;
if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG;
......@@ -583,9 +586,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp)))
{
client_field->def= strdup_root(field_alloc, "");
client_field->def_length= 0;
}
else
{
client_field->def= strdup_root(field_alloc, tmp.ptr());
client_field->def_length= tmp.length();
}
}
else
client_field->def=0;
......
......@@ -308,6 +308,10 @@ TODO list:
#include "../myisammrg/myrg_def.h"
#endif
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);}
......@@ -646,20 +650,24 @@ void query_cache_abort(NET *net)
}
void query_cache_end_of_result(NET *net)
void query_cache_end_of_result(THD *thd)
{
DBUG_ENTER("query_cache_end_of_result");
#ifdef EMBEDDED_LIBRARY
query_cache_insert(&thd->net, (byte*)thd,
emb_count_querycache_size(thd));
#endif
#ifndef DBUG_OFF
// Check if we have called query_cache.wreck() (which disables the cache)
if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
#endif
if (net->query_cache_query != 0) // Quick check on unlocked structure
if (thd->net.query_cache_query != 0) // Quick check on unlocked structure
{
STRUCT_LOCK(&query_cache.structure_guard_mutex);
Query_cache_block *query_block = ((Query_cache_block*)
net->query_cache_query);
thd->net.query_cache_query);
if (query_block)
{
DUMP(&query_cache);
......@@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net)
// Cache was flushed or resized and query was deleted => do nothing
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
}
net->query_cache_query=0;
thd->net.query_cache_query=0;
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
}
DBUG_VOID_RETURN;
......@@ -1052,23 +1060,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
/*
Send cached result to client
*/
#ifndef EMBEDDED_LIBRARY
do
{
DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
result_block->length, result_block->used,
result_block->headers_len()+
ALIGN_SIZE(sizeof(Query_cache_result))));
result_block->length, result_block->used,
result_block->headers_len()+
ALIGN_SIZE(sizeof(Query_cache_result))));
Query_cache_result *result = result_block->result();
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
if (net_real_write(&thd->net, result->data(),
result_block->used -
result_block->headers_len() -
ALIGN_SIZE(sizeof(Query_cache_result))))
break; // Client aborted
#endif
result_block = result_block->next;
} while (result_block != first_result_block);
#else
{
Querycache_stream qs(result_block, result_block->headers_len() +
ALIGN_SIZE(sizeof(Query_cache_result)));
emb_load_querycache_result(thd, &qs);
}
#endif /*!EMBEDDED_LIBRARY*/
thd->limit_found_rows = query->found_rows();
......@@ -1784,18 +1798,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
Query_cache_block *block = *result_block;
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result)));
#ifndef EMBEDDED_LIBRARY
// Now fill list of blocks that created by allocate_data_chain
do
{
block->type = type;
ulong length = block->used - headers_len;
DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length,
(ulong)block));
(ulong)block));
memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length);
rest += length;
block = block->next;
type = Query_cache_block::RES_CONT;
} while (block != *result_block);
#else
Querycache_stream qs(*result_block, headers_len);
emb_store_querycache_result(&qs, (THD*)data);
#endif /*!EMBEDDED_LIBRARY*/
}
else
{
......
......@@ -392,7 +392,7 @@ protected:
void destroy();
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_end_of_result(THD *thd);
friend void query_cache_abort(NET *net);
/*
......@@ -416,7 +416,7 @@ protected:
extern Query_cache query_cache;
extern TYPELIB query_cache_type_typelib;
void query_cache_end_of_result(NET *net);
void query_cache_end_of_result(THD *thd);
void query_cache_abort(NET *net);
#endif
......@@ -3886,9 +3886,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
else
{
mysql_execute_command(thd);
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
query_cache_end_of_result(&thd->net);
#endif
query_cache_end_of_result(thd);
}
}
}
......@@ -3896,9 +3894,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
{
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error));
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
query_cache_abort(&thd->net);
#endif
}
thd->proc_info="freeing items";
free_items(thd->free_list); /* Free strings used by items */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment