Commit 70701c64 authored by unknown's avatar unknown

Merge bk-internal:/home/bk/mysql-4.1/

into serg.mylan:/usr/home/serg/Abk/mysql-4.1


myisam/mi_check.c:
  Auto merged
myisam/mi_delete.c:
  Auto merged
myisam/mi_write.c:
  Auto merged
myisam/myisamchk.c:
  Auto merged
myisam/myisamdef.h:
  Auto merged
mysql-test/r/mysqldump.result:
  Auto merged
mysql-test/r/range.result:
  Auto merged
sql/ha_myisam.cc:
  Auto merged
sql/ha_myisam.h:
  Auto merged
sql/ha_myisammrg.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/item_cmpfunc.h:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_test.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
parents 40c2ce10 3897d2de
This diff is collapsed.
......@@ -46,6 +46,7 @@
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
#define HA_OPEN_ABORT_IF_CRASHED 16
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
#define HA_OPEN_TO_ASSIGN 64 /* Open for key cache assignment */
/* The following is parameter to ha_rkey() how to use key */
......@@ -131,7 +132,8 @@ enum ha_extra_function {
current query id */
HA_EXTRA_PREPARE_FOR_DELETE,
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
HA_EXTRA_SET_KEY_CACHE /* Set ref to assigned key cache */
};
/* The following is parameter to ha_panic() */
......
......@@ -558,6 +558,9 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
/* Typical key cash */
#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
/* Default size of a key cache block */
#define KEY_CACHE_BLOCK_SIZE (uint) 1024
/* Some things that this system doesn't have */
......
......@@ -111,8 +111,6 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024
#define MAX_KEYCACHE_BLOCK_SIZE 16384
/* root_alloc flags */
#define MY_KEEP_PREALLOC 1
......@@ -267,7 +265,8 @@ enum cache_type
enum flush_type
{
FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE
FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED, FLUSH_FORCE_WRITE,
FLUSH_REMOVE
};
typedef struct st_record_cache /* Used when cacheing records */
......@@ -504,14 +503,46 @@ my_off_t my_b_append_tell(IO_CACHE* info);
#define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \
*(info)->current_pos)
/* key_cache_variables */
typedef struct st_keycache
{
ulonglong size;
} KEY_CACHE;
typedef uint32 ha_checksum;
/* Pointer to a key cache data structure (see the key cache module) */
typedef struct st_key_cache* KEY_CACHE_HANDLE;
/* Key cache variable structure */
/*
The structure contains the parameters of a key cache that can
be set and undated by regular set global statements.
It also contains read-only statistics parameters.
If the corresponding key cache data structure has been already
created the variable contains the key cache handle.
The variables are put into a named list called key_caches.
At present the variables are only added to this list.
*/
typedef struct st_key_cache_var
{
ulonglong buff_size; /* size the memory allocated for the cache */
ulong block_size; /* size of the blocks in the key cache */
ulong division_limit; /* min. percentage of warm blocks */
ulong age_threshold; /* determines when hot block is downgraded */
KEY_CACHE_HANDLE cache; /* handles for the current and registered */
ulong blocks_used; /* number of currently used blocks */
ulong blocks_changed; /* number of currently dirty blocks */
ulong cache_w_requests; /* number of write requests (write hits) */
ulong cache_write; /* number of writes from the cache to files */
ulong cache_r_requests; /* number of read requests (read hits) */
ulong cache_read; /* number of reads from files to the cache */
int blocks; /* max number of blocks in the cache */
struct st_key_cache_asmt *assign_list; /* list of assignments to the cache */
int assignments; /* number of not completed assignments */
void (*action)(void *); /* optional call back function */
void *extra_info; /* ptr to extra info */
} KEY_CACHE_VAR;
#define DEFAULT_KEY_CACHE_NAME "default"
extern KEY_CACHE_HANDLE *dflt_keycache;
extern KEY_CACHE_VAR dflt_key_cache_var;
#define DFLT_INIT_HITS 3
#include <my_alloc.h>
/* Prototypes for mysys and my_func functions */
......@@ -650,16 +681,26 @@ extern int flush_write_cache(RECORD_CACHE *info);
extern long my_clock(void);
extern sig_handler sigtstp_handler(int signal_number);
extern void handle_recived_signals(void);
extern int init_key_cache(ulong use_mem);
extern int resize_key_cache(ulong use_mem);
extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length,
extern int init_key_cache(KEY_CACHE_HANDLE *pkeycache,
uint key_cache_block_size,
ulong use_mem, KEY_CACHE_VAR* env);
extern int resize_key_cache(KEY_CACHE_HANDLE *pkeycache,
uint key_cache_block_size, ulong use_mem);
extern void change_key_cache_param(KEY_CACHE_HANDLE keycache);
extern byte *key_cache_read(KEY_CACHE_HANDLE keycache,
File file, my_off_t filepos, int level,
byte* buff, uint length,
uint block_length,int return_buffer);
extern int key_cache_insert(File file, my_off_t filepos,
extern int key_cache_insert(KEY_CACHE_HANDLE keycache,
File file, my_off_t filepos, int level,
byte *buff, uint length);
extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length,
extern int key_cache_write(KEY_CACHE_HANDLE keycache,
File file, my_off_t filepos, int level,
byte* buff, uint length,
uint block_length,int force_write);
extern int flush_key_blocks(int file, enum flush_type type);
extern void end_key_cache(void);
extern int flush_key_blocks(KEY_CACHE_HANDLE keycache,
int file, enum flush_type type);
extern void end_key_cache(KEY_CACHE_HANDLE *pkeycache,my_bool cleanup);
extern sig_handler my_set_alarm_variable(int signo);
extern void my_string_ptr_sort(void *base,uint items,size_s size);
extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
......
......@@ -408,6 +408,9 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
void mi_flush_bulk_insert(MI_INFO *info, uint inx);
void mi_end_bulk_insert(MI_INFO *info);
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
KEY_CACHE_VAR *key_cache,
pthread_mutex_t *assign_lock);
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
#ifdef __cplusplus
......
......@@ -50,7 +50,7 @@ int nisam_lock_database(N_INFO *info, int lock_type)
else
count= --share->w_locks;
if (info->lock_type == F_WRLCK && !share->w_locks &&
flush_key_blocks(share->kfile,FLUSH_KEEP))
flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_KEEP))
error=my_errno;
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
if (end_io_cache(&info->rec_cache))
......@@ -329,7 +329,7 @@ int _nisam_test_if_changed(register N_INFO *info)
share->state.uniq != info->last_uniq)
{ /* Keyfile has changed */
if (share->state.process != share->this_process)
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
VOID(flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_RELEASE));
share->last_process=share->state.process;
info->last_loop= share->state.loop;
info->last_uniq= share->state.uniq;
......
......@@ -27,10 +27,11 @@ uchar *_nisam_fetch_keypage(register N_INFO *info, N_KEYDEF *keyinfo,
my_off_t page, uchar *buff, int return_buffer)
{
uchar *tmp;
tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff,
(uint) keyinfo->base.block_length,
(uint) keyinfo->base.block_length,
return_buffer);
tmp=(uchar*) key_cache_read(*dflt_keycache,
info->s->kfile,page,DFLT_INIT_HITS,(byte*) buff,
(uint) keyinfo->base.block_length,
(uint) keyinfo->base.block_length,
return_buffer);
if (tmp == info->buff)
{
info->update|=HA_STATE_BUFF_SAVED;
......@@ -83,9 +84,11 @@ int _nisam_write_keypage(register N_INFO *info, register N_KEYDEF *keyinfo,
length=keyinfo->base.block_length;
}
#endif
return (key_cache_write(info->s->kfile,page,(byte*) buff,length,
(uint) keyinfo->base.block_length,
(int) (info->lock_type != F_UNLCK)));
return (key_cache_write(*dflt_keycache,
info->s->kfile,page,DFLT_INIT_HITS,
(byte*) buff,length,
(uint) keyinfo->base.block_length,
(int) (info->lock_type != F_UNLCK)));
} /* nisam_write_keypage */
......@@ -99,7 +102,9 @@ int _nisam_dispose(register N_INFO *info, N_KEYDEF *keyinfo, my_off_t pos)
old_link=info->s->state.key_del[keynr];
info->s->state.key_del[keynr]=(ulong) pos;
DBUG_RETURN(key_cache_write(info->s->kfile,pos,(byte*) &old_link,
DBUG_RETURN(key_cache_write(*dflt_keycache,
info->s->kfile,pos,DFLT_INIT_HITS,
(byte*) &old_link,
sizeof(long),
(uint) keyinfo->base.block_length,
(int) (info->lock_type != F_UNLCK)));
......@@ -126,7 +131,8 @@ ulong _nisam_new(register N_INFO *info, N_KEYDEF *keyinfo)
}
else
{
if (!key_cache_read(info->s->kfile,pos,
if (!key_cache_read(*dflt_keycache,
info->s->kfile,pos,DFLT_INIT_HITS,
(byte*) &info->s->state.key_del[keynr],
(uint) sizeof(long),
(uint) keyinfo->base.block_length,0))
......
......@@ -56,7 +56,8 @@ int nisam_close(register N_INFO *info)
if (flag)
{
if (share->kfile >= 0 && flush_key_blocks(share->kfile,FLUSH_RELEASE))
if (share->kfile >= 0 &&
flush_key_blocks(*dflt_keycache,share->kfile,FLUSH_RELEASE))
error=my_errno;
if (share->kfile >= 0 && my_close(share->kfile,MYF(0)))
error = my_errno;
......
......@@ -516,7 +516,8 @@ static int nisamchk(my_string filename)
if (!rep_quick)
{
if (testflag & T_EXTEND)
VOID(init_key_cache(use_buffers));
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,
use_buffers,&dflt_key_cache_var));
VOID(init_io_cache(&read_cache,datafile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,
MYF(MY_WME)));
......@@ -1459,7 +1460,8 @@ my_string name;
printf("Data records: %lu\n",(ulong) share->state.records);
}
VOID(init_key_cache(use_buffers));
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,use_buffers,
&dflt_key_cache_var));
if (init_io_cache(&read_cache,info->dfile,(uint) read_buffer_length,
READ_CACHE,share->pack.header_length,1,MYF(MY_WME)))
goto err;
......@@ -1887,12 +1889,12 @@ static void lock_memory(void)
static int flush_blocks(file)
File file;
{
if (flush_key_blocks(file,FLUSH_RELEASE))
if (flush_key_blocks(dflt_keycache,file,FLUSH_RELEASE))
{
print_error("%d when trying to write bufferts",my_errno);
return(1);
}
end_key_cache();
end_key_cache(dflt_keycache,1);
return 0;
} /* flush_blocks */
......@@ -1936,7 +1938,8 @@ int write_info;
if (share->state.key_root[sort_key] == NI_POS_ERROR)
DBUG_RETURN(0); /* Nothing to do */
init_key_cache(use_buffers);
init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,use_buffers,
&dflt_key_cache_var);
if (init_io_cache(&info->rec_cache,-1,(uint) write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
......
......@@ -329,8 +329,8 @@ static int examine_log(my_string file_name, char **table_names)
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
(tree_element_free) file_info_free, NULL);
VOID(init_key_cache(KEY_CACHE_SIZE));
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
&dflt_key_cache_var));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
!my_b_read(&cache,(byte*) head,9))
......@@ -622,7 +622,7 @@ static int examine_log(my_string file_name, char **table_names)
goto end;
}
}
end_key_cache();
end_key_cache(dflt_keycache,1);
delete_tree(&tree);
VOID(end_io_cache(&cache));
VOID(my_close(file,MYF(0)));
......@@ -642,7 +642,7 @@ static int examine_log(my_string file_name, char **table_names)
llstr(isamlog_filepos,llbuff)));
fflush(stderr);
end:
end_key_cache();
end_key_cache(dflt_keycache,1);
delete_tree(&tree);
VOID(end_io_cache(&cache));
VOID(my_close(file,MYF(0)));
......
......@@ -48,7 +48,7 @@ int nisam_panic(enum ha_panic_function flag)
if (info->s->base.options & HA_OPTION_READ_ONLY_DATA)
break;
#endif
if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
if (flush_key_blocks(*dflt_keycache,info->s->kfile,FLUSH_RELEASE))
error=my_errno;
if (info->opt_flag & WRITE_CACHE_USED)
if (flush_io_cache(&info->rec_cache))
......
......@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
goto err;
printf("- Writing key:s\n");
if (key_cacheing)
init_key_cache(IO_SIZE*16); /* Use a small cache */
init_key_cache(dflt_keycache,512,IO_SIZE*16,0); /* Use a small cache */
if (locking)
nisam_lock_database(file,F_WRLCK);
if (write_cacheing)
......@@ -674,7 +674,7 @@ int main(int argc, char *argv[])
puts("Locking used");
if (use_blob)
puts("blobs used");
end_key_cache();
end_key_cache(&dflt_keycache,1);
if (blob_buffer)
my_free(blob_buffer,MYF(0));
my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
......
......@@ -173,7 +173,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
init_key_cache(65536L);
init_key_cache(dflt_keycache,512,65536L,0);
printf("Process %d, pid: %d\n",id,(int) getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
......
......@@ -47,7 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
mi_range.c mi_dbug.c mi_checksum.c mi_log.c \
mi_changed.c mi_static.c mi_delete_all.c \
mi_delete_table.c mi_rename.c mi_check.c \
mi_preload.c \
mi_keycache.c mi_preload.c \
ft_parser.c ft_stopwords.c ft_static.c \
ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
......
......@@ -241,7 +241,9 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
if (next_link > info->state->key_file_length ||
next_link & (info->s->blocksize-1))
DBUG_RETURN(1);
if (!(buff=key_cache_read(info->s->kfile, next_link, (byte*) info->buff,
if (!(buff=key_cache_read(*info->s->keycache,
info->s->kfile, next_link, DFLT_INIT_HITS,
(byte*) info->buff,
myisam_block_size, block_size, 1)))
DBUG_RETURN(1);
next_link=mi_sizekorr(buff);
......@@ -270,7 +272,8 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
if (!(param->testflag & T_SILENT)) puts("- check file-size");
flush_key_blocks(info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */
flush_key_blocks(*info->s->keycache,
info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
if ((skr=(my_off_t) info->state->key_file_length) != size)
......@@ -380,8 +383,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
if (share->state.key_root[key] == HA_OFFSET_ERROR &&
(info->state->records == 0 || keyinfo->flag & HA_FULLTEXT))
continue;
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],info->buff,
0))
if (!_mi_fetch_keypage(info,keyinfo,share->state.key_root[key],
DFLT_INIT_HITS,info->buff,0))
{
mi_check_print_error(param,"Can't read indexpage from filepos: %s",
llstr(share->state.key_root[key],buff));
......@@ -559,7 +562,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
info->state->key_file_length=(max_length &
~ (my_off_t) (info->s->blocksize-1));
}
if (!_mi_fetch_keypage(info,keyinfo,next_page,temp_buff,0))
if (!_mi_fetch_keypage(info,keyinfo,next_page,
DFLT_INIT_HITS,temp_buff,0))
{
mi_check_print_error(param,"Can't read key from filepos: %s",llstr(next_page,llbuff));
goto err;
......@@ -1138,7 +1142,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->testflag|=T_REP; /* for easy checking */
if (!param->using_global_keycache)
VOID(init_key_cache(param->use_buffers));
VOID(init_key_cache(dflt_keycache,dflt_key_cache_var.block_size,
param->use_buffers,&dflt_key_cache_var));
if (init_io_cache(&param->read_cache,info->dfile,
(uint) param->read_buffer_length,
......@@ -1459,7 +1464,8 @@ int movepoint(register MI_INFO *info, byte *record, my_off_t oldpos,
nod_flag=mi_test_if_nod(info->buff);
_mi_dpointer(info,info->int_keypos-nod_flag-
info->s->rec_reflength,newpos);
if (_mi_write_keypage(info,keyinfo,info->last_keypage,info->buff))
if (_mi_write_keypage(info,keyinfo,info->last_keypage,
DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
}
else
......@@ -1496,13 +1502,13 @@ void lock_memory(MI_CHECK *param __attribute__((unused)))
int flush_blocks(MI_CHECK *param, File file)
{
if (flush_key_blocks(file,FLUSH_RELEASE))
if (flush_key_blocks(*dflt_keycache,file,FLUSH_RELEASE))
{
mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
return(1);
}
if (!param->using_global_keycache)
end_key_cache();
end_key_cache(dflt_keycache,1);
return 0;
} /* flush_blocks */
......@@ -1557,7 +1563,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
}
/* Flush key cache for this file if we are calling this outside myisamchk */
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
share->state.version=(ulong) time((time_t*) 0);
old_state= share->state; /* save state if not stored */
......@@ -1621,7 +1627,7 @@ static int sort_one_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
mi_check_print_error(param,"Not Enough memory");
DBUG_RETURN(-1);
}
if (!_mi_fetch_keypage(info,keyinfo,pagepos,buff,0))
if (!_mi_fetch_keypage(info,keyinfo,pagepos,DFLT_INIT_HITS,buff,0))
{
mi_check_print_error(param,"Can't read key block from filepos: %s",
llstr(pagepos,llbuff));
......@@ -1867,7 +1873,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
Flush key cache for this file if we are calling this outside
myisamchk
*/
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
......@@ -1877,7 +1883,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
}
else
{
if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
goto err;
key_map= ~key_map; /* Create the missing keys */
}
......@@ -2230,7 +2236,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
Flush key cache for this file if we are calling this outside
myisamchk
*/
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
......@@ -2240,7 +2246,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
}
else
{
if (flush_key_blocks(share->kfile, FLUSH_FORCE_WRITE))
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
goto err;
key_map= ~key_map; /* Create the missing keys */
}
......@@ -3354,13 +3360,13 @@ static int sort_insert_key(MI_SORT_PARAM *sort_param,
bzero((byte*) anc_buff+key_block->last_length,
keyinfo->block_length- key_block->last_length);
key_file_length=info->state->key_file_length;
if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back to it */
if (key_file_length == info->state->key_file_length)
{
if (_mi_write_keypage(info, keyinfo, filepos, anc_buff))
if (_mi_write_keypage(info, keyinfo, filepos, DFLT_INIT_HITS, anc_buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) anc_buff,
......@@ -3458,13 +3464,14 @@ int flush_pending_blocks(MI_SORT_PARAM *sort_param)
_mi_kpointer(info,key_block->end_pos,filepos);
key_file_length=info->state->key_file_length;
bzero((byte*) key_block->buff+length, keyinfo->block_length-length);
if ((filepos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
if ((filepos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* If we read the page from the key cache, we have to write it back */
if (key_file_length == info->state->key_file_length)
{
if (_mi_write_keypage(info, keyinfo, filepos, key_block->buff))
if (_mi_write_keypage(info, keyinfo, filepos,
DFLT_INIT_HITS, key_block->buff))
DBUG_RETURN(1);
}
else if (my_pwrite(info->s->kfile,(byte*) key_block->buff,
......
......@@ -64,7 +64,7 @@ int mi_close(register MI_INFO *info)
if (flag)
{
if (share->kfile >= 0 &&
flush_key_blocks(share->kfile,
flush_key_blocks(*share->keycache,share->kfile,
share->temporary ? FLUSH_IGNORE_CHANGED :
FLUSH_RELEASE))
error=my_errno;
......
......@@ -156,7 +156,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
DBUG_RETURN(my_errno=ENOMEM);
}
DBUG_PRINT("info",("root_page: %ld",old_root));
if (!_mi_fetch_keypage(info,keyinfo,old_root,root_buff,0))
if (!_mi_fetch_keypage(info,keyinfo,old_root,DFLT_INIT_HITS,root_buff,0))
{
error= -1;
goto err;
......@@ -180,11 +180,12 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo,
*root=_mi_kpos(nod_flag,root_buff+2+nod_flag);
else
*root=HA_OFFSET_ERROR;
if (_mi_dispose(info,keyinfo,old_root))
if (_mi_dispose(info,keyinfo,old_root,DFLT_INIT_HITS))
error= -1;
}
else
error=_mi_write_keypage(info,keyinfo,old_root,root_buff);
error=_mi_write_keypage(info,keyinfo,old_root,
DFLT_INIT_HITS,root_buff);
}
}
err:
......@@ -262,7 +263,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (subkeys == -1)
{
/* the last entry in sub-tree */
_mi_dispose(info, keyinfo, root);
_mi_dispose(info, keyinfo, root,DFLT_INIT_HITS);
/* fall through to normal delete */
}
else
......@@ -276,7 +277,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
subkeys++;
ft_intXstore(kpos, subkeys);
if (!ret_value)
ret_value=_mi_write_keypage(info,keyinfo,page,anc_buff);
ret_value=_mi_write_keypage(info,keyinfo,page,
DFLT_INIT_HITS,anc_buff);
DBUG_PRINT("exit",("Return: %d",ret_value));
DBUG_RETURN(ret_value);
}
......@@ -295,7 +297,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_PRINT("exit",("Return: %d",-1));
DBUG_RETURN(-1);
}
if (!_mi_fetch_keypage(info,keyinfo,leaf_page,leaf_buff,0))
if (!_mi_fetch_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff,0))
goto err;
}
......@@ -327,7 +329,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
mi_putint(anc_buff,length,nod_flag);
if (!nod_flag)
{ /* On leaf page */
if (_mi_write_keypage(info,keyinfo,page,anc_buff))
if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff))
{
DBUG_PRINT("exit",("Return: %d",-1));
DBUG_RETURN(-1);
......@@ -362,7 +364,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
ret_value=_mi_split_page(info,keyinfo,key,anc_buff,lastkey,0) | 2;
}
if (save_flag && ret_value != 1)
ret_value|=_mi_write_keypage(info,keyinfo,page,anc_buff);
ret_value|=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,anc_buff);
else
{
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
......@@ -406,7 +408,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
if (!(next_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MI_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_mi_fetch_keypage(info,keyinfo,next_page,next_buff,0))
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,next_buff,0))
ret_value= -1;
else
{
......@@ -434,7 +436,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
(uchar*) 0,(uchar*) 0,(my_off_t) 0,0);
}
}
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
goto err;
}
my_afree((byte*) next_buff);
......@@ -444,7 +446,7 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key,
/* Remove last key from leaf page */
mi_putint(leaf_buff,key_start-leaf_buff,nod_flag);
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
goto err;
/* Place last key in ancestor page on deleted key position */
......@@ -532,7 +534,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
goto err;
}
next_page= _mi_kpos(key_reflength,next_keypos);
if (!_mi_fetch_keypage(info,keyinfo,next_page,buff,0))
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
goto err;
buff_length=mi_getint(buff);
DBUG_DUMP("next",(byte*) buff,buff_length);
......@@ -571,7 +573,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (buff_length <= keyinfo->block_length)
{ /* Keys in one page */
memcpy((byte*) leaf_buff,(byte*) buff,(size_t) buff_length);
if (_mi_dispose(info,keyinfo,next_page))
if (_mi_dispose(info,keyinfo,next_page,DFLT_INIT_HITS))
goto err;
}
else
......@@ -620,10 +622,10 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
(*keyinfo->store_key)(keyinfo,buff+p_length,&s_temp);
mi_putint(buff,length+t_length+p_length,nod_flag);
if (_mi_write_keypage(info,keyinfo,next_page,buff))
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
goto err;
}
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
goto err;
DBUG_RETURN(anc_length <= ((info->quick_mode ? MI_MIN_BLOCK_LENGTH :
(uint) keyinfo->underflow_block_length)));
......@@ -635,7 +637,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (!keypos)
goto err;
next_page= _mi_kpos(key_reflength,keypos);
if (!_mi_fetch_keypage(info,keyinfo,next_page,buff,0))
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff,0))
goto err;
buff_length=mi_getint(buff);
endpos=buff+buff_length;
......@@ -679,7 +681,7 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (buff_length <= keyinfo->block_length)
{ /* Keys in one page */
if (_mi_dispose(info,keyinfo,leaf_page))
if (_mi_dispose(info,keyinfo,leaf_page,DFLT_INIT_HITS))
goto err;
}
else
......@@ -726,11 +728,11 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo,
(size_t) length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length,&s_temp);
mi_putint(leaf_buff,length+t_length+p_length,nod_flag);
if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff))
if (_mi_write_keypage(info,keyinfo,leaf_page,DFLT_INIT_HITS,leaf_buff))
goto err;
mi_putint(buff,endpos-buff,nod_flag);
}
if (_mi_write_keypage(info,keyinfo,next_page,buff))
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,buff))
goto err;
DBUG_RETURN(anc_length <= (uint) keyinfo->block_length/2);
err:
......
......@@ -53,7 +53,7 @@ int mi_delete_all_rows(MI_INFO *info)
If we are using delayed keys or if the user has done changes to the tables
since it was locked then there may be key blocks in the key cache
*/
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
flush_key_blocks(*share->keycache, share->kfile, FLUSH_IGNORE_CHANGED);
if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) )
goto err;
......
......@@ -283,7 +283,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock(&share->intern_lock);
if (flush_key_blocks(share->kfile,
if (flush_key_blocks(*share->keycache, share->kfile,
(function == HA_EXTRA_FORCE_REOPEN ?
FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
{
......@@ -329,7 +329,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
break;
case HA_EXTRA_FLUSH:
if (!share->temporary)
flush_key_blocks(share->kfile,FLUSH_KEEP);
flush_key_blocks(*share->keycache,share->kfile,FLUSH_KEEP);
#ifdef HAVE_PWRITE
_mi_decrement_open_count(info);
#endif
......@@ -374,6 +374,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
info->preload_buff_size= *((ulong *) extra_arg);
break;
case HA_EXTRA_SET_KEY_CACHE:
share->reg_keycache= share->keycache= (KEY_CACHE_HANDLE *) extra_arg;
break;
case HA_EXTRA_KEY_CACHE:
case HA_EXTRA_NO_KEY_CACHE:
default:
......
/* 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 */
/*
Key cache assignments
*/
#include "myisamdef.h"
/*
Assign pages of the index file for a table to a key cache
SYNOPSIS
mi_assign_to_keycache()
info open table
map map of indexes to assign to the key cache
key_cache_ptr pointer to the key cache handle
RETURN VALUE
0 if a success. error code - otherwise.
NOTES.
At present pages for all indexes must be assigned to the same key cache.
In future only pages for indexes specified in the key_map parameter
of the table will be assigned to the specified key cache.
*/
typedef struct st_assign_extra_info
{
pthread_mutex_t *lock;
struct st_my_thread_var *waiting_thread;
} ASSIGN_EXTRA_INFO;
static void remove_key_cache_assign(void *arg)
{
KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) arg;
ASSIGN_EXTRA_INFO *extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info;
struct st_my_thread_var *waiting_thread;
pthread_mutex_t *lock= extra_info->lock;
pthread_mutex_lock(lock);
if (!(--key_cache->assignments) &&
(waiting_thread = extra_info->waiting_thread))
{
my_free(extra_info, MYF(0));
key_cache->extra_info= 0;
if (waiting_thread != my_thread_var)
pthread_cond_signal(&waiting_thread->suspend);
}
pthread_mutex_unlock(lock);
}
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
KEY_CACHE_VAR *key_cache,
pthread_mutex_t *assign_lock)
{
ASSIGN_EXTRA_INFO *extra_info;
int error= 0;
MYISAM_SHARE* share= info->s;
DBUG_ENTER("mi_assign_to_keycache");
share->reg_keycache= &key_cache->cache;
pthread_mutex_lock(assign_lock);
if (!(extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info))
{
if (!(extra_info= (ASSIGN_EXTRA_INFO*) my_malloc(sizeof(ASSIGN_EXTRA_INFO),
MYF(MY_WME | MY_ZEROFILL))))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
key_cache->extra_info= extra_info;
key_cache->action= remove_key_cache_assign;
extra_info->lock= assign_lock;
}
key_cache->assignments++;
pthread_mutex_unlock(assign_lock);
if (!(info->lock_type == F_WRLCK && share->w_locks))
{
if (flush_key_blocks(*share->keycache, share->kfile, FLUSH_REMOVE))
{
error=my_errno;
mi_mark_crashed(info); /* Mark that table must be checked */
}
share->keycache= &key_cache->cache;
}
else
{
extra_info->waiting_thread= my_thread_var;
}
DBUG_RETURN(error);
}
......@@ -34,6 +34,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
uint count;
MYISAM_SHARE *share=info->s;
uint flag;
uint switch_fl= 0;
DBUG_ENTER("mi_lock_database");
DBUG_PRINT("info",("lock_type: %d", lock_type));
......@@ -60,12 +61,21 @@ int mi_lock_database(MI_INFO *info, int lock_type)
else
count= --share->w_locks;
--share->tot_locks;
/*
During a key cache reassignment the current and registered
key caches for the table are different.
*/
if (info->lock_type == F_WRLCK && !share->w_locks &&
!share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP))
((switch_fl= share->keycache != share->reg_keycache) ||
!share->delay_key_write) &&
flush_key_blocks(*share->keycache, share->kfile,
switch_fl ? FLUSH_REMOVE : FLUSH_KEEP))
{
error=my_errno;
mi_mark_crashed(info); /* Mark that table must be checked */
}
if (switch_fl)
share->keycache= share->reg_keycache;
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
if (end_io_cache(&info->rec_cache))
......@@ -400,7 +410,7 @@ int _mi_test_if_changed(register MI_INFO *info)
{ /* Keyfile has changed */
DBUG_PRINT("info",("index file changed"));
if (share->state.process != share->this_process)
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
VOID(flush_key_blocks(*share->keycache,share->kfile,FLUSH_RELEASE));
share->last_process=share->state.process;
info->last_unique= share->state.unique;
info->last_loop= share->state.update_count;
......
......@@ -24,14 +24,16 @@
/* Fetch a key-page in memory */
uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
my_off_t page, uchar *buff, int return_buffer)
my_off_t page, int level,
uchar *buff, int return_buffer)
{
uchar *tmp;
uint page_size;
DBUG_ENTER("_mi_fetch_keypage");
DBUG_PRINT("enter",("page: %ld",page));
tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff,
tmp=(uchar*) key_cache_read(*info->s->keycache,
info->s->kfile, page, level, (byte*) buff,
(uint) keyinfo->block_length,
(uint) keyinfo->block_length,
return_buffer);
......@@ -61,7 +63,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
/* Write a key-page on disk */
int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
my_off_t page, uchar *buff)
my_off_t page, int level, uchar *buff)
{
reg3 uint length;
DBUG_ENTER("_mi_write_keypage");
......@@ -92,7 +94,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
length=keyinfo->block_length;
}
#endif
DBUG_RETURN((key_cache_write(info->s->kfile,page,(byte*) buff,length,
DBUG_RETURN((key_cache_write(*info->s->keycache,
info->s->kfile,page, level, (byte*) buff,length,
(uint) keyinfo->block_length,
(int) ((info->lock_type != F_UNLCK) ||
info->s->delay_key_write))));
......@@ -101,7 +104,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
/* Remove page from disk */
int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos,
int level)
{
my_off_t old_link;
char buff[8];
......@@ -112,7 +116,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
info->s->state.key_del[keyinfo->block_size]=pos;
mi_sizestore(buff,old_link);
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
DBUG_RETURN(key_cache_write(info->s->kfile,pos,buff,
DBUG_RETURN(key_cache_write(*info->s->keycache,
info->s->kfile, pos , level, buff,
sizeof(buff),
(uint) keyinfo->block_length,
(int) (info->lock_type != F_UNLCK)));
......@@ -121,7 +126,7 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
/* Make new page on disk */
my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
{
my_off_t pos;
char buff[8];
......@@ -140,7 +145,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
}
else
{
if (!key_cache_read(info->s->kfile,pos,
if (!key_cache_read(*info->s->keycache,
info->s->kfile, pos, level,
buff,
(uint) sizeof(buff),
(uint) keyinfo->block_length,0))
......
......@@ -48,7 +48,7 @@ int mi_panic(enum ha_panic_function flag)
if (info->s->options & HA_OPTION_READ_ONLY_DATA)
break;
#endif
if (flush_key_blocks(info->s->kfile,FLUSH_RELEASE))
if (flush_key_blocks(*info->s->keycache,info->s->kfile,FLUSH_RELEASE))
error=my_errno;
if (info->opt_flag & WRITE_CACHE_USED)
if (flush_io_cache(&info->rec_cache))
......
......@@ -69,7 +69,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
if (flush_key_blocks(share->kfile, FLUSH_RELEASE))
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_RELEASE))
goto err;
do
......@@ -87,7 +87,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
if (mi_test_if_nod(buff))
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length))
if (key_cache_insert(*share->keycache,
share->kfile, pos, DFLT_INIT_HITS,
(byte*) buff, block_length))
goto err;
}
pos+= block_length;
......@@ -97,7 +99,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
}
else
{
if (key_cache_insert(share->kfile, pos, (byte*) buff, length))
if (key_cache_insert(*share->keycache,
share->kfile, pos, DFLT_INIT_HITS,
(byte*) buff, length))
goto err;
pos+= length;
}
......
......@@ -142,7 +142,7 @@ static double _mi_search_pos(register MI_INFO *info,
if (pos == HA_OFFSET_ERROR)
DBUG_RETURN(0.5);
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,1)))
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,1)))
goto err;
flag=(*keyinfo->bin_search)(info,keyinfo,buff,key,key_len,nextflag,
&keypos,info->lastkey, &after_key);
......
......@@ -76,7 +76,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_RETURN(1); /* Search at upper levels */
}
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
DBUG_DUMP("page",(byte*) buff,mi_getint(buff));
......@@ -119,7 +119,7 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (pos != info->last_keypage)
{
uchar *old_buff=buff;
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,info->buff,
if (!(buff=_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,
test(!(nextflag & SEARCH_SAVE_BUFF)))))
goto err;
keypos=buff+(keypos-old_buff);
......@@ -1108,7 +1108,7 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (info->buff_used)
{
if (!_mi_fetch_keypage(info,keyinfo,info->last_search_keypage,
info->buff,0))
DFLT_INIT_HITS,info->buff,0))
DBUG_RETURN(-1);
info->buff_used=0;
}
......@@ -1177,7 +1177,7 @@ int _mi_search_first(register MI_INFO *info, register MI_KEYDEF *keyinfo,
do
{
if (!_mi_fetch_keypage(info,keyinfo,pos,info->buff,0))
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,info->buff,0))
{
info->lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
......@@ -1220,7 +1220,7 @@ int _mi_search_last(register MI_INFO *info, register MI_KEYDEF *keyinfo,
buff=info->buff;
do
{
if (!_mi_fetch_keypage(info,keyinfo,pos,buff,0))
if (!_mi_fetch_keypage(info,keyinfo,pos,DFLT_INIT_HITS,buff,0))
{
info->lastpos= HA_OFFSET_ERROR;
DBUG_RETURN(-1);
......
......@@ -50,7 +50,7 @@ int main(int argc,char *argv[])
MY_INIT(argv[0]);
my_init();
if (key_cacheing)
init_key_cache(IO_SIZE*16);
init_key_cache(dflt_keycache,512,IO_SIZE*16,0);
get_options(argc,argv);
exit(run_test("test1"));
......
......@@ -49,6 +49,7 @@ static int verbose=0,testflag=0,
static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1,
create_flag=0;
static ulong key_cache_size=IO_SIZE*16;
static uint key_cache_block_size=IO_SIZE;
static uint keys=MYISAM_KEYS,recant=1000;
static uint use_blob=0;
......@@ -214,7 +215,7 @@ int main(int argc, char *argv[])
if (!silent)
printf("- Writing key:s\n");
if (key_cacheing)
init_key_cache(key_cache_size); /* Use a small cache */
init_key_cache(dflt_keycache,key_cache_block_size,key_cache_size,0); /* Use a small cache */
if (locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
......@@ -274,7 +275,7 @@ int main(int argc, char *argv[])
goto end;
}
if (key_cacheing)
resize_key_cache(key_cache_size*2);
resize_key_cache(dflt_keycache,key_cache_block_size,key_cache_size*2);
}
if (!silent)
......@@ -816,16 +817,19 @@ int main(int argc, char *argv[])
puts("Locking used");
if (use_blob)
puts("blobs used");
#if 0
printf("key cache status: \n\
blocks used:%10lu\n\
w_requests: %10lu\n\
writes: %10lu\n\
r_requests: %10lu\n\
reads: %10lu\n",
my_blocks_used, my_cache_w_requests, my_cache_write,
my_blocks_used,
my_cache_w_requests, my_cache_write,
my_cache_r_requests, my_cache_read);
#endif
}
end_key_cache();
end_key_cache(dflt_keycache,1);
if (blob_buffer)
my_free(blob_buffer,MYF(0));
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
......
......@@ -177,7 +177,7 @@ void start_test(int id)
exit(1);
}
if (key_cacheing && rnd(2) == 0)
init_key_cache(65536L);
init_key_cache(dflt_keycache,512,65536L,0);
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
for (error=i=0 ; i < tests && !error; i++)
......
......@@ -310,8 +310,8 @@ int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
mi_putint(info->buff,t_length+2+nod_flag,nod_flag);
(*keyinfo->store_key)(keyinfo,info->buff+2+nod_flag,&s_temp);
info->buff_used=info->page_changed=1; /* info->buff is used */
if ((*root= _mi_new(info,keyinfo)) == HA_OFFSET_ERROR ||
_mi_write_keypage(info,keyinfo,*root,info->buff))
if ((*root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR ||
_mi_write_keypage(info,keyinfo,*root,DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
DBUG_RETURN(0);
} /* _mi_enlarge_root */
......@@ -342,7 +342,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (!(temp_buff= (uchar*) my_alloca((uint) keyinfo->block_length+
MI_MAX_KEY_BUFF*2)))
DBUG_RETURN(-1);
if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0))
if (!_mi_fetch_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff,0))
goto err;
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
......@@ -386,7 +386,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ASSERT(subkeys < 0);
ft_intXstore(keypos, subkeys);
if (!error)
error=_mi_write_keypage(info,keyinfo,page,temp_buff);
error=_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff);
my_afree((byte*) temp_buff);
DBUG_RETURN(error);
}
......@@ -409,7 +409,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
{
error=_mi_insert(info,keyinfo,key,temp_buff,keypos,keybuff,father_buff,
father_keypos,father_page, insert_last);
if (_mi_write_keypage(info,keyinfo,page,temp_buff))
if (_mi_write_keypage(info,keyinfo,page,DFLT_INIT_HITS,temp_buff))
goto err;
}
my_afree((byte*) temp_buff);
......@@ -580,7 +580,7 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
}
/* Move middle item to key and pointer to new page */
if ((new_pos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
DBUG_RETURN(-1);
_mi_kpointer(info,_mi_move_key(keyinfo,key,key_buff),new_pos);
......@@ -596,7 +596,7 @@ int _mi_split_page(register MI_INFO *info, register MI_KEYDEF *keyinfo,
(*keyinfo->store_key)(keyinfo,info->buff+key_ref_length,&s_temp);
mi_putint(info->buff,length+t_length+key_ref_length,nod_flag);
if (_mi_write_keypage(info,keyinfo,new_pos,info->buff))
if (_mi_write_keypage(info,keyinfo,new_pos,DFLT_INIT_HITS,info->buff))
DBUG_RETURN(-1);
DBUG_DUMP("key",(byte*) key,_mi_keylength(keyinfo,key));
DBUG_RETURN(2); /* Middle key up */
......@@ -747,7 +747,7 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
DBUG_PRINT("test",("use left page: %lu",next_page));
} /* father_key_pos ptr to parting key */
if (!_mi_fetch_keypage(info,keyinfo,next_page,info->buff,0))
if (!_mi_fetch_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff,0))
goto err;
DBUG_DUMP("next",(byte*) info->buff,mi_getint(info->buff));
......@@ -787,8 +787,8 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
memcpy((byte*) buff+2,(byte*) pos+k_length,(size_t) length);
}
if (_mi_write_keypage(info,keyinfo,next_page,info->buff) ||
_mi_write_keypage(info,keyinfo,father_page,father_buff))
if (_mi_write_keypage(info,keyinfo,next_page,DFLT_INIT_HITS,info->buff) ||
_mi_write_keypage(info,keyinfo,father_page,DFLT_INIT_HITS,father_buff))
goto err;
DBUG_RETURN(0);
}
......@@ -828,12 +828,13 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
memcpy((byte*) (right ? key : father_key_pos),pos,(size_t) k_length);
memcpy((byte*) (right ? father_key_pos : key),tmp_part_key, k_length);
if ((new_pos=_mi_new(info,keyinfo)) == HA_OFFSET_ERROR)
if ((new_pos=_mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
goto err;
_mi_kpointer(info,key+k_length,new_pos);
if (_mi_write_keypage(info,keyinfo,(right ? new_pos : next_page),
info->buff) ||
_mi_write_keypage(info,keyinfo,(right ? next_page : new_pos),extra_buff))
DFLT_INIT_HITS,info->buff) ||
_mi_write_keypage(info,keyinfo,(right ? next_page : new_pos),
DFLT_INIT_HITS,extra_buff))
goto err;
DBUG_RETURN(1); /* Middle key up */
......
......@@ -44,6 +44,7 @@ static const char *load_default_groups[]= { "myisamchk", 0 };
static const char *set_charset_name, *opt_tmpdir;
static CHARSET_INFO *set_charset;
static long opt_myisam_block_size;
static long opt_key_cache_block_size;
static const char *my_progname_short;
static int stopwords_inited= 0;
static MY_TMPDIR myisamchk_tmpdir;
......@@ -148,7 +149,8 @@ int main(int argc, char **argv)
enum options_mc {
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE,
OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE,
OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE,
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_MAX_WORD_LEN_FOR_SORT
......@@ -283,6 +285,11 @@ static struct my_option my_long_options[] =
(gptr*) &check_param.use_buffers, (gptr*) &check_param.use_buffers, 0,
GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT, (long) MALLOC_OVERHEAD,
(long) ~0L, (long) MALLOC_OVERHEAD, (long) IO_SIZE, 0},
{ "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "",
(gptr*) &opt_key_cache_block_size,
(gptr*) &opt_key_cache_block_size, 0,
GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
MI_MAX_KEY_BLOCK_LENGTH, 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
{ "myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "",
(gptr*) &opt_myisam_block_size, (gptr*) &opt_myisam_block_size, 0,
GET_LONG, REQUIRED_ARG, MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH,
......@@ -1022,7 +1029,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
VOID(init_key_cache(param->use_buffers));
VOID(init_key_cache(dflt_keycache,opt_key_cache_block_size,
param->use_buffers,&dflt_key_cache_var));
VOID(init_io_cache(&param->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
......@@ -1445,7 +1453,8 @@ static int mi_sort_records(MI_CHECK *param,
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
DBUG_RETURN(0); /* Nothing to do */
init_key_cache(param->use_buffers);
init_key_cache(dflt_keycache,opt_key_cache_block_size,param->use_buffers,
&dflt_key_cache_var);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
......
......@@ -166,6 +166,8 @@ typedef struct st_mi_isam_share { /* Shared between opens */
char *data_file_name, /* Resolved path names from symlinks */
*index_file_name;
byte *file_map; /* mem-map of file if possible */
KEY_CACHE_HANDLE *keycache; /* ref to the current key cache */
KEY_CACHE_HANDLE *reg_keycache; /* ref to the registered key cache */
MI_DECODE_TREE *decode_trees;
uint16 *decode_tables;
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
......@@ -550,11 +552,12 @@ extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
extern int _mi_search_first(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
extern int _mi_search_last(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
extern uchar *_mi_fetch_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
uchar *buff,int return_buffer);
int level,uchar *buff,int return_buffer);
extern int _mi_write_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t page,
uchar *buff);
extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos);
extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo);
int level, uchar *buff);
extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,my_off_t pos,
int level);
extern my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo,int level);
extern uint _mi_make_key(MI_INFO *info,uint keynr,uchar *key,
const byte *record,my_off_t filepos);
extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
......
......@@ -333,7 +333,8 @@ static int examine_log(my_string file_name, char **table_names)
bzero((gptr) com_count,sizeof(com_count));
init_tree(&tree,0,0,sizeof(file_info),(qsort_cmp2) file_info_compare,1,
(tree_element_free) file_info_free, NULL);
VOID(init_key_cache(KEY_CACHE_SIZE));
VOID(init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
&dflt_key_cache_var));
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&
......@@ -647,7 +648,7 @@ static int examine_log(my_string file_name, char **table_names)
goto end;
}
}
end_key_cache();
end_key_cache(dflt_keycache,1);
delete_tree(&tree);
VOID(end_io_cache(&cache));
VOID(my_close(file,MYF(0)));
......@@ -667,7 +668,7 @@ static int examine_log(my_string file_name, char **table_names)
llstr(isamlog_filepos,llbuff)));
fflush(stderr);
end:
end_key_cache();
end_key_cache(dflt_keycache,1);
delete_tree(&tree);
VOID(end_io_cache(&cache));
VOID(my_close(file,MYF(0)));
......
......@@ -60,7 +60,7 @@ static int rtree_find_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint search_flag, u
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
}
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
......@@ -257,7 +257,7 @@ static int rtree_get_req(MI_INFO *info, MI_KEYDEF *keyinfo, uint key_length,
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
return -1;
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
......@@ -429,7 +429,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
}
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
......@@ -445,7 +445,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
case 0: /* child was not split */
{
rtree_combine_rect(keyinfo->seg, k, key, k, key_length);
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
goto err1;
goto ok;
}
......@@ -462,7 +462,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
goto err1;
res = rtree_add_key(info, keyinfo, new_key, key_length,
page_buf, new_page);
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
goto err1;
goto ok;
}
......@@ -476,7 +476,7 @@ static int rtree_insert_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
else
{
res = rtree_add_key(info, keyinfo, key, key_length, page_buf, new_page);
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
goto err1;
goto ok;
}
......@@ -509,12 +509,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
{
int res;
if ((old_root = _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
if ((old_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) == HA_OFFSET_ERROR)
return -1;
info->buff_used = 1;
mi_putint(info->buff, 2, 0);
res = rtree_add_key(info, keyinfo, key, key_length, info->buff, NULL);
if (_mi_write_keypage(info, keyinfo, old_root, info->buff))
if (_mi_write_keypage(info, keyinfo, old_root, DFLT_INIT_HITS, info->buff))
return 1;
info->s->state.key_root[keynr] = old_root;
return res;
......@@ -542,7 +542,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
}
mi_putint(new_root_buf, 2, nod_flag);
if ((new_root = _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
HA_OFFSET_ERROR)
goto err1;
new_key = new_root_buf + keyinfo->block_length + nod_flag;
......@@ -559,7 +560,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
if (rtree_add_key(info, keyinfo, new_key, key_length, new_root_buf, NULL)
== -1)
goto err1;
if (_mi_write_keypage(info, keyinfo, new_root, new_root_buf))
if (_mi_write_keypage(info, keyinfo, new_root,
DFLT_INIT_HITS, new_root_buf))
goto err1;
info->s->state.key_root[keynr] = new_root;
......@@ -636,7 +638,7 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
my_errno = HA_ERR_OUT_OF_MEM;
return -1;
}
if (!_mi_fetch_keypage(info, keyinfo, page, page_buf, 0))
if (!_mi_fetch_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
......@@ -662,7 +664,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
if (rtree_set_key_mbr(info, keyinfo, k, key_length,
_mi_kpos(nod_flag, k)))
goto err1;
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page,
DFLT_INIT_HITS, page_buf))
goto err1;
}
else
......@@ -672,7 +675,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
level + 1))
goto err1;
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page,
DFLT_INIT_HITS, page_buf))
goto err1;
*page_size = mi_getint(page_buf);
}
......@@ -686,7 +690,8 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
case 2: /* vacuous case: last key in the leaf */
{
rtree_delete_key(info, page_buf, k, key_length, nod_flag);
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page,
DFLT_INIT_HITS, page_buf))
goto err1;
*page_size = mi_getint(page_buf);
res = 0;
......@@ -711,13 +716,13 @@ static int rtree_delete_req(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
{
/* last key in the leaf */
res = 2;
if (_mi_dispose(info, keyinfo, page))
if (_mi_dispose(info, keyinfo, page, DFLT_INIT_HITS))
goto err1;
}
else
{
res = 0;
if (_mi_write_keypage(info, keyinfo, page, page_buf))
if (_mi_write_keypage(info, keyinfo, page, DFLT_INIT_HITS, page_buf))
goto err1;
}
goto ok;
......@@ -783,7 +788,7 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
goto err1;
}
if (!_mi_fetch_keypage(info, keyinfo, ReinsertList.pages[i].offs,
page_buf, 0))
DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
k = rt_PAGE_FIRST_KEY(page_buf, nod_flag);
......@@ -798,7 +803,8 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
}
}
my_afree((byte*)page_buf);
if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs))
if (_mi_dispose(info, keyinfo, ReinsertList.pages[i].offs,
DFLT_INIT_HITS))
goto err1;
}
if (ReinsertList.pages)
......@@ -807,7 +813,8 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
/* check for redundant root (not leaf, 1 child) and eliminate */
if ((old_root = info->s->state.key_root[keynr]) == HA_OFFSET_ERROR)
goto err1;
if (!_mi_fetch_keypage(info, keyinfo, old_root, info->buff, 0))
if (!_mi_fetch_keypage(info, keyinfo, old_root, DFLT_INIT_HITS,
info->buff, 0))
goto err1;
nod_flag = mi_test_if_nod(info->buff);
page_size = mi_getint(info->buff);
......@@ -816,7 +823,7 @@ int rtree_delete(MI_INFO *info, uint keynr, uchar *key, uint key_length)
{
my_off_t new_root = _mi_kpos(nod_flag,
rt_PAGE_FIRST_KEY(info->buff, nod_flag));
if (_mi_dispose(info, keyinfo, old_root))
if (_mi_dispose(info, keyinfo, old_root, DFLT_INIT_HITS))
goto err1;
info->s->state.key_root[keynr] = new_root;
}
......@@ -863,7 +870,7 @@ ha_rows rtree_estimate(MI_INFO *info, uint keynr, uchar *key,
return HA_POS_ERROR;
if (!(page_buf = (uchar*)my_alloca((uint)keyinfo->block_length)))
return HA_POS_ERROR;
if (!_mi_fetch_keypage(info, keyinfo, root, page_buf, 0))
if (!_mi_fetch_keypage(info, keyinfo, root, DFLT_INIT_HITS, page_buf, 0))
goto err1;
nod_flag = mi_test_if_nod(page_buf);
......
......@@ -88,7 +88,8 @@ int rtree_delete_key(MI_INFO *info, uchar *page_buf, uchar *key,
int rtree_set_key_mbr(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key,
uint key_length, my_off_t child_page)
{
if (!_mi_fetch_keypage(info, keyinfo, child_page, info->buff, 0))
if (!_mi_fetch_keypage(info, keyinfo, child_page,
DFLT_INIT_HITS, info->buff, 0))
return -1;
return rtree_page_mbr(info, keyinfo->seg, info->buff, key, key_length);
......
......@@ -332,10 +332,12 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
mi_putint(page, 2 + n1 * full_length, nod_flag);
mi_putint(new_page, 2 + n2 * full_length, nod_flag);
if ((*new_page_offs= _mi_new(info, keyinfo)) == HA_OFFSET_ERROR)
if ((*new_page_offs= _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
HA_OFFSET_ERROR)
err_code= -1;
else
err_code= _mi_write_keypage(info, keyinfo, *new_page_offs, new_page);
err_code= _mi_write_keypage(info, keyinfo, *new_page_offs,
DFLT_INIT_HITS, new_page);
my_afree((byte*)new_page);
......
......@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain
select min(a1) from t1 where a1 != 'KKK';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using where; Using index
1 SIMPLE t1 range PRIMARY PRIMARY 3 NULL 14 Using where; Using index
explain
select max(a3) from t1 where a2 < 2 and a3 < 'SEA';
id select_type table type possible_keys key key_len ref rows Extra
......@@ -560,7 +560,7 @@ explain
select concat(min(t1.a1),min(t2.a4)) from t1, t2 where t2.a4 <> 'AME';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 3 NULL 14 Using index
1 SIMPLE t2 index NULL k2 4 NULL 6 Using where; Using index
1 SIMPLE t2 range k2 k2 4 NULL 6 Using where; Using index
drop table t1, t2;
CREATE TABLE t1 (a int, b int);
select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1;
......
......@@ -41,3 +41,194 @@ SELECT @@default.key_buffer_size;
ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1
SELECT @@skr.table_type="test";
ERROR HY000: Variable 'table_type' is not a variable component (Can't be used as XXXX.variable_name)
select @@keycache1.key_cache_block_size;
@@keycache1.key_cache_block_size
0
select @@keycache1.key_buffer_size;
@@keycache1.key_buffer_size
0
set global keycache1.key_cache_block_size=2048;
select @@keycache1.key_buffer_size;
@@keycache1.key_buffer_size
0
select @@keycache1.key_cache_block_size;
@@keycache1.key_cache_block_size
2048
set global keycache1.key_buffer_size=1*1024*1024;
select @@keycache1.key_buffer_size;
@@keycache1.key_buffer_size
1048576
select @@keycache1.key_cache_block_size;
@@keycache1.key_cache_block_size
2048
set global keycache2.key_buffer_size=4*1024*1024;
select @@keycache2.key_buffer_size;
@@keycache2.key_buffer_size
4194304
select @@keycache2.key_cache_block_size;
@@keycache2.key_cache_block_size
1024
set global keycache1.key_buffer_size=0;
select @@keycache1.key_buffer_size;
@@keycache1.key_buffer_size
0
select @@keycache1.key_cache_block_size;
@@keycache1.key_cache_block_size
0
select @@key_buffer_size;
@@key_buffer_size
2097152
select @@key_cache_block_size;
@@key_cache_block_size
1024
drop table if exists t1, t2;
create table t1 (p int primary key, a char(10));
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
(3, 1, 'yyyy'), (4, 3, 'zzzz');
select * from t1;
p a
1 qqqq
11 yyyy
select * from t2;
p i a
1 1 qqqq
2 1 pppp
3 1 yyyy
4 3 zzzz
update t1 set p=2 where p=1;
update t2 set i=2 where i=1;
cache index t1 keys in keycache1;
Table Op Msg_type Msg_text
test.t1 assign_to_keycache status OK
explain select p from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index
select p from t1;
p
2
11
explain select i from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL k1 5 NULL 4 Using index
select i from t2;
i
2
2
2
3
explain select count(*) from t1, t2 where t1.p = t2.i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 2 Using index
1 SIMPLE t2 ref k1 k1 5 test.t1.p 2 Using where; Using index
select count(*) from t1, t2 where t1.p = t2.i;
count(*)
3
cache index t2 keys in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
update t2 set p=p+1000, i=2 where a='qqqq';
cache index t2 keys in keycache2;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
insert into t2 values (2000, 3, 'yyyy');
cache index t2 keys in keycache1;
Table Op Msg_type Msg_text
test.t2 assign_to_keycache status OK
update t2 set p=3000 where a='zzzz';
select * from t2;
p i a
1001 2 qqqq
2 2 pppp
3 2 yyyy
3000 3 zzzz
2000 3 yyyy
explain select p from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 4 NULL 5 Using index
select p from t2;
p
2
3
1001
2000
3000
explain select i from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL k1 5 NULL 5 Using index
select i from t2;
i
2
2
2
3
3
explain select a from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL k2 11 NULL 5 Using index
select a from t2;
a
pppp
qqqq
yyyy
yyyy
zzzz
select @@keycache2.key_buffer_size;
@@keycache2.key_buffer_size
4194304
select @@keycache2.key_cache_block_size;
@@keycache2.key_cache_block_size
1024
set global keycache2.key_buffer_size=0;
select @@keycache2.key_buffer_size;
@@keycache2.key_buffer_size
0
select @@keycache2.key_cache_block_size;
@@keycache2.key_cache_block_size
0
update t2 set p=4000 where a='zzzz';
update t1 set p=p+1;
set global keycache1.key_buffer_size=0;
select * from t2;
p i a
1001 2 qqqq
2 2 pppp
3 2 yyyy
4000 3 zzzz
2000 3 yyyy
select p from t2;
p
2
3
1001
2000
4000
explain select i from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL k1 5 NULL 5 Using index
select i from t2;
i
2
2
2
3
3
explain select a from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL k2 11 NULL 5 Using index
select a from t2;
a
pppp
qqqq
yyyy
yyyy
zzzz
select * from t1;
p a
3 qqqq
12 yyyy
select p from t1;
p
3
12
......@@ -4,14 +4,35 @@ INSERT INTO t1 VALUES (1), (2);
<?xml version="1.0"?>
<mysqldump>
<database name="test">
<table name="t1">
<table_structure name="t1">
<field Field="a" Type="int(11)" Null="YES" />
</table_structure>
<table_data name="t1">
<row>
<field name="a">1</field>
</row>
<row>
<field name="a">2</field>
</row>
</table>
</table_data>
</database>
</mysqldump>
DROP TABLE t1;
CREATE TABLE `t"1` (`a"b"c"` char(2));
INSERT INTO `t"1` VALUES ("\"1"), ("2\"");
<?xml version="1.0"?>
<mysqldump>
<database name="test">
<table_structure name="t&quot;1">
<field Field="a&quot;b&quot;c&quot;" Type="char(2)" Null="YES" />
</table_structure>
<table_data name="t&quot;1">
<row>
<field name="a&quot;b&quot;c&quot;">&quot;1</field>
</row>
<row>
<field name="a&quot;b&quot;c&quot;">2&quot;</field>
</row>
</table_data>
</database>
</mysqldump>
drop table if exists t1;
drop table if exists t1, t2;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
......@@ -215,17 +215,6 @@ select count(*) from t1 where art = 'J';
count(*)
213
drop table t1;
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
id1 idnull
drop table t1;
create table t1 (x int, y int, index(x), index(y));
insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
update t1 set y=x;
......@@ -286,3 +275,145 @@ id
5
9
drop table t1;
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
id1 idnull
drop table t1;
create table t1 (
id int not null auto_increment,
name char(1) not null,
uid int not null,
primary key (id),
index uid_index (uid));
create table t2 (
id int not null auto_increment,
name char(1) not null,
uid int not null,
primary key (id),
index uid_index (uid));
insert into t1(id, uid, name) values(1, 0, ' ');
insert into t1(uid, name) values(0, ' ');
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
delete from t2;
insert into t2(uid, name) values
(1, CHAR(64+1)),
(2, CHAR(64+2)),
(3, CHAR(64+3)),
(4, CHAR(64+4)),
(5, CHAR(64+5)),
(6, CHAR(64+6)),
(7, CHAR(64+7)),
(8, CHAR(64+8)),
(9, CHAR(64+9)),
(10, CHAR(64+10)),
(11, CHAR(64+11)),
(12, CHAR(64+12)),
(13, CHAR(64+13)),
(14, CHAR(64+14)),
(15, CHAR(64+15)),
(16, CHAR(64+16)),
(17, CHAR(64+17)),
(18, CHAR(64+18)),
(19, CHAR(64+19)),
(20, CHAR(64+20)),
(21, CHAR(64+21)),
(22, CHAR(64+22)),
(23, CHAR(64+23)),
(24, CHAR(64+24)),
(25, CHAR(64+25)),
(26, CHAR(64+26));
insert into t1(uid, name) select uid, name from t2;
delete from t2;
insert into t2(id, uid, name) select id, uid, name from t1;
select count(*) from t1;
count(*)
1026
select count(*) from t2;
count(*)
1026
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range uid_index uid_index 4 NULL 128 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range uid_index uid_index 4 NULL 129 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id name uid id name uid
1001 A 1 1001 A 1
1002 B 2 1002 B 2
1003 C 3 1003 C 3
1004 D 4 1004 D 4
1005 E 5 1005 E 5
1006 F 6 1006 F 6
1007 G 7 1007 G 7
1008 H 8 1008 H 8
1009 I 9 1009 I 9
1010 J 10 1010 J 10
1011 K 11 1011 K 11
1012 L 12 1012 L 12
1013 M 13 1013 M 13
1014 N 14 1014 N 14
1015 O 15 1015 O 15
1016 P 16 1016 P 16
1017 Q 17 1017 Q 17
1018 R 18 1018 R 18
1019 S 19 1019 S 19
1020 T 20 1020 T 20
1021 U 21 1021 U 21
1022 V 22 1022 V 22
1023 W 23 1023 W 23
1024 X 24 1024 X 24
1025 Y 25 1025 Y 25
1026 Z 26 1026 Z 26
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
id name uid id name uid
1001 A 1 1001 A 1
1002 B 2 1002 B 2
1003 C 3 1003 C 3
1004 D 4 1004 D 4
1005 E 5 1005 E 5
1006 F 6 1006 F 6
1007 G 7 1007 G 7
1008 H 8 1008 H 8
1009 I 9 1009 I 9
1010 J 10 1010 J 10
1011 K 11 1011 K 11
1012 L 12 1012 L 12
1013 M 13 1013 M 13
1014 N 14 1014 N 14
1015 O 15 1015 O 15
1016 P 16 1016 P 16
1017 Q 17 1017 Q 17
1018 R 18 1018 R 18
1019 S 19 1019 S 19
1020 T 20 1020 T 20
1021 U 21 1021 U 21
1022 V 22 1022 V 22
1023 W 23 1023 W 23
1024 X 24 1024 X 24
1025 Y 25 1025 Y 25
1026 Z 26 1026 Z 26
drop table t1,t2;
#
# Test of key cache
# Test of multiple key caches
#
SET @save_key_buffer=@@key_buffer_size;
......@@ -40,3 +40,83 @@ SET @@global.key_buffer_size=@save_key_buffer;
SELECT @@default.key_buffer_size;
--error 1271
SELECT @@skr.table_type="test";
select @@keycache1.key_cache_block_size;
select @@keycache1.key_buffer_size;
set global keycache1.key_cache_block_size=2048;
select @@keycache1.key_buffer_size;
select @@keycache1.key_cache_block_size;
set global keycache1.key_buffer_size=1*1024*1024;
select @@keycache1.key_buffer_size;
select @@keycache1.key_cache_block_size;
set global keycache2.key_buffer_size=4*1024*1024;
select @@keycache2.key_buffer_size;
select @@keycache2.key_cache_block_size;
set global keycache1.key_buffer_size=0;
select @@keycache1.key_buffer_size;
select @@keycache1.key_cache_block_size;
select @@key_buffer_size;
select @@key_cache_block_size;
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (p int primary key, a char(10));
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
(3, 1, 'yyyy'), (4, 3, 'zzzz');
select * from t1;
select * from t2;
update t1 set p=2 where p=1;
update t2 set i=2 where i=1;
cache index t1 keys in keycache1;
explain select p from t1;
select p from t1;
explain select i from t2;
select i from t2;
explain select count(*) from t1, t2 where t1.p = t2.i;
select count(*) from t1, t2 where t1.p = t2.i;
cache index t2 keys in keycache1;
update t2 set p=p+1000, i=2 where a='qqqq';
cache index t2 keys in keycache2;
insert into t2 values (2000, 3, 'yyyy');
cache index t2 keys in keycache1;
update t2 set p=3000 where a='zzzz';
select * from t2;
explain select p from t2;
select p from t2;
explain select i from t2;
select i from t2;
explain select a from t2;
select a from t2;
select @@keycache2.key_buffer_size;
select @@keycache2.key_cache_block_size;
set global keycache2.key_buffer_size=0;
select @@keycache2.key_buffer_size;
select @@keycache2.key_cache_block_size;
update t2 set p=4000 where a='zzzz';
update t1 set p=p+1;
set global keycache1.key_buffer_size=0;
select * from t2;
select p from t2;
explain select i from t2;
select i from t2;
explain select a from t2;
select a from t2;
select * from t1;
select p from t1;
......@@ -6,5 +6,14 @@ DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2);
--exec $MYSQL_DUMP -X test t1
--exec $MYSQL_DUMP --skip-all -X test t1
DROP TABLE t1;
#
# Bug #1707
#
CREATE TABLE `t"1` (`a"b"c"` char(2));
INSERT INTO `t"1` VALUES ("\"1"), ("2\"");
--exec $MYSQL_DUMP --skip-all -X test
DROP TABLE `t"1`;
......@@ -3,7 +3,7 @@
#
--disable_warnings
drop table if exists t1;
drop table if exists t1, t2;
--enable_warnings
CREATE TABLE t1 (
......@@ -174,18 +174,6 @@ select count(*) from t1 where art = 'j' or art = 'J';
select count(*) from t1 where art = 'j';
select count(*) from t1 where art = 'J';
drop table t1;
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
drop table t1;
#
# BETWEEN problems
#
......@@ -225,3 +213,96 @@ insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
select id from t1 where id in (2,5,9) ;
select id from t1 where id=2 or id=5 or id=9 ;
drop table t1;
create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
drop table t1;
#
# Problem with optimizing !=
#
create table t1 (
id int not null auto_increment,
name char(1) not null,
uid int not null,
primary key (id),
index uid_index (uid));
create table t2 (
id int not null auto_increment,
name char(1) not null,
uid int not null,
primary key (id),
index uid_index (uid));
insert into t1(id, uid, name) values(1, 0, ' ');
insert into t1(uid, name) values(0, ' ');
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t2(uid, name) select uid, name from t1;
insert into t1(uid, name) select uid, name from t2;
delete from t2;
insert into t2(uid, name) values
(1, CHAR(64+1)),
(2, CHAR(64+2)),
(3, CHAR(64+3)),
(4, CHAR(64+4)),
(5, CHAR(64+5)),
(6, CHAR(64+6)),
(7, CHAR(64+7)),
(8, CHAR(64+8)),
(9, CHAR(64+9)),
(10, CHAR(64+10)),
(11, CHAR(64+11)),
(12, CHAR(64+12)),
(13, CHAR(64+13)),
(14, CHAR(64+14)),
(15, CHAR(64+15)),
(16, CHAR(64+16)),
(17, CHAR(64+17)),
(18, CHAR(64+18)),
(19, CHAR(64+19)),
(20, CHAR(64+20)),
(21, CHAR(64+21)),
(22, CHAR(64+22)),
(23, CHAR(64+23)),
(24, CHAR(64+24)),
(25, CHAR(64+25)),
(26, CHAR(64+26));
insert into t1(uid, name) select uid, name from t2;
delete from t2;
insert into t2(id, uid, name) select id, uid, name from t1;
select count(*) from t1;
select count(*) from t2;
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
drop table t1,t2;
This diff is collapsed.
......@@ -228,6 +228,12 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
if (!(file=mi_open(name, mode, test_if_locked)))
return (my_errno ? my_errno : -1);
/* Synchronize key cache assignment of the handler */
KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache :
&dflt_key_cache_var;
VOID(mi_extra(file, HA_EXTRA_SET_KEY_CACHE,
(void*) &key_cache->cache));
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
......@@ -691,6 +697,131 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
}
/*
Assign table indexes to a key cache.
*/
int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
{
uint len;
KEY_CACHE_VAR *old_key_cache;
KEY_CACHE_VAR *new_key_cache;
const char *errmsg=0;
int error= HA_ADMIN_OK;
ulonglong map= ~(ulonglong) 0;
TABLE_LIST *table_list= table->pos_in_table_list;
const char *new_key_cache_name= table_list->option ?
(const char *) table_list->option :
DEFAULT_KEY_CACHE_NAME;
KEY_CACHE_ASMT *key_cache_asmt= table->key_cache_asmt;
bool triggered= key_cache_asmt->triggered;
DBUG_ENTER("ha_myisam::assign_to_keycache");
VOID(pthread_mutex_lock(&LOCK_assign));
old_key_cache= key_cache_asmt->key_cache;
/* Check validity of the index references */
if (!triggered && table_list->use_index)
{
key_map kmap= get_key_map_from_key_list(table, table_list->use_index);
if (kmap == ~(key_map) 0)
{
errmsg= thd->net.last_error;
error= HA_ADMIN_FAILED;
goto err;
}
if (kmap)
map= kmap;
}
len= strlen(new_key_cache_name);
new_key_cache= get_or_create_key_cache(new_key_cache_name, len);
if (old_key_cache == new_key_cache)
{
/* Nothing to do: table is assigned to the same key cache */
goto ok;
}
if (!new_key_cache ||
(!new_key_cache->cache && ha_key_cache(new_key_cache)))
{
if (key_cache_asmt->triggered)
error= HA_ERR_OUT_OF_MEM;
else
{
char buf[ERRMSGSIZE];
my_snprintf(buf, ERRMSGSIZE,
"Failed to create key cache %s", new_key_cache_name);
errmsg= buf;
error= HA_ADMIN_FAILED;
}
goto err;
}
reassign_key_cache(key_cache_asmt, new_key_cache);
VOID(pthread_mutex_unlock(&LOCK_assign));
error= mi_assign_to_keycache(file, map, new_key_cache, &LOCK_assign);
VOID(pthread_mutex_lock(&LOCK_assign));
if (error && !key_cache_asmt->triggered)
{
switch (error) {
default:
char buf[ERRMSGSIZE+20];
my_snprintf(buf, ERRMSGSIZE,
"Failed to flush to index file (errno: %d)", my_errno);
errmsg= buf;
}
error= HA_ADMIN_CORRUPT;
goto err;
}
goto ok;
err:
if (!triggered)
{
MI_CHECK param;
myisamchk_init(&param);
param.thd= thd;
param.op_name= (char*)"assign_to_keycache";
param.db_name= table->table_cache_key;
param.table_name= table->table_name;
param.testflag= 0;
mi_check_print_error(&param, errmsg);
}
ok:
if (--key_cache_asmt->requests)
{
/* There is a queue of assignments for the table */
/* Remove the first member from the queue */
struct st_my_thread_var *last= key_cache_asmt->queue;
struct st_my_thread_var *thread= last->next;
if (thread->next == thread)
key_cache_asmt->queue= 0;
else
{
last->next= thread->next;
last->next->prev= &last->next;
thread->next= 0;
}
/* Signal the first waiting thread to proceed */
VOID(pthread_cond_signal(&thread->suspend));
}
key_cache_asmt->triggered= 0;
VOID(pthread_mutex_unlock(&LOCK_assign));
DBUG_RETURN(error);
}
/*
Preload pages of the index file for a table into the key cache.
*/
......
......@@ -127,6 +127,7 @@ class ha_myisam: public handler
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
int restore(THD* thd, HA_CHECK_OPT* check_opt);
int backup(THD* thd, HA_CHECK_OPT* check_opt);
int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
#ifdef HAVE_REPLICATION
int dump(THD* thd, int fd);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -245,7 +245,7 @@ class Item_func_ne :public Item_bool_rowready_func2
longlong val_int();
enum Functype functype() const { return NE_FUNC; }
cond_result eq_cmp_result() const { return COND_FALSE; }
optimize_type select_optimize() const { return OPTIMIZE_NONE; }
optimize_type select_optimize() const { return OPTIMIZE_KEY; }
const char *func_name() const { return "<>"; }
};
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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