Commit c2f6d577 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

merge

parents 4ec3eda7 880026cc
This diff is collapsed.
......@@ -243,7 +243,8 @@ static COMMANDS commands[] = {
};
static const char *load_default_groups[]= { "mysql","client",0 };
static const char *server_default_groups[]= { "server", "mysql_SERVER", 0 };
static const char *server_default_groups[]=
{ "server", "embedded", "mysql_SERVER", 0 };
#ifdef HAVE_READLINE
extern "C" void add_history(char *command); /* From readline directory */
......@@ -271,7 +272,6 @@ int main(int argc,char *argv[])
{
char buff[80];
mysql_server_init(0, NULL, server_default_groups);
MY_INIT(argv[0]);
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
......@@ -302,6 +302,7 @@ int main(int argc,char *argv[])
!(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin)))
exit(1);
glob_buffer.realloc(512);
mysql_server_init(0, NULL, server_default_groups);
completion_hash_init(&ht,50);
bzero((char*) &mysql, sizeof(mysql));
if (sql_connect(current_host,current_db,current_user,opt_password,
......@@ -368,7 +369,6 @@ int main(int argc,char *argv[])
if (opt_outfile)
end_tee();
mysql_end(0);
mysql_server_end();
#ifndef _lint
DBUG_RETURN(0); // Keep compiler happy
#endif
......@@ -398,6 +398,7 @@ sig_handler mysql_end(int sig)
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_host,MYF(MY_ALLOW_ZERO_PTR));
my_free(current_user,MYF(MY_ALLOW_ZERO_PTR));
mysql_server_end();
my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(status.exit_status);
}
......
......@@ -306,17 +306,18 @@ static void close_cons()
static void close_files()
{
do
DBUG_ENTER("close_files");
for (; cur_file != file_stack ; cur_file--)
{
if (*cur_file != stdin && *cur_file)
my_fclose(*cur_file,MYF(0));
} while (cur_file-- != file_stack);
}
DBUG_VOID_RETURN;
}
static void free_used_memory()
{
uint i;
DBUG_ENTER("free_used_memory");
close_cons();
close_files();
hash_free(&var_hash);
......@@ -336,8 +337,8 @@ static void free_used_memory()
dynstr_free(&ds_res);
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv);
mysql_server_end();
my_end(MY_CHECK_ERROR);
DBUG_VOID_RETURN;
}
static void die(const char* fmt, ...)
......@@ -1303,15 +1304,11 @@ int read_line(char* buf, int size)
{
if ((*cur_file) != stdin)
my_fclose(*cur_file,MYF(0));
cur_file--;
lineno--;
if (cur_file == file_stack)
return 1;
else
{
cur_file--;
lineno--;
continue;
}
continue;
}
switch(state) {
......@@ -1592,7 +1589,7 @@ int parse_args(int argc, char **argv)
result_file = optarg;
break;
case 'x':
if (!(*cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME))))
if (!(*++cur_file = my_fopen(optarg, O_RDONLY, MYF(MY_WME))))
die("Could not open %s: errno = %d", optarg, errno);
break;
case 'p':
......@@ -1949,9 +1946,10 @@ int main(int argc, char** argv)
struct st_query* q;
my_bool require_file=0, q_send_flag=0;
char save_file[FN_REFLEN];
mysql_server_init(sizeof(embedded_server_args) / sizeof(char *) - 1,
embedded_server_args, embedded_server_groups);
MY_INIT(argv[0]);
{
DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
save_file[0]=0;
TMPDIR[0]=0;
......@@ -1976,9 +1974,12 @@ int main(int argc, char** argv)
*block_ok = 1;
init_dynamic_string(&ds_res, "", 0, 65536);
parse_args(argc, argv);
if (mysql_server_init(sizeof(embedded_server_args) / sizeof(char *) - 1,
embedded_server_args, embedded_server_groups))
die("Can't initialize MySQL server");
init_var_hash();
if (!*cur_file)
*cur_file = stdin;
if (cur_file == file_stack)
*++cur_file = stdin;
*lineno=1;
if (!( mysql_init(&cur_con->mysql)))
......@@ -2114,10 +2115,10 @@ int main(int argc, char** argv)
printf("ok\n");
}
mysql_server_end();
free_used_memory();
exit(error ? 1 : 0);
return error ? 1 : 0; /* Keep compiler happy */
DBUG_RETURN(error ? 1 : 0); /* Keep compiler happy */
}
}
......
......@@ -965,4 +965,13 @@ typedef union {
#define statistic_add(V,C,L) (V)+=(C)
#endif
/* Macros to make switching between C and C++ mode easier */
#ifdef __cplusplus
#define C_MODE_START extern "C" {
#define C_MODE_END }
#else
#define C_MODE_START
#define C_MODE_END
#endif
#endif /* _global_h */
......@@ -106,7 +106,8 @@ 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 KEYCACHE_BLOCK_SIZE 1024
#define DEFAULT_KEYCACHE_BLOCK_SIZE 1024
#define MAX_KEYCACHE_BLOCK_SIZE 16384
/* root_alloc flags */
#define MY_KEEP_PREALLOC 1
......@@ -190,9 +191,10 @@ extern char *get_charsets_dir(char *buf);
/* statistics */
extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
extern ulong _my_blocks_used,_my_blocks_changed;
extern ulong _my_blocks_used,_my_blocks_changed;
extern uint key_cache_block_size;
extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
extern my_bool key_cache_inited;
extern my_bool key_cache_inited, my_init_done;
/* Point to current my_message() */
extern void (*my_sigtstp_cleanup)(void),
......@@ -602,6 +604,7 @@ my_bool my_compress(byte *, ulong *, ulong *);
my_bool my_uncompress(byte *, ulong *, ulong *);
byte *my_compress_alloc(const byte *packet, ulong *len, ulong *complen);
ulong checksum(const byte *mem, uint count);
uint my_bit_log2(ulong value);
#if defined(_MSC_VER) && !defined(__WIN__)
extern void sleep(int sec);
......
......@@ -46,6 +46,11 @@ extern "C" {
/* Max extra space to use when sorting keys */
#define MI_MAX_TEMP_LENGTH 256*1024L*1024L
/* Possible values for myisam_block_size (must be power of 2) */
#define MI_KEY_BLOCK_LENGTH 1024 /* default key block length */
#define MI_MIN_KEY_BLOCK_LENGTH 1024 /* Min key block length */
#define MI_MAX_KEY_BLOCK_LENGTH 16384
#define mi_portable_sizeof_char_ptr 8
typedef uint32 ha_checksum;
......@@ -192,7 +197,7 @@ extern uint myisam_block_size;
extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_bool myisam_concurrent_insert;
extern my_off_t myisam_max_temp_length,myisam_max_extra_temp_length;
extern uint myisam_bulk_insert_tree_size;
extern ulong myisam_bulk_insert_tree_size;
/* Prototypes for myisam-functions */
......
......@@ -26,11 +26,9 @@
#undef __WIN__
#endif
#ifndef MYSQL_SERVER
#ifdef __cplusplus
extern "C" {
#endif
#endif
#ifndef _global_h /* If not standard header */
#include <sys/types.h>
......@@ -229,7 +227,7 @@ typedef struct st_mysql_res {
/* Set up and bring down the server; to ensure that applications will
* work when linked against either the standard client library or the
* embedded server library, these functions should be called. */
void mysql_server_init(int argc, const char **argv, const char **groups);
int mysql_server_init(int argc, const char **argv, const char **groups);
void mysql_server_end();
/* Set up and bring down a thread; these function should be called
......@@ -382,10 +380,8 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
#define HAVE_MYSQL_REAL_CONNECT
#ifndef MYSQL_SERVER
#ifdef __cplusplus
}
#endif
#endif
#endif
#endif /* _mysql_h */
......@@ -91,10 +91,12 @@ static sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
void mysql_server_init(int argc __attribute__((unused)),
int mysql_server_init(int argc __attribute__((unused)),
const char **argv __attribute__((unused)),
const char **groups __attribute__((unused)))
{}
{
return 0;
}
void mysql_server_end()
{}
......
......@@ -39,6 +39,8 @@ libmysqlsources = errmsg.c get_password.c password.c
## XXX: we should not have to duplicate info from the sources list
libmysqlobjects = errmsg.lo get_password.lo password.lo
noinst_HEADERS = embedded_priv.h
sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
ha_innobase.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
ha_myisam.cc ha_myisammrg.cc handler.cc sql_handler.cc \
......
/* 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 */
/* Prototypes for the embedded version of MySQL */
#include <my_global.h>
#include <mysql_embed.h>
#include <mysql.h>
#include <mysql_version.h>
#include <mysqld_error.h>
#include <my_pthread.h>
C_MODE_START
extern void start_embedded_connection(NET * net);
extern void end_embedded_connection(NET * net);
extern void lib_connection_phase(NET *net, int phase);
extern bool lib_dispatch_command(enum enum_server_command command, NET *net,
const char *arg, ulong length);
C_MODE_END
......@@ -43,6 +43,7 @@ usage: $0 [-g|-h|-r] [test-name ...]
EOF
}
init_args=""
while test $# -gt 0
do
arg=
......@@ -56,6 +57,7 @@ do
-h | --help | -\? ) usage; exit 0;;
-l | --list ) list=1 ; shift ;;
-r | --run ) run="${cr}run"; shift;;
--debug) init_args="$init_args --debug" ; shift ;;
-s | --start=* )
test $argset -eq 0 && { shift; arg="$1"; }
start="$arg"
......@@ -103,7 +105,7 @@ do
echo "test '$b' doesn't exist" >&2
continue
}
args="-v -S /tmp/mysql.sock -R $r -x $t test"
args="$init_args -v -S /tmp/mysql.sock -R $r -x $t test"
echo "set args $args$run" > test-gdbinit
#if false && test -n "$run"
if test -n "$run" -o $gdb -eq 1
......
This diff is collapsed.
......@@ -15,15 +15,7 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#include <my_global.h>
#if defined(__WIN__) || defined(_WIN32) || defined(_WIN64)
#include <winsock.h>
#include <odbcinst.h>
#endif
#include "mysql_embed.h"
#include "mysql.h"
#include "mysql_version.h"
#include "mysqld_error.h"
#include "embedded_priv.h"
#include <my_sys.h>
#include <mysys_err.h>
#include <m_string.h>
......@@ -51,9 +43,6 @@
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#if defined(THREAD) && !defined(__WIN__)
#include <my_pthread.h> /* because of signal() */
#endif
#ifndef INADDR_NONE
#define INADDR_NONE -1
#endif
......@@ -74,12 +63,6 @@ my_string mysql_unix_port=0;
#define closesocket(A) close(A)
#endif
/* XXX: this is real ugly... */
extern void start_embedded_connection(NET * net);
extern void lib_connection_phase(NET *net, int phase);
extern bool lib_dispatch_command(enum enum_server_command command, NET *net,
const char *arg, ulong length);
static void mysql_once_init(void);
static MYSQL_DATA *read_rows (MYSQL *mysql,MYSQL_FIELD *fields,
uint field_count);
......@@ -89,7 +72,6 @@ static void end_server(MYSQL *mysql);
static void read_user_name(char *name);
static void append_wild(char *to,char *end,const char *wild);
static int send_file_to_server(MYSQL *mysql,const char *filename);
static sig_handler pipe_sig_handler(int sig);
static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length);
......@@ -402,22 +384,6 @@ mysql_debug(const char *debug)
#endif
}
/**************************************************************************
** Close the server connection if we get a SIGPIPE
ARGSUSED
**************************************************************************/
static sig_handler
pipe_sig_handler(int sig __attribute__((unused)))
{
DBUG_PRINT("info",("Hit by signal %d",sig));
#ifdef DONT_REMEMBER_SIGNAL
(void) signal(SIGPIPE,pipe_sig_handler);
#endif
}
/**************************************************************************
** Shut down connection
**************************************************************************/
......@@ -428,11 +394,7 @@ end_server(MYSQL *mysql)
DBUG_ENTER("end_server");
if (mysql->net.vio != 0)
{
init_sigpipe_variables
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
set_sigpipe(mysql);
vio_delete(mysql->net.vio);
reset_sigpipe(mysql);
end_embedded_connection(&mysql->net);
mysql->net.vio= 0; /* Marker */
}
net_end(&mysql->net);
......
......@@ -173,7 +173,7 @@ int do_boolean(ALL_IN_ONE *aio, uint nested __attribute__((unused)),
aio->key_root);
else
r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
USE_WHOLE_KEY, SEARCH_BIGGER,
aio->key_root);
}
break;
......
......@@ -126,7 +126,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
aio->key_root);
else
r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
aio->info->lastkey_length, SEARCH_BIGGER,
USE_WHOLE_KEY, SEARCH_BIGGER,
aio->key_root);
}
if(doc_cnt) {
......
......@@ -34,7 +34,7 @@ FT_DOCLIST *ft_init_search(void *info, uint keynr, byte *query,
/* black magic ON */
if ((int) (keynr = _mi_check_index((MI_INFO *)info,keynr)) < 0)
return NULL;
if (_mi_readinfo((MI_INFO *)info,F_RDLCK,1))
if (fast_mi_readinfo((MI_INFO *) info))
return NULL;
/* black magic OFF */
......
......@@ -24,7 +24,7 @@ int mi_is_changed(MI_INFO *info)
{
int result;
DBUG_ENTER("mi_is_changed");
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(-1);
VOID(_mi_writeinfo(info,0));
result=(int) info->data_changed;
......
......@@ -231,7 +231,7 @@ wrong:
static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
{
my_off_t next_link;
uint block_size=(nr+1)*MI_KEY_BLOCK_LENGTH;
uint block_size=(nr+1)*MI_MIN_KEY_BLOCK_LENGTH;
ha_rows records;
char llbuff[21],*buff;
DBUG_ENTER("check_k_link");
......@@ -1205,8 +1205,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
param->calc_checksum=1;
if (!rep_quick)
share->state.checksum=0;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
for (i=0 ; i < info->s->base.keys ; i++)
......@@ -1301,9 +1299,9 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
else
{
info->state->data_file_length=sort_info->max_pos;
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
}
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
if (!(param->testflag & T_SILENT))
{
......@@ -1886,8 +1884,6 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
param->calc_checksum=1;
if (! rep_quick)
share->state.checksum=0;
rec_per_key_part= param->rec_per_key_part;
for (sort_info->key=0 ; sort_info->key < share->base.keys ;
......@@ -2018,7 +2014,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
"Can't change size of datafile, error: %d",
my_errno);
}
else if (param->testflag & T_CALC_CHECKSUM)
if (param->testflag & T_CALC_CHECKSUM)
share->state.checksum=param->glob_crc;
if (my_chsize(share->kfile,info->state->key_file_length,MYF(0)))
......@@ -2115,6 +2111,7 @@ static int sort_key_read(SORT_INFO *sort_info, void *key)
DBUG_RETURN(sort_write_record(sort_info));
} /* sort_key_read */
static int sort_ft_key_read(SORT_INFO *sort_info, void *key)
{
int error;
......@@ -2540,7 +2537,7 @@ int sort_write_record(SORT_INFO *sort_info)
DBUG_RETURN(1);
}
sort_info->filepos+=share->base.pack_reclength;
info->s->state.checksum+=mi_static_checksum(info, sort_info->record);
/* sort_info->param->glob_crc+=mi_static_checksum(info, sort_info->record); */
break;
case DYNAMIC_RECORD:
if (! info->blobs)
......@@ -2564,7 +2561,7 @@ int sort_write_record(SORT_INFO *sort_info)
}
info->checksum=mi_checksum(info,sort_info->record);
reclength=_mi_rec_pack(info,from,sort_info->record);
info->s->state.checksum+=info->checksum;
/* sort_info->param->glob_crc+=info->checksum; */
block_length=reclength+ 3 + test(reclength >= (65520-3));
if (block_length < share->base.min_block_length)
block_length=share->base.min_block_length;
......@@ -2578,7 +2575,7 @@ int sort_write_record(SORT_INFO *sort_info)
DBUG_RETURN(1);
}
sort_info->filepos+=block_length;
info->s->state.checksum+=info->checksum;
/* sort_info->param->glob_crc+=info->checksum; */
break;
case COMPRESSED_RECORD:
reclength=info->packed_length;
......@@ -2591,7 +2588,7 @@ int sort_write_record(SORT_INFO *sort_info)
mi_check_print_error(param,"%d when writing to datafile",my_errno);
DBUG_RETURN(1);
}
info->s->state.checksum+=info->checksum;
/* sort_info->param->glob_crc+=info->checksum; */
sort_info->filepos+=reclength+length;
break;
}
......@@ -2808,9 +2805,9 @@ static int sort_delete_record(MI_CHECK *param)
DBUG_RETURN(1);
}
}
if (info->s->calc_checksum)
info->s->state.checksum-=(*info->s->calc_checksum)(info,
sort_info->record);
if (param->calc_checksum)
param->glob_crc-=(*info->s->calc_checksum)(info,
sort_info->record);
}
error=flush_io_cache(&info->rec_cache) || (*info->s->delete_record)(info);
info->dfile=old_file; /* restore actual value */
......
......@@ -227,8 +227,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.key_del=key_del;
if (uniques)
{
max_key_block_length= MI_KEY_BLOCK_LENGTH;
max_key_length= MI_UNIQUE_HASH_LENGTH;
max_key_block_length= myisam_block_size;
max_key_length= MI_UNIQUE_HASH_LENGTH;
}
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
......@@ -370,7 +370,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE);
if (keydef->block_length/MI_KEY_BLOCK_LENGTH > MI_MAX_KEY_BLOCK_SIZE)
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH)
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err;
......@@ -386,7 +386,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
(length*2)))*
(ulong) keydef->block_length;
}
for (i=max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
for (i=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
key_del[i]=HA_OFFSET_ERROR;
unique_key_parts=0;
......@@ -401,7 +401,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
key_segs+=uniques; /* Each unique has 1 key seg */
base_pos=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
max_key_block_length/MI_KEY_BLOCK_LENGTH*MI_STATE_KEYBLOCK_SIZE+
max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH*
MI_STATE_KEYBLOCK_SIZE+
key_segs*MI_STATE_KEYSEG_SIZE);
info_length=base_pos+(uint) (MI_BASE_INFO_SIZE+
keys * MI_KEYDEF_SIZE+
......@@ -420,7 +421,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.language= (ci->language ?
ci->language : MY_CHARSET_CURRENT);
share.state.header.max_block_size=max_key_block_length/MI_KEY_BLOCK_LENGTH;
share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
......@@ -433,7 +434,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.base.rec_reflength=pointer;
share.base.key_reflength=
mi_get_pointer_length((tot_length + max_key_block_length * keys *
MI_INDEX_BLOCK_MARGIN) / MI_KEY_BLOCK_LENGTH,
MI_INDEX_BLOCK_MARGIN) / MI_MIN_KEY_BLOCK_LENGTH,
3);
share.base.keys= share.state.header.keys = keys;
share.state.header.uniques= uniques;
......@@ -575,7 +576,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
tmp_keydef.keysegs=1;
tmp_keydef.flag= HA_UNIQUE_CHECK;
tmp_keydef.block_length= MI_KEY_BLOCK_LENGTH;
tmp_keydef.block_length= myisam_block_size;
tmp_keydef.keylength= MI_UNIQUE_HASH_LENGTH + pointer;
tmp_keydef.minlength=tmp_keydef.maxlength=tmp_keydef.keylength;
tmp_keyseg.type= MI_UNIQUE_HASH_TYPE;
......
......@@ -196,7 +196,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("d_search");
DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff));
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,key_length,SEARCH_SAME,
flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key, USE_WHOLE_KEY,
SEARCH_SAME,
&keypos, lastkey, &last_key);
if (flag == MI_FOUND_WRONG_KEY)
{
......
......@@ -43,7 +43,7 @@ int mi_delete_all_rows(MI_INFO *info)
info->state->empty=info->state->key_empty=0;
state->checksum=0;
for (i=share->base.max_key_block_length/MI_KEY_BLOCK_LENGTH ; i-- ; )
for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
state->key_del[i]= HA_OFFSET_ERROR;
for (i=0 ; i < share->base.keys ; i++)
state->key_root[i]= HA_OFFSET_ERROR;
......
......@@ -1059,11 +1059,11 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
} while (left_length);
info->update|= HA_STATE_AKTIV; /* We have a aktive record */
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
DBUG_RETURN(_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR ? 0 : -1);
}
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
DBUG_RETURN(-1); /* Wrong data to read */
panic:
......@@ -1393,8 +1393,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
} while (left_len);
info->update|= HA_STATE_AKTIV | HA_STATE_KEY_CHANGED;
if (share->r_locks == 0 && share->w_locks == 0)
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
if (_mi_rec_unpack(info,buf,info->rec_buff,block_info.rec_len) !=
MY_FILE_ERROR)
DBUG_RETURN(0);
......
......@@ -45,7 +45,7 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag)
{
pthread_mutex_lock(&share->intern_lock);
VOID(_mi_readinfo(info,F_RDLCK,0));
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
pthread_mutex_unlock(&share->intern_lock);
}
if (flag & HA_STATUS_VARIABLE)
......
......@@ -346,7 +346,7 @@ err:
int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
{
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
if (filepos != HA_OFFSET_ERROR)
{
if (info->lastinx >= 0)
......
......@@ -50,6 +50,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
count= --share->r_locks;
else
count= --share->w_locks;
--share->tot_locks;
if (info->lock_type == F_WRLCK && !share->w_locks &&
!share->delay_key_write && flush_key_blocks(share->kfile,FLUSH_KEEP))
{
......@@ -153,6 +154,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
VOID(_mi_test_if_changed(info));
share->r_locks++;
share->tot_locks++;
info->lock_type=lock_type;
break;
case F_WRLCK:
......@@ -200,6 +202,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
VOID(_mi_test_if_changed(info));
info->lock_type=lock_type;
share->w_locks++;
share->tot_locks++;
break;
default:
break; /* Impossible */
......@@ -295,13 +298,12 @@ my_bool mi_check_status(void* param)
int _mi_readinfo(register MI_INFO *info, int lock_type, int check_keybuffer)
{
MYISAM_SHARE *share;
DBUG_ENTER("_mi_readinfo");
share=info->s;
if (info->lock_type == F_UNLCK)
{
if (!share->r_locks && !share->w_locks)
MYISAM_SHARE *share=info->s;
if (!share->tot_locks)
{
if ((info->tmp_lock_type=lock_type) != F_RDLCK)
if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
......@@ -339,7 +341,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
DBUG_ENTER("_mi_writeinfo");
error=0;
if (share->r_locks == 0 && share->w_locks == 0)
if (share->tot_locks == 0)
{
olderror=my_errno; /* Remember last error */
if (operation)
......
......@@ -217,7 +217,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
(mi_safe_mul(share->base.reclength,
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
max_key_file_length=
mi_safe_mul(MI_KEY_BLOCK_LENGTH,
mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
......@@ -913,7 +913,7 @@ char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
keydef->keylength = mi_uint2korr(ptr); ptr +=2;
keydef->minlength = mi_uint2korr(ptr); ptr +=2;
keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
keydef->block_size = keydef->block_length/MI_KEY_BLOCK_LENGTH-1;
keydef->block_size = keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */
return ptr;
......
......@@ -64,9 +64,9 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
#ifndef FAST /* Safety check */
if (page < info->s->base.keystart ||
page+keyinfo->block_length > info->state->key_file_length ||
page & (myisam_block_size-1))
(page & (MI_MIN_KEY_BLOCK_LENGTH-1)))
{
DBUG_PRINT("error",("Trying to write outside key region: %lu",
DBUG_PRINT("error",("Trying to write inside key status region: %lu",
(long) page));
my_errno=EINVAL;
return(-1);
......
......@@ -45,7 +45,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(HA_POS_ERROR);
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(HA_POS_ERROR);
info->update&= (HA_STATE_CHANGED+HA_STATE_ROW_CHANGED);
if (info->s->concurrent_insert)
......@@ -58,7 +58,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
info->state->records+ (ha_rows) 1);
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR)
DBUG_RETURN(HA_POS_ERROR);
DBUG_PRINT("info",("records: %ld",(ulong) (end_pos-start_pos)));
......@@ -72,7 +72,7 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key,
static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
enum ha_rkey_function search_flag)
{
uint inx=(uint) info->lastinx;
uint inx=(uint) info->lastinx, nextflag;
MI_KEYDEF *keyinfo=info->s->keyinfo+inx;
uchar *key_buff;
double pos;
......@@ -86,8 +86,12 @@ static ha_rows _mi_record_pos(MI_INFO *info, const byte *key, uint key_len,
key_len=_mi_pack_key(info,inx,key_buff,(uchar*) key,key_len);
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,
(uchar*) key_buff,key_len););
nextflag=myisam_read_vec[search_flag];
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
key_len=USE_WHOLE_KEY;
pos=_mi_search_pos(info,keyinfo,key_buff,key_len,
myisam_read_vec[search_flag] | SEARCH_SAVE_BUFF,
nextflag | SEARCH_SAVE_BUFF,
info->s->state.key_root[inx]);
if (pos >= 0.0)
{
......@@ -145,9 +149,9 @@ static double _mi_search_pos(register MI_INFO *info,
** Matches keynr+1
*/
offset=1.0; /* Matches keynr+1 */
if (nextflag & SEARCH_FIND &&
if ((nextflag & SEARCH_FIND) && nod_flag &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
key_len) && nod_flag)
key_len != USE_WHOLE_KEY))
{
/*
** There may be identical keys in the tree. Try to match on of those.
......
......@@ -27,7 +27,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
{
uchar *key_buff;
MYISAM_SHARE *share=info->s;
uint pack_key_length;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
info,inx,search_flag));
......@@ -55,11 +55,17 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
bmove(key_buff,key,key_len);
}
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
goto err;
if (share->concurrent_insert)
rw_rdlock(&share->key_root_lock[inx]);
if (!_mi_search(info,info->s->keyinfo+inx,key_buff,pack_key_length,
nextflag=myisam_read_vec[search_flag];
use_key_length=pack_key_length;
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
use_key_length=USE_WHOLE_KEY;
if (!_mi_search(info,info->s->keyinfo+inx,key_buff,use_key_length,
myisam_read_vec[search_flag],info->s->state.key_root[inx]))
{
while (info->lastpos >= info->state->data_file_length)
......
......@@ -35,7 +35,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_PREV_FOUND)
flag=0; /* Read first */
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
......@@ -51,7 +51,7 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
info->s->state.key_root[inx]);
else
error=_mi_search(info,info->s->keyinfo+inx,info->lastkey,
info->lastkey_length,flag, info->s->state.key_root[inx]);
USE_WHOLE_KEY,flag, info->s->state.key_root[inx]);
if (!error)
{
......
......@@ -35,7 +35,7 @@ int mi_rnext_same(MI_INFO *info, byte *buf)
DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX);
keyinfo=info->s->keyinfo+inx;
flag=SEARCH_BIGGER; /* Read next */
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
memcpy(info->lastkey2,info->lastkey,info->last_rkey_length);
......
......@@ -36,7 +36,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
if (info->lastpos == HA_OFFSET_ERROR && info->update & HA_STATE_NEXT_FOUND)
flag=0; /* Read last */
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
changed=_mi_test_if_changed(info);
if (share->concurrent_insert)
......@@ -50,7 +50,7 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
share->state.key_root[inx]);
else
error=_mi_search(info,share->keyinfo+inx,info->lastkey,
info->lastkey_length, flag, share->state.key_root[inx]);
USE_WHOLE_KEY, flag, share->state.key_root[inx]);
if (!error)
{
......
......@@ -41,7 +41,7 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
/* Read row from data file */
if (_mi_readinfo(info,F_RDLCK,1))
if (fast_mi_readinfo(info))
DBUG_RETURN(my_errno);
if (inx >= 0)
......@@ -51,7 +51,8 @@ int mi_rsame(MI_INFO *info, byte *record, int inx)
info->lastpos);
if (info->s->concurrent_insert)
rw_rdlock(&info->s->key_root_lock[inx]);
VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey,0,SEARCH_SAME,
VOID(_mi_search(info,info->s->keyinfo+inx,info->lastkey, USE_WHOLE_KEY,
SEARCH_SAME,
info->s->state.key_root[inx]));
if (info->s->concurrent_insert)
rw_unlock(&info->s->key_root_lock[inx]);
......
......@@ -107,14 +107,15 @@ int _mi_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
}
else
{
if (nextflag & SEARCH_FIND && (!(keyinfo->flag & HA_NOSAME)
|| key_len) && nod_flag)
if ((nextflag & SEARCH_FIND) && nod_flag &&
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
key_len != USE_WHOLE_KEY))
{
if ((error=_mi_search(info,keyinfo,key,key_len,SEARCH_FIND,
_mi_kpos(nod_flag,keypos))) >= 0 ||
my_errno != HA_ERR_KEY_NOT_FOUND)
DBUG_RETURN(error);
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in memory */
info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
}
}
if (pos != info->last_keypage)
......@@ -283,8 +284,6 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
LINT_INIT(saved_vseg);
t_buff[0]=0; /* Avoid bugs */
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
key_len=USE_WHOLE_KEY;
end= page+mi_getint(page);
nod_flag=mi_test_if_nod(page);
page+=2+nod_flag;
......@@ -477,11 +476,11 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
switch (nod_flag) {
#if SIZEOF_OFF_T > 4
case 7:
return mi_uint7korr(after_key)*MI_KEY_BLOCK_LENGTH;
return mi_uint7korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 6:
return mi_uint6korr(after_key)*MI_KEY_BLOCK_LENGTH;
return mi_uint6korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 5:
return mi_uint5korr(after_key)*MI_KEY_BLOCK_LENGTH;
return mi_uint5korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH;
#else
case 7:
after_key++;
......@@ -491,13 +490,13 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
after_key++;
#endif
case 4:
return ((my_off_t) mi_uint4korr(after_key))*MI_KEY_BLOCK_LENGTH;
return ((my_off_t) mi_uint4korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 3:
return ((my_off_t) mi_uint3korr(after_key))*MI_KEY_BLOCK_LENGTH;
return ((my_off_t) mi_uint3korr(after_key))*MI_MIN_KEY_BLOCK_LENGTH;
case 2:
return (my_off_t) (mi_uint2korr(after_key)*MI_KEY_BLOCK_LENGTH);
return (my_off_t) (mi_uint2korr(after_key)*MI_MIN_KEY_BLOCK_LENGTH);
case 1:
return (uint) (*after_key)*MI_KEY_BLOCK_LENGTH;
return (uint) (*after_key)*MI_MIN_KEY_BLOCK_LENGTH;
case 0: /* At leaf page */
default: /* Impossible */
return(HA_OFFSET_ERROR);
......@@ -509,7 +508,7 @@ my_off_t _mi_kpos(uint nod_flag, uchar *after_key)
void _mi_kpointer(register MI_INFO *info, register uchar *buff, my_off_t pos)
{
pos/=MI_KEY_BLOCK_LENGTH;
pos/=MI_MIN_KEY_BLOCK_LENGTH;
switch (info->s->base.key_reflength) {
#if SIZEOF_OFF_T > 4
case 7: mi_int7store(buff,pos); break;
......@@ -719,10 +718,7 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a,
double d_1,d_2;
uint next_key_length;
if (!(nextflag & (SEARCH_FIND | SEARCH_NO_FIND | SEARCH_LAST)))
key_length=USE_WHOLE_KEY;
*diff_pos=0;
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
{
uchar *end;
......@@ -1446,7 +1442,7 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
info->page_changed ||
(info->int_keytree_version != keyinfo->version &&
(info->int_nod_flag || info->buff_used)))
DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, pos));
if (info->buff_used)
......@@ -1459,17 +1455,17 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
/* Last used buffer is in info->buff */
nod_flag=mi_test_if_nod(info->buff);
memcpy(lastkey,key,key_length);
if (nextflag & SEARCH_BIGGER) /* Next key */
{
my_off_t tmp_pos=_mi_kpos(nod_flag,info->int_keypos);
if (tmp_pos != HA_OFFSET_ERROR)
{
if ((error=_mi_search(info,keyinfo,key,key_length,
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, tmp_pos)) <=0)
DBUG_RETURN(error);
}
memcpy(lastkey,key,key_length);
if (!(info->lastkey_length=(*keyinfo->get_key)(keyinfo,nod_flag,
&info->int_keypos,lastkey)))
DBUG_RETURN(-1);
......@@ -1483,12 +1479,14 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (!info->int_keypos)
DBUG_RETURN(-1);
if (info->int_keypos == info->buff+2)
DBUG_RETURN(_mi_search(info,keyinfo,key,key_length,
DBUG_RETURN(_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF, pos));
if ((error=_mi_search(info,keyinfo,key,0,nextflag | SEARCH_SAVE_BUFF,
if ((error=_mi_search(info,keyinfo,key, USE_WHOLE_KEY,
nextflag | SEARCH_SAVE_BUFF,
_mi_kpos(nod_flag,info->int_keypos))) <= 0)
DBUG_RETURN(error);
/* QQ: We should be able to optimize away the following call */
if (! _mi_get_last_key(info,keyinfo,info->buff,lastkey,
info->int_keypos,&info->lastkey_length))
DBUG_RETURN(-1);
......
......@@ -40,7 +40,7 @@ my_bool myisam_concurrent_insert=0;
#endif
my_off_t myisam_max_extra_temp_length= MI_MAX_TEMP_LENGTH;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
uint myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_bulk_insert_tree_size=8192*1024;
/* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ */
/* Position is , == , >= , <= , > , < */
......
......@@ -181,8 +181,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
error=my_pread(info->dfile,(char*) record,info->s->base.reclength,
pos,MYF(MY_NABP)) != 0;
if (info->s->r_locks == 0 && info->s->w_locks == 0)
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
if (! error)
{
if (!*record)
......@@ -195,7 +194,7 @@ int _mi_read_static_record(register MI_INFO *info, register my_off_t pos,
}
return(-1); /* Error on read */
}
VOID(_mi_writeinfo(info,0)); /* No such record */
fast_mi_writeinfo(info); /* No such record */
return(-1);
}
......@@ -257,7 +256,7 @@ int _mi_read_rnd_static_record(MI_INFO *info, byte *buf,
DBUG_PRINT("test",("filepos: %ld (%ld) records: %ld del: %ld",
filepos/share->base.reclength,filepos,
info->state->records, info->state->del));
VOID(_mi_writeinfo(info,0));
fast_mi_writeinfo(info);
DBUG_RETURN(my_errno=HA_ERR_END_OF_FILE);
}
info->lastpos= filepos;
......
......@@ -343,68 +343,72 @@ int main(int argc, char *argv[])
}
if (testflag==3) goto end;
if (!silent)
printf("- Same key: first - next -> last - prev -> first\n");
DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
for (i=999, dupp_keys=j=0 ; i>0 ; i--)
{
if (key1[i] >dupp_keys) { dupp_keys=key1[i]; j=i; }
if (key1[i] > dupp_keys) { dupp_keys=key1[i]; j=i; }
}
sprintf(key,"%6d",j);
if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err;
if (mi_rsame(file,read_record2,-1)) goto err;
if (memcmp(read_record,read_record2,reclength) != 0)
{
printf("mi_rsame didn't find same record\n");
goto end;
}
info.recpos=mi_position(file);
if (mi_rfirst(file,read_record2,0) ||
mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
memcmp(read_record,read_record2,reclength) != 0)
if (dupp_keys)
{
printf("mi_rsame_with_pos didn't find same record\n");
goto end;
}
{
int skr=mi_rnext(file,read_record2,0);
if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
mi_rprev(file,read_record2,-1) ||
if (!silent)
printf("- Same key: first - next -> last - prev -> first\n");
DBUG_PRINT("progpos",("first - next -> last - prev -> first"));
if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys);
if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err;
if (mi_rsame(file,read_record2,-1)) goto err;
if (memcmp(read_record,read_record2,reclength) != 0)
{
printf("mi_rsame didn't find same record\n");
goto end;
}
info.recpos=mi_position(file);
if (mi_rfirst(file,read_record2,0) ||
mi_rsame_with_pos(file,read_record2,0,info.recpos) ||
memcmp(read_record,read_record2,reclength) != 0)
{
printf("mi_rsame_with_pos lost position\n");
printf("mi_rsame_with_pos didn't find same record\n");
goto end;
}
{
int skr=mi_rnext(file,read_record2,0);
if ((skr && my_errno != HA_ERR_END_OF_FILE) ||
mi_rprev(file,read_record2,-1) ||
memcmp(read_record,read_record2,reclength) != 0)
{
printf("mi_rsame_with_pos lost position\n");
goto end;
}
}
ant=1;
start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length;
while (mi_rnext(file,read_record2,0) == 0 &&
memcmp(read_record2+start,key,length) == 0) ant++;
if (ant != dupp_keys)
{
printf("next: Found: %d keys of %d\n",ant,dupp_keys);
goto end;
}
ant=0;
while (mi_rprev(file,read_record3,0) == 0 &&
bcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys)
{
printf("prev: Found: %d records of %d\n",ant,dupp_keys);
goto end;
}
}
ant=1;
start=keyinfo[0].seg[0].start; length=keyinfo[0].seg[0].length;
while (mi_rnext(file,read_record2,0) == 0 &&
memcmp(read_record2+start,key,length) == 0) ant++;
if (ant != dupp_keys)
{
printf("next: Found: %d keys of %d\n",ant,dupp_keys);
goto end;
}
ant=0;
while (mi_rprev(file,read_record3,0) == 0 &&
bcmp(read_record3+start,key,length) == 0) ant++;
if (ant != dupp_keys)
{
printf("prev: Found: %d records of %d\n",ant,dupp_keys);
goto end;
}
/* Check of mi_rnext_same */
if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
goto err;
ant=1;
while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
ant++;
if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
{
printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
goto end;
/* Check of mi_rnext_same */
if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT))
goto err;
ant=1;
while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10)
ant++;
if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE)
{
printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys);
goto end;
}
}
if (!silent)
......@@ -776,9 +780,13 @@ end:
printf("\nFollowing test have been made:\n");
printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete);
if (rec_pointer_size)
printf("Record pointer size: %d\n",rec_pointer_size);
printf("Record pointer size: %d\n",rec_pointer_size);
printf("myisam_block_size: %u\n", myisam_block_size);
if (key_cacheing)
{
puts("Key cacheing used");
printf("key_cache_block_size: %u\n", key_cache_block_size);
}
if (write_cacheing)
puts("Write cacheing used");
if (write_cacheing)
......@@ -801,7 +809,7 @@ reads: %10lu\n",
end_key_cache();
if (blob_buffer)
my_free(blob_buffer,MYF(0));
my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
return(0);
err:
printf("got error: %d when using MyISAM-database\n",my_errno);
......@@ -861,7 +869,29 @@ static void get_options(int argc, char **argv)
verbose=1;
break;
case 'm': /* records */
recant=atoi(++pos);
if ((recant=atoi(++pos)) < 10)
{
fprintf(stderr,"record count must be >= 10\n");
exit(1);
}
break;
case 'e': /* myisam_block_length */
if ((myisam_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH)
{
fprintf(stderr,"Wrong myisam_block_length\n");
exit(1);
}
myisam_block_size=1 << my_bit_log2(myisam_block_size);
break;
case 'E': /* myisam_block_length */
if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH ||
key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH)
{
fprintf(stderr,"Wrong key_cache_block_size\n");
exit(1);
}
key_cache_block_size=1 << my_bit_log2(key_cache_block_size);
break;
case 'f':
if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS)
......@@ -904,7 +934,7 @@ static void get_options(int argc, char **argv)
case 'V':
printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
puts("By Monty, for your professional use\n");
printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-t#]\n",
printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n",
progname);
exit(0);
case '#':
......
Maximum memory usage: 545477 bytes (533k)
Maximum memory usage: 545477 bytes (533k)
Maximum memory usage: 545369 bytes (533k)
mi_test2-i686 -s -L -K -R1 -m2000 ; Should give error 135
mi_test2 -s -L -K -R1 -m2000 ; Should give error 135
Error: 135 in write at record: 1105
got error: 135 when using MyISAM-database
Maximum memory usage: 29439 bytes (29k)
Maximum memory usage: 66541 bytes (65k)
Maximum memory usage: 5101 bytes (5k)
Maximum memory usage: 545488 bytes (533k)
myisamchk: MyISAM file test2
myisamchk: warning: Datafile is almost full, 65532 of 65534 used
MyISAM-table 'test2' is usable but should be fixed
Commands Used count Errors Recover errors
open 1 0 0
write 50 0 0
update 5 0 0
delete 50 0 0
close 1 0 0
extra 6 0 0
Total 113 0 0
Maximum memory usage: 545744 bytes (533k)
open 17 0 0
write 850 0 0
update 85 0 0
delete 850 0 0
close 17 0 0
extra 102 0 0
Total 1921 0 0
Commands Used count Errors Recover errors
open 2 0 0
write 100 0 0
update 10 0 0
delete 100 0 0
close 2 0 0
extra 12 0 0
Total 226 0 0
Maximum memory usage: 5101 bytes (5k)
1.12user 0.52system 0:01.71elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (214major+25minor)pagefaults 0swaps
Maximum memory usage: 21189 bytes (21k)
1.29user 0.55system 0:01.82elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (215major+29minor)pagefaults 0swaps
Maximum memory usage: 66541 bytes (65k)
1.10user 0.51system 0:01.66elapsed 96%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (216major+40minor)pagefaults 0swaps
Maximum memory usage: 82629 bytes (81k)
1.33user 0.24system 0:01.54elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (216major+44minor)pagefaults 0swaps
Maximum memory usage: 545477 bytes (533k)
1.31user 0.24system 0:01.55elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (216major+173minor)pagefaults 0swaps
Maximum memory usage: 545389 bytes (533k)
1.37user 0.18system 0:01.57elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (218major+180minor)pagefaults 0swaps
Maximum memory usage: 109165 bytes (107k)
1.42user 0.38system 0:01.78elapsed 101%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (218major+51minor)pagefaults 0swaps
open 18 0 0
write 900 0 0
update 90 0 0
delete 900 0 0
close 18 0 0
extra 108 0 0
Total 2034 0 0
real 0m1.054s
user 0m0.410s
sys 0m0.640s
real 0m1.077s
user 0m0.550s
sys 0m0.530s
real 0m1.100s
user 0m0.420s
sys 0m0.680s
real 0m0.783s
user 0m0.590s
sys 0m0.200s
real 0m0.764s
user 0m0.560s
sys 0m0.210s
real 0m0.699s
user 0m0.570s
sys 0m0.130s
real 0m0.991s
user 0m0.630s
sys 0m0.350s
......@@ -66,6 +66,14 @@ myisamchk$suffix -rs test1
myisamchk$suffix -se test1
myisamchk$suffix -rqs test1
myisamchk$suffix -se test1
myisamchk$suffix -rs --correct-checksum test1
myisamchk$suffix -se test1
myisamchk$suffix -rqs --correct-checksum test1
myisamchk$suffix -se test1
myisamchk$suffix -ros --correct-checksum test1
myisamchk$suffix -se test1
myisamchk$suffix -rqos --correct-checksum test1
myisamchk$suffix -se test1
# check of myisampack / myisamchk
myisampack$suffix --force -s test1
......@@ -105,13 +113,25 @@ mi_test1$suffix $silent --key_multiple -P -S
myisamchk$suffix -sm test1
mi_test2$suffix $silent -L -K -W -P
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -A
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -S -R1 -m500
echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -R1 -m2000
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -B
myisamchk$suffix -sm test2
mi_test2$suffix $silent -D -B -c
myisamchk$suffix -sm test2
mi_test2$suffix $silent -m10000 -e8192 -K
myisamchk$suffix -sm test2
mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
myisamchk$suffix -sm test2
mi_test2$suffix $silent -L -K -W -P -m50 -l
myisamlog$suffix
mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
......
......@@ -291,7 +291,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
my_bool insert_last)
{
int error,flag;
uint comp_flag,nod_flag;
uint comp_flag,nod_flag, search_key_length;
uchar *temp_buff,*keypos;
uchar keybuff[MI_MAX_KEY_BUFF];
my_bool was_last_key;
......@@ -299,10 +299,14 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_ENTER("w_search");
DBUG_PRINT("enter",("page: %ld",page));
search_key_length=USE_WHOLE_KEY;
if (keyinfo->flag & HA_SORT_ALLOWS_SAME)
comp_flag=SEARCH_BIGGER; /* Put after same key */
else if (keyinfo->flag & HA_NOSAME)
{
comp_flag=SEARCH_FIND | SEARCH_UPDATE; /* No dupplicates */
search_key_length= key_length;
}
else
comp_flag=SEARCH_SAME; /* Keys in rec-pos order */
......@@ -312,8 +316,8 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (!_mi_fetch_keypage(info,keyinfo,page,temp_buff,0))
goto err;
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,key_length,comp_flag,
&keypos, keybuff, &was_last_key);
flag=(*keyinfo->bin_search)(info,keyinfo,temp_buff,key,search_key_length,
comp_flag, &keypos, keybuff, &was_last_key);
nod_flag=mi_test_if_nod(temp_buff);
if (flag == 0)
{
......
......@@ -40,6 +40,7 @@ static char **default_argv;
static const char *load_default_groups[]= { "myisamchk", 0 };
static const char *set_charset_name;
static CHARSET_INFO *set_charset;
static long opt_myisam_block_size;
static const char *type_names[]=
{ "?","char","binary", "short", "long", "float",
......@@ -141,6 +142,9 @@ int main(int argc, char **argv)
static CHANGEABLE_VAR changeable_vars[] = {
{ "key_buffer_size",(long*) &check_param.use_buffers,(long) USE_BUFFER_INIT,
(long) MALLOC_OVERHEAD, (long) ~0L,(long) MALLOC_OVERHEAD,(long) IO_SIZE },
{ "myisam_block_size", (long*) &opt_myisam_block_size,
MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
0, MI_MIN_KEY_BLOCK_LENGTH },
{ "read_buffer_size", (long*) &check_param.read_buffer_length,(long) READ_BUFFER_INIT,
(long) MALLOC_OVERHEAD,(long) ~0L,(long) MALLOC_OVERHEAD,(long) 1L },
{ "write_buffer_size", (long*) &check_param.write_buffer_length,(long) READ_BUFFER_INIT,
......@@ -159,7 +163,10 @@ static CHANGEABLE_VAR changeable_vars[] = {
20, 4, HA_FT_MAXLEN, 0, 1 },
{ NullS,(long*) 0,0L,0L,0L,0L,0L,} };
enum options {OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS};
enum options {
OPT_CHARSETS_DIR=256, OPT_SET_CHARSET,OPT_START_CHECK_POS,
OPT_CORRECT_CHECKSUM
};
static struct option long_options[] =
......@@ -167,9 +174,10 @@ static struct option long_options[] =
{"analyze", no_argument, 0, 'a'},
{"block-search", required_argument,0, 'b'},
{"backup", no_argument, 0, 'B'},
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
{"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR},
{"check", no_argument, 0, 'c'},
{"check-only-changed",no_argument, 0, 'C'},
{"correct-checksum", no_argument, 0, OPT_CORRECT_CHECKSUM},
#ifndef DBUG_OFF
{"debug", optional_argument, 0, '#'},
#endif
......@@ -205,7 +213,7 @@ static struct option long_options[] =
static void print_version(void)
{
printf("%s Ver 1.51 for %s at %s\n",my_progname,SYSTEM_TYPE,
printf("%s Ver 1.52 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
}
......@@ -248,6 +256,7 @@ static void usage(void)
puts("Repair options (When using -r or -o) \n\
-B, --backup Make a backup of the .MYD file as 'filename-time.BAK'\n\
--correct-checksum Correct checksum information for table. \n\
-D, --data-file-length=# Max length of data file (when recreating data\n\
file when it's full)\n\
-e, --extend-check Try to recover every possible row from the data file\n\
......@@ -433,6 +442,9 @@ static void get_options(register int *argc,register char ***argv)
case 'V':
print_version();
exit(0);
case OPT_CORRECT_CHECKSUM:
check_param.testflag|=T_CALC_CHECKSUM;
break;
case OPT_CHARSETS_DIR:
charsets_dir = optarg;
break;
......@@ -449,6 +461,11 @@ static void get_options(register int *argc,register char ***argv)
exit(0);
}
}
/* If using repair, then update checksum if one uses --update-state */
if ((check_param.testflag & T_UPDATE_STATE) &&
(check_param.testflag & (T_REP | T_REP_BY_SORT)))
check_param.testflag|= T_CALC_CHECKSUM;
(*argc)-=optind;
(*argv)+=optind;
if (*argc == 0)
......@@ -456,6 +473,7 @@ static void get_options(register int *argc,register char ***argv)
usage();
exit(-1);
}
if ((check_param.testflag & T_UNPACK) &&
(check_param.opt_rep_quick || (check_param.testflag & T_SORT_RECORDS)))
{
......@@ -479,6 +497,7 @@ static void get_options(register int *argc,register char ***argv)
if (!(set_charset=get_charset_by_name(set_charset_name, MYF(MY_WME))))
exit(1);
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
return;
} /* get options */
......@@ -605,7 +624,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
(((ulonglong) 1L << share->base.keys)-1)) ||
test_if_almost_full(info) ||
info->s->state.header.file_version[3] != myisam_file_magic[3] ||
(set_charset && set_charset->number != share->state.header.language)))
(set_charset && set_charset->number != share->state.header.language) ||
myisam_block_size != MI_KEY_BLOCK_LENGTH))
{
if (set_charset)
check_param.language=set_charset->number;
......
......@@ -173,7 +173,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
File data_file; /* Shared data file */
int mode; /* mode of file on open */
uint reopen; /* How many times reopened */
uint w_locks,r_locks; /* Number of read/write locks */
uint w_locks,r_locks,tot_locks; /* Number of read/write locks */
uint blocksize; /* blocksize of keyfile */
ulong min_pack_length; /* Theese are used by packed data */
ulong max_pack_length;
......@@ -365,10 +365,8 @@ struct st_myisam_info {
#define PACK_TYPE_ZERO_FILL 4
#define MI_FOUND_WRONG_KEY 32738 /* Impossible value from _mi_key_cmp */
#define MI_KEY_BLOCK_LENGTH 1024 /* Min key block length */
#define MI_MAX_KEY_BLOCK_LENGTH 8192
#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_KEY_BLOCK_LENGTH)
#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/MI_KEY_BLOCK_LENGTH+1)*MI_KEY_BLOCK_LENGTH)
#define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/myisam_block_size+1)*myisam_block_size)
#define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */
#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */
......@@ -589,6 +587,9 @@ enum myisam_log_commands {
#define myisam_log_command(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_command(a,b,c,d,e)
#define myisam_log_record(a,b,c,d,e) if (myisam_log_file >= 0) _myisam_log_record(a,b,c,d,e)
#define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0)
#define fast_mi_readinfo(INFO) (!(INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1)
#ifdef __cplusplus
extern "C" {
#endif
......
......@@ -45,7 +45,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_quick.c my_lockmem.c my_static.c \
getopt.c getopt1.c getvar.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc my_net.c \
my_vsnprintf.c charset.c my_bitmap.c
my_vsnprintf.c charset.c my_bitmap.c my_bit.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c
libmysys_a_LIBADD = @THREAD_LOBJECTS@
......
......@@ -53,7 +53,6 @@ typedef struct sec_link {
} SEC_LINK;
static uint find_next_bigger_power(uint value);
static SEC_LINK *find_key_block(int file,my_off_t filepos,int *error);
/* static variables in this file */
......@@ -61,9 +60,11 @@ static SEC_LINK *_my_block_root,**_my_hash_root,
*_my_used_first,*_my_used_last;
static int _my_disk_blocks;
static uint _my_disk_blocks_used, _my_hash_blocks;
static uint key_cache_shift;
ulong _my_blocks_used,_my_blocks_changed;
ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
uint key_cache_block_size=DEFAULT_KEYCACHE_BLOCK_SIZE;
static byte HUGE_PTR *_my_block_mem;
static SEC_LINK *changed_blocks[CHANGED_BLOCKS_HASH];
static SEC_LINK *file_blocks[CHANGED_BLOCKS_HASH];
......@@ -92,12 +93,16 @@ int init_key_cache(ulong use_mem,
{
key_cache_inited=TRUE;
_my_disk_blocks= -1;
key_cache_shift=my_bit_log2(key_cache_block_size);
DBUG_PRINT("info",("key_cache_block_size: %u key_cache_shift: %u",
key_cache_block_size, key_cache_shift));
#ifndef DBUG_OFF
_my_printed=0;
#endif
}
blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+KEYCACHE_BLOCK_SIZE));
blocks= (uint) (use_mem/(sizeof(SEC_LINK)+sizeof(SEC_LINK*)*5/4+
key_cache_block_size));
/* No use to have very few blocks */
if (blocks >= 8 && _my_disk_blocks < 0)
{
......@@ -107,13 +112,15 @@ int init_key_cache(ulong use_mem,
#endif
for (;;)
{
if ((_my_hash_blocks=find_next_bigger_power((uint) blocks)) < blocks*5/4)
_my_hash_blocks<<=1;
/* Set my_hash_blocks to the next bigger 2 power */
_my_hash_blocks=(uint) 1 << (my_bit_log2(blocks*5/4)+1);
while ((length=(uint) blocks*sizeof(SEC_LINK)+
sizeof(SEC_LINK*)*_my_hash_blocks)+(ulong) blocks*KEYCACHE_BLOCK_SIZE >
sizeof(SEC_LINK*)*_my_hash_blocks)+
((ulong) blocks << key_cache_shift) >
use_mem)
blocks--;
if ((_my_block_mem=my_malloc_lock((ulong) blocks * KEYCACHE_BLOCK_SIZE,MYF(0))))
if ((_my_block_mem=my_malloc_lock((ulong) blocks << key_cache_shift,
MYF(0))))
{
if ((_my_block_root=(SEC_LINK*) my_malloc((uint) length,MYF(0))) != 0)
break;
......@@ -170,17 +177,6 @@ void end_key_cache(void)
} /* end_key_cache */
static uint find_next_bigger_power(uint value)
{
uint old_value=1;
while (value)
{
old_value=value;
value&= value-1;
}
return (old_value << 1);
}
static inline void link_into_file_blocks(SEC_LINK *next, int file)
{
reg1 SEC_LINK **ptr= &file_blocks[(uint) file & CHANGED_BLOCKS_MASK];
......@@ -243,7 +239,7 @@ static void test_key_cache(const char *where, my_bool lock);
/*
** read a key_buffer
** filepos must point at a even KEYCACHE_BLOCK_SIZE block
** filepos must point at a even key_cache_block_size block
** if return_buffer is set then the intern buffer is returned if
** it can be used
** Returns adress to where data is read
......@@ -257,7 +253,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
int error=0;
#ifndef THREAD
if (block_length > KEYCACHE_BLOCK_SIZE)
if (block_length > key_cache_block_size)
return_buffer=0;
#endif
if (_my_disk_blocks > 0)
......@@ -268,7 +264,8 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
do
{
_my_cache_r_requests++;
read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
read_length= (length > key_cache_block_size ? key_cache_block_size :
length);
if (!(next=find_key_block(file,filepos,&error)))
{
pthread_mutex_unlock(&THR_LOCK_keycache);
......@@ -310,7 +307,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
/* write a key_buffer */
/* We don't have to use pwrite because of write locking */
/* buff must point at a even KEYCACHE_BLOCK_SIZE block */
/* buff must point at a even key_cache_block_size block */
int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
uint block_length __attribute__((unused)),
......@@ -336,7 +333,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
_my_cache_w_requests++;
do
{
read_length= length > KEYCACHE_BLOCK_SIZE ? KEYCACHE_BLOCK_SIZE : length;
read_length= length > key_cache_block_size ? key_cache_block_size : length;
if (!(next=find_key_block(file,filepos,&error)))
goto end; /* Fatal error */
if (!dont_write) /* If we wrote buff at start */
......@@ -385,7 +382,7 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
#endif
*error=0;
next= *(start= &_my_hash_root[((ulong) (filepos/KEYCACHE_BLOCK_SIZE)+(ulong) file) &
next= *(start= &_my_hash_root[((ulong) (filepos >> key_cache_shift)+(ulong) file) &
(_my_hash_blocks-1)]);
while (next && (next->diskpos != filepos || next->file != file))
next= next->next_hash;
......@@ -411,7 +408,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
{ /* There are unused blocks */
next= &_my_block_root[_my_blocks_used++]; /* Link in hash-chain */
next->buffer=ADD_TO_PTR(_my_block_mem,
(ulong) _my_disk_blocks_used*KEYCACHE_BLOCK_SIZE,byte*);
((ulong) _my_disk_blocks_used << key_cache_shift),
byte*);
/* link first in file_blocks */
next->changed=0;
link_into_file_blocks(next,file);
......@@ -426,7 +424,8 @@ static SEC_LINK *find_key_block(int file, my_off_t filepos, int *error)
next= _my_used_first;
if (next->changed)
{
if (my_pwrite(next->file,next->buffer,KEYCACHE_BLOCK_SIZE,next->diskpos,
if (my_pwrite(next->file,next->buffer,key_cache_block_size,
next->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
*error=1;
......@@ -505,7 +504,8 @@ static int flush_cached_blocks(File file, SEC_LINK **cache, uint count)
qsort((byte*) cache, count, sizeof(*cache), (qsort_cmp) cmp_sec_link);
for ( ; count-- ; cache++)
{
if (my_pwrite(file,(*cache)->buffer,KEYCACHE_BLOCK_SIZE,(*cache)->diskpos,
if (my_pwrite(file,(*cache)->buffer,key_cache_block_size,
(*cache)->diskpos,
MYF(MY_NABP | MY_WAIT_IF_FULL)))
{
if (!last_errno)
......@@ -646,7 +646,7 @@ static void test_key_cache(const char *where, my_bool lock)
i,(ulong) pos,(ulong) prev,(ulong) pos->prev_hash));
}
if (((pos->diskpos/KEYCACHE_BLOCK_SIZE)+pos->file) % _my_hash_blocks != i)
if (((pos->diskpos >> key_cache_shift)+pos->file) % _my_hash_blocks != i)
{
DBUG_PRINT("error",("hash: %d pos: %lx : Wrong disk_buffer %ld",
i,(ulong) pos,(ulong) pos->diskpos));
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/* Some useful bit functions */
#include "mysys_priv.h"
/*
Find smallest X in 2^X >= value
This can be used to divide a number with value by doing a shift instead
*/
uint my_bit_log2(ulong value)
{
uint bit;
for (bit=0 ; value > 1 ; value>>=1, bit++) ;
return bit;
}
......@@ -45,9 +45,8 @@ static my_bool win32_init_tcp_ip();
#else
#define my_win_init()
#endif
static my_bool my_init_done=0;
my_bool my_init_done=0;
static ulong atoi_octal(const char *str)
{
......
......@@ -56,6 +56,13 @@ END_OF_DATA
echo ""
fi
echo "Adding columns needed by GRANT .. REQUIRE (openssl)"
echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
ALTER TABLE user ADD ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL, ADD ssl_cipher BLOB NOT NULL, ADD x509_issuer BLOB NOT NULL, ADD x509_subject BLOB NOT NULL
END_OF_DATA
echo ""
#
# Create tables_priv and columns_priv if they don't exists
#
......@@ -96,6 +103,7 @@ echo "You can ignore any errors from this"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
END_OF_DATA
echo ""
#
# Add the new 'type' column to the func table.
......@@ -107,3 +115,14 @@ echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password=$root_password mysql <<EOF
alter table func add type enum ('function','aggregate') NOT NULL;
EOF
echo ""
echo "Converting all privilege tables to MyISAM format"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA
ALTER TABLE user type=MyISAM;
ALTER TABLE db type=MyISAM;
ALTER TABLE host type=MyISAM;
ALTER TABLE func type=MyISAM;
ALTER TABLE columns_priv type=MyISAM;
ALTER TABLE tables_priv type=MyISAM;
END_OF_DATA
......@@ -225,9 +225,9 @@ then
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
c_u="$c_u ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL,"
c_u="$c_u ssl_cipher BLOB NULL,"
c_u="$c_u x509_issuer BLOB NULL,"
c_u="$c_u x509_subject BLOB NULL,"
c_u="$c_u ssl_cipher BLOB NOT NULL,"
c_u="$c_u x509_issuer BLOB NOT NULL,"
c_u="$c_u x509_subject BLOB NOT NULL,"
c_u="$c_u PRIMARY KEY Host (Host,User)"
c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';"
......
......@@ -72,8 +72,7 @@ static void read_texts(const char *file_name,const char ***point,
Check that the above file is the right version for this program!\n\n",
my_progname,name,ant,error_messages);
VOID(my_close(file,MYF(MY_WME)));
clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */
unireg_abort(1);
}
x_free((gptr) *point); /* Free old language */
......@@ -115,8 +114,7 @@ err:
if (file != FERR)
VOID(my_close(file,MYF(MY_WME)));
fprintf(stderr,buff,my_progname,name);
clean_up(0); /* Clean_up frees everything */
exit(1); /* We can't continue */
unireg_abort(1);
} /* read_texts */
......
......@@ -1197,13 +1197,19 @@ longlong Item_cond_or::val_int()
longlong Item_func_isnull::val_int()
{
(void) args[0]->val();
if (internal_result_type == REAL_RESULT)
(void) args[0]->val();
else
(void) args[0]->val_int();
return (args[0]->null_value) ? 1 : 0;
}
longlong Item_func_isnotnull::val_int()
{
(void) args[0]->val();
if (internal_result_type == REAL_RESULT)
(void) args[0]->val();
else
(void) args[0]->val_int();
return !(args[0]->null_value) ? 1 : 0;
}
......
......@@ -429,6 +429,7 @@ class Item_func_in :public Item_int_func
class Item_func_isnull :public Item_bool_func
{
enum Item_result internal_result_type;
public:
Item_func_isnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
......@@ -437,6 +438,7 @@ public:
{
decimals=0; max_length=1; maybe_null=0;
Item_func_isnull::update_used_tables();
internal_result_type=args[0]->result_type();
}
const char *func_name() const { return "isnull"; }
/* Optimize case of not_null_column IS NULL */
......@@ -455,11 +457,16 @@ public:
class Item_func_isnotnull :public Item_bool_func
{
enum Item_result internal_result_type;
public:
Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
enum Functype functype() const { return ISNOTNULL_FUNC; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
void fix_length_and_dec()
{
decimals=0; max_length=1; maybe_null=0;
internal_result_type=args[0]->result_type();
}
const char *func_name() const { return "isnotnull"; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
};
......
......@@ -506,7 +506,7 @@ void sql_print_error(const char *format,...)
__attribute__ ((format (printf, 1, 2)));
extern uint32 server_id;
extern char mysql_data_home[2],server_version[SERVER_VERSION_LENGTH],
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
max_sort_char, mysql_real_data_home[];
extern my_string mysql_unix_port,mysql_tmpdir;
extern const char *first_keyword, *localhost, *delayed_user;
......
......@@ -214,8 +214,9 @@ SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES;
static bool opt_skip_slave_start = 0; // if set, slave is not autostarted
static bool opt_do_pstack = 0;
static ulong opt_specialflag=SPECIAL_ENGLISH;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
static ulong back_log,connect_timeout,concurrency;
static ulong opt_myisam_block_size;
static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0;
static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
......@@ -310,10 +311,16 @@ ulong slow_launch_threads = 0;
ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size;
char mysql_real_data_home[FN_REFLEN],
mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN],
language[LIBLEN],reg_ext[FN_EXTLEN],
default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
*opt_init_file;
#ifndef EMBEDDED_LIBRARY
char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff;
#else
char *mysql_data_home=mysql_real_data_home;
#endif
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first";
......@@ -677,9 +684,8 @@ static sig_handler print_signal_warning(int sig)
void unireg_end(int signal_number __attribute__((unused)))
{
clean_up();
#ifndef EMBEDDED_LIBRARY
my_thread_end();
pthread_exit(0); // Exit is in main thread
#endif
}
......@@ -688,6 +694,7 @@ void unireg_abort(int exit_code)
if (exit_code)
sql_print_error("Aborting\n");
clean_up(); /* purecov: inspected */
my_thread_end();
exit(exit_code); /* purecov: inspected */
}
......@@ -730,14 +737,13 @@ void clean_up(bool print_message)
free_max_user_conn();
end_slave_list();
#ifndef __WIN__
#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
if (print_message)
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
my_thread_end();
/* Tell main we are ready */
(void) pthread_mutex_lock(&LOCK_thread_count);
......@@ -1782,10 +1788,6 @@ int main(int argc, char **argv)
init_thr_lock();
init_slave_list();
/* Fix varibles that are base 1024*1024 */
myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
/* Setup log files */
if (opt_log)
open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL);
......@@ -1796,17 +1798,18 @@ int main(int argc, char **argv)
using_update_log=1;
}
//make sure slave thread gets started
// if server_id is set, valid master.info is present, and master_host has
// not been specified
if(server_id && !master_host)
{
char fname[FN_REFLEN+128];
MY_STAT stat_area;
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi))
master_host = glob_mi.host;
}
/*
make sure slave thread gets started if server_id is set,
valid master.info is present, and master_host has not been specified
*/
if (server_id && !master_host)
{
char fname[FN_REFLEN+128];
MY_STAT stat_area;
fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32);
if (my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi))
master_host = glob_mi.host;
}
if (opt_bin_log && !server_id)
{
......@@ -2882,6 +2885,9 @@ CHANGEABLE_VAR changeable_vars[] = {
~0L, 1, ~0L, 0, 1 },
{ "myisam_bulk_insert_tree_size", (long*) &myisam_bulk_insert_tree_size,
8192*1024, 4, ~0L, 0, 1 },
{ "myisam_block_size", (long*) &opt_myisam_block_size,
MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
0, MI_MIN_KEY_BLOCK_LENGTH },
{ "myisam_max_extra_sort_file_size",
(long*) &myisam_max_extra_sort_file_size,
(long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 },
......@@ -4025,6 +4031,12 @@ static void get_options(int argc,char **argv)
/* To be deleted in MySQL 4.0 */
if (!record_rnd_cache_size)
record_rnd_cache_size=my_default_record_cache_size;
/* Fix variables that are base 1024*1024 */
myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE);
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
}
......
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