diff options
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/charset.c | 4 | ||||
-rw-r--r-- | mysys/default.c | 6 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 84 | ||||
-rw-r--r-- | mysys/mf_soundex.c | 4 | ||||
-rw-r--r-- | mysys/my_getopt.c | 30 | ||||
-rw-r--r-- | mysys/my_getsystime.c | 27 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 3 |
7 files changed, 122 insertions, 36 deletions
diff --git a/mysys/charset.c b/mysys/charset.c index 80f62b06a3e..e58c851cf7c 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -97,7 +97,7 @@ static void init_state_maps(CHARSET_INFO *cs) state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP; state_map[(uchar)'&']=state_map[(uchar)'|']=(uchar) MY_LEX_BOOL; state_map[(uchar)'#']=(uchar) MY_LEX_COMMENT; - state_map[(uchar)';']=(uchar) MY_LEX_COLON; + state_map[(uchar)';']=(uchar) MY_LEX_SEMICOLON; state_map[(uchar)':']=(uchar) MY_LEX_SET_VAR; state_map[0]=(uchar) MY_LEX_EOL; state_map[(uchar)'\\']= (uchar) MY_LEX_ESCAPE; @@ -373,7 +373,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) uint len; MY_STAT stat_info; - if (!my_stat(filename, &stat_info, MYF(MY_WME)) || + if (!my_stat(filename, &stat_info, MYF(myflags)) || ((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) || !(buf= (char *)my_malloc(len,myflags))) return TRUE; diff --git a/mysys/default.c b/mysys/default.c index d09b0dd97af..af67520322f 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -166,6 +166,12 @@ int load_defaults(const char *conf_file, const char **groups, if ((error= search_default_file(&args, &alloc, "", forced_default_file, "", &group)) < 0) goto err; + if (error > 0) + { + fprintf(stderr, "Could not open required defaults file: %s\n", + forced_default_file); + goto err; + } } else if (dirname_length(conf_file)) { diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 689391537f8..168483f276b 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -20,6 +20,23 @@ One cache can handle many files. It must contain buffers of the same blocksize. init_key_cache() should be used to init cache handler. + + The free list (free_block_list) is a stack like structure. + When a block is freed by free_block(), it is pushed onto the stack. + When a new block is required it is first tried to pop one from the stack. + If the stack is empty, it is tried to get a never-used block from the pool. + If this is empty too, then a block is taken from the LRU ring, flushing it + to disk, if neccessary. This is handled in find_key_block(). + With the new free list, the blocks can have three temperatures: + hot, warm and cold (which is free). This is remembered in the block header + by the enum BLOCK_TEMPERATURE temperature variable. Remembering the + temperature is neccessary to correctly count the number of warm blocks, + which is required to decide when blocks are allowed to become hot. Whenever + a block is inserted to another (sub-)chain, we take the old and new + temperature into account to decide if we got one more or less warm block. + blocks_unused is the sum of never used blocks in the pool and of currently + free blocks. blocks_used is the number of blocks fetched from the pool and + as such gives the maximum number of in-use blocks at any time. */ #include "mysys_priv.h" @@ -116,6 +133,9 @@ struct st_hash_link #define PAGE_TO_BE_READ 1 #define PAGE_WAIT_TO_BE_READ 2 +/* block temperature determines in which (sub-)chain the block currently is */ +enum BLOCK_TEMPERATURE { BLOCK_COLD /*free*/ , BLOCK_WARM , BLOCK_HOT }; + /* key cache block */ struct st_block_link { @@ -130,6 +150,7 @@ struct st_block_link uint offset; /* beginning of modified data in the buffer */ uint length; /* end of data in the buffer */ uint status; /* state of the block */ + enum BLOCK_TEMPERATURE temperature; /* block temperature: cold, warm, hot */ uint hits_left; /* number of hits left until promotion */ ulonglong last_hit_time; /* timestamp of the last hit */ KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */ @@ -340,6 +361,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, } blocks= blocks / 4*3; } + keycache->blocks_unused= (ulong) blocks; keycache->disk_blocks= (int) blocks; keycache->hash_links= hash_links; keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root + @@ -357,12 +379,13 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache->free_hash_list= NULL; keycache->blocks_used= keycache->blocks_changed= 0; - keycache->global_blocks_used= keycache->global_blocks_changed= 0; + keycache->global_blocks_changed= 0; keycache->blocks_available=0; /* For debugging */ /* The LRU chain is empty after initialization */ keycache->used_last= NULL; keycache->used_ins= NULL; + keycache->free_block_list= NULL; keycache->keycache_time= 0; keycache->warm_blocks= 0; keycache->min_warm_blocks= (division_limit ? @@ -596,7 +619,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) DBUG_PRINT("status", ("used: %d changed: %d w_requests: %ld \ writes: %ld r_requests: %ld reads: %ld", - keycache->global_blocks_used, keycache->global_blocks_changed, + keycache->blocks_used, keycache->global_blocks_changed, keycache->global_cache_w_requests, keycache->global_cache_write, keycache->global_cache_r_requests, keycache->global_cache_read)); @@ -1014,7 +1037,9 @@ static inline void unreg_request(KEY_CACHE *keycache, keycache->warm_blocks > keycache->min_warm_blocks; if (hot) { - keycache->warm_blocks--; + if (block->temperature == BLOCK_WARM) + keycache->warm_blocks--; + block->temperature= BLOCK_HOT; KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks=%u", keycache->warm_blocks)); } @@ -1026,7 +1051,11 @@ static inline void unreg_request(KEY_CACHE *keycache, block= keycache->used_ins; unlink_block(keycache, block); link_block(keycache, block, 0, 0); - keycache->warm_blocks++; + if (block->temperature != BLOCK_WARM) + { + keycache->warm_blocks++; + block->temperature= BLOCK_WARM; + } KEYCACHE_DBUG_PRINT("unreg_request", ("#warm_blocks=%u", keycache->warm_blocks)); } @@ -1363,28 +1392,40 @@ restart: if (! block) { /* No block is assigned for the page yet */ - if (keycache->blocks_used < (uint) keycache->disk_blocks) + if (keycache->blocks_unused) { - /* There are some never used blocks, take first of them */ - hash_link->block= block= &keycache->block_root[keycache->blocks_used]; - block->buffer= ADD_TO_PTR(keycache->block_mem, - ((ulong) keycache->blocks_used* - keycache->key_cache_block_size), - byte*); + if (keycache->free_block_list) + { + /* There is a block in the free list. */ + block= keycache->free_block_list; + keycache->free_block_list= block->next_used; + block->next_used= NULL; + } + else + { + /* There are some never used blocks, take first of them */ + block= &keycache->block_root[keycache->blocks_used]; + block->buffer= ADD_TO_PTR(keycache->block_mem, + ((ulong) keycache->blocks_used* + keycache->key_cache_block_size), + byte*); + keycache->blocks_used++; + } + keycache->blocks_unused--; block->status= 0; block->length= 0; block->offset= keycache->key_cache_block_size; block->requests= 1; - keycache->blocks_used++; - keycache->global_blocks_used++; - keycache->warm_blocks++; + block->temperature= BLOCK_COLD; block->hits_left= init_hits_left; block->last_hit_time= 0; link_to_file_list(keycache, block, file, 0); block->hash_link= hash_link; + hash_link->block= block; page_status= PAGE_TO_BE_READ; KEYCACHE_DBUG_PRINT("find_key_block", - ("got never used block %u", BLOCK_NUMBER(block))); + ("got free or never used block %u", + BLOCK_NUMBER(block))); } else { @@ -2021,7 +2062,7 @@ end: /* Free block: remove reference to it from hash table, remove it from the chain file of dirty/clean blocks - and add it at the beginning of the LRU chain + and add it to the free list. */ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) @@ -2045,6 +2086,17 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block) ("block is freed")); unreg_request(keycache, block, 0); block->hash_link= NULL; + + /* Remove the free block from the LRU ring. */ + unlink_block(keycache, block); + if (block->temperature == BLOCK_WARM) + keycache->warm_blocks--; + block->temperature= BLOCK_COLD; + /* Insert the free block in the free list. */ + block->next_used= keycache->free_block_list; + keycache->free_block_list= block; + /* Keep track of the number of currently unused blocks. */ + keycache->blocks_unused++; } diff --git a/mysys/mf_soundex.c b/mysys/mf_soundex.c index 75d9270c5af..27ab4892c57 100644 --- a/mysys/mf_soundex.c +++ b/mysys/mf_soundex.c @@ -52,7 +52,7 @@ void soundex(CHARSET_INFO * cs,register my_string out_pntr, my_string in_pntr, if (remove_garbage) { - while (*in_pntr && my_isspace(cs,*in_pntr)) /* Skipp pre-space */ + while (*in_pntr && !my_isalpha(cs,*in_pntr)) /* Skipp pre-space */ in_pntr++; } *out_pntr++ = map[(uchar)*in_pntr]; /* Copy first letter */ @@ -98,7 +98,7 @@ static char get_scode(CHARSET_INFO * cs,char **ptr, pbool remove_garbage) ch=my_toupper(cs,**ptr); if (ch < 'A' || ch > 'Z') { - if (my_isalpha(cs,ch)) /* If exetended alfa (country spec) */ + if (my_isalpha(cs,ch)) /* If extended alfa (country spec) */ return '0'; /* threat as vokal */ return 0; /* Can't map */ } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 8a1f6db6f8a..efd5789968c 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -342,8 +342,8 @@ int handle_options(int *argc, char ***argv, { if (!optend) /* No argument -> enable option */ *((my_bool*) value)= (my_bool) 1; - else /* If argument differs from 0, enable option, else disable */ - *((my_bool*) value)= (my_bool) atoi(optend) != 0; + else + argument= optend; } } else if (optp->arg_type == REQUIRED_ARG && !optend) @@ -398,18 +398,25 @@ int handle_options(int *argc, char ***argv, /* This is in effect a jump out of the outer loop */ optend= (char*) " "; } - else if (optp->arg_type == REQUIRED_ARG) + else { + if (optp->arg_type == OPT_ARG) + { + if (optp->var_type == GET_BOOL) + *((my_bool*) optp->value)= (my_bool) 1; + get_one_option(optp->id, optp, argument); + continue; + } /* Check if there are more arguments after this one */ - if (!*++pos) + if (!pos[1]) { - if (my_getopt_print_errors) - fprintf(stderr, - "%s: option '-%c' requires an argument\n", - my_progname, optp->id); - return EXIT_ARGUMENT_REQUIRED; + if (my_getopt_print_errors) + fprintf(stderr, + "%s: option '-%c' requires an argument\n", + my_progname, optp->id); + return EXIT_ARGUMENT_REQUIRED; } - argument= *pos; + argument= *++pos; (*argc)--; /* the other loop will break, because *optend + 1 == 0 */ } @@ -525,6 +532,9 @@ static int setval(const struct my_option *opts, gptr *value, char *argument, return EXIT_NO_PTR_TO_VARIABLE; switch ((opts->var_type & GET_TYPE_MASK)) { + case GET_BOOL: /* If argument differs from 0, enable option, else disable */ + *((my_bool*) result_pos)= (my_bool) atoi(argument) != 0; + break; case GET_INT: case GET_UINT: /* fall through */ *((int*) result_pos)= (int) getopt_ll(argument, opts, &err); diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index bdaa232d560..91c977f0b5a 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -30,11 +30,28 @@ ulonglong my_getsystime() clock_gettime(CLOCK_REALTIME, &tp); return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100; #elif defined(__WIN__) - /* TODO: use GetSystemTimeAsFileTime here or - QueryPerformanceCounter/QueryPerformanceFrequency */ - struct _timeb tb; - _ftime(&tb); - return (ulonglong)tb.time*10000000+(ulonglong)tb.millitm*10000; +#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10) + static __int64 offset=0, freq; + LARGE_INTEGER t_cnt; + if (!offset) + { + /* strictly speaking there should be a mutex to protect + initialization section. But my_getsystime() is called from + UUID() code, and UUID() calls are serialized with a mutex anyway + */ + LARGE_INTEGER li; + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + li.LowPart=ft.dwLowDateTime; + li.HighPart=ft.dwHighDateTime; + offset=li.QuadPart-OFFSET_TO_EPOC; + QueryPerformanceFrequency(&li); + freq=li.QuadPart; + QueryPerformanceCounter(&t_cnt); + offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq; + } + QueryPerformanceCounter(&t_cnt); + return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset; #elif defined(__NETWARE__) NXTime_t tm; NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 445cef0cd6f..0ce59bee346 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -203,7 +203,8 @@ void my_thread_end(void) tmp->dbug=0; } #endif -#if !defined(__bsdi__) || defined(HAVE_mit_thread) /* bsdi dumps core here */ +#if !defined(__bsdi__) && !defined(__OpenBSD__) || defined(HAVE_mit_thread) + /* bsdi and openbsd 3.5 dumps core here */ pthread_cond_destroy(&tmp->suspend); #endif pthread_mutex_destroy(&tmp->mutex); |