diff options
author | sasha@mysql.sashanet.com <> | 2000-11-15 18:58:59 -0700 |
---|---|---|
committer | sasha@mysql.sashanet.com <> | 2000-11-15 18:58:59 -0700 |
commit | eb0a423e0ea8cefa04719226923755aa4bb8a961 (patch) | |
tree | d78befdf5251596d35567b37ed5edb3edae3f8bd /mysys | |
parent | 5faab668f7996ae58f645a2b563f5c290d37b76c (diff) | |
parent | a9097ca323bf399c5fc45d94a9b121c304f7681e (diff) | |
download | mariadb-git-eb0a423e0ea8cefa04719226923755aa4bb8a961.tar.gz |
merged
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/Makefile.am | 4 | ||||
-rw-r--r-- | mysys/hash.c | 3 | ||||
-rw-r--r-- | mysys/mf_cache.c | 8 | ||||
-rw-r--r-- | mysys/mf_iocache.c | 43 | ||||
-rw-r--r-- | mysys/mf_iocache2.c | 212 | ||||
-rw-r--r-- | mysys/my_vsnprintf.c | 91 |
6 files changed, 281 insertions, 80 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 6b38d9364f6..9e9b4f8d9ed 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -26,8 +26,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ mf_path.c mf_loadpath.c\ my_open.c my_create.c my_seek.c my_read.c \ my_pread.c my_write.c \ - mf_reccache.c mf_keycache.c \ - mf_iocache.c mf_cache.c mf_tempfile.c \ + mf_keycache.c \ + mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \ my_lock.c mf_brkhant.c my_alarm.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_alloc.c safemalloc.c my_fopen.c my_fstream.c \ diff --git a/mysys/hash.c b/mysys/hash.c index a6181443a42..9c6497c7717 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -374,10 +374,11 @@ my_bool hash_delete(HASH *hash,byte *record) uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index; HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; DBUG_ENTER("hash_delete"); + if (!hash->records) + DBUG_RETURN(1); blength=hash->blength; data=dynamic_element(&hash->array,0,HASH_LINK*); - /* Search after record with key */ pos=data+ hash_mask(rec_hashnr(hash,record),blength,hash->records); gpos = 0; diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c index 2c197f6fd20..ff29926ac50 100644 --- a/mysys/mf_cache.c +++ b/mysys/mf_cache.c @@ -74,7 +74,7 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix, } my_free(cache->dir, MYF(MY_ALLOW_ZERO_PTR)); my_free(cache->prefix,MYF(MY_ALLOW_ZERO_PTR)); - DBUG_RETURN(0); + DBUG_RETURN(1); } /* Create the temporary file */ @@ -101,10 +101,12 @@ void close_cached_file(IO_CACHE *cache) DBUG_ENTER("close_cached_file"); if (my_b_inited(cache)) { + File file=cache->file; + cache->file= -1; /* Don't flush data */ (void) end_io_cache(cache); - if (cache->file >= 0) + if (file >= 0) { - (void) my_close(cache->file,MYF(0)); + (void) my_close(file,MYF(0)); #ifdef CANT_DELETE_OPEN_FILES if (cache->file_name) { diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 86cf5fc65e2..0d1c227c2b2 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -22,10 +22,13 @@ (and get a EOF-error). Possibly use of asyncronic io. macros for read and writes for faster io. - Used instead of FILE when reading or writing hole files. - This shall make mf_rec_cache obsolite. - One can change info->pos_in_file to a higer value to skipp bytes in file if + Used instead of FILE when reading or writing whole files. + This will make mf_rec_cache obsolete. + One can change info->pos_in_file to a higher value to skip bytes in file if also info->rc_pos is set to info->rc_end. + If called through open_cached_file(), then the temporary file will + only be created if a write exeeds the file buffer or if one calls + flush_io_cache(). */ #define MAP_TO_USE_RAID @@ -40,7 +43,7 @@ static void my_aiowait(my_aio_result *result); /* ** if cachesize == 0 then use default cachesize (from s-file) - ** if file == -1 then real_open_cached_file() will be called to + ** if file == -1 then real_open_cached_file() will be called. ** returns 0 if ok */ @@ -59,17 +62,24 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2; if (type == READ_CACHE) { /* Assume file isn't growing */ - my_off_t file_pos,end_of_file; - if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR)) - DBUG_RETURN(1); - end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0)); - if (end_of_file < seek_offset) - end_of_file=seek_offset; - VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0))); - if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1) + if (cache_myflags & MY_DONT_CHECK_FILESIZE) { - cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; - use_async_io=0; /* No nead to use async */ + cache_myflags &= ~MY_DONT_CHECK_FILESIZE; + } + else + { + my_off_t file_pos,end_of_file; + if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR)) + DBUG_RETURN(1); + end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0)); + if (end_of_file < seek_offset) + end_of_file=seek_offset; + VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0))); + if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1) + { + cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; + use_async_io=0; /* No nead to use async */ + } } } @@ -545,7 +555,6 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count, return error; } - /* Flush write cache */ int flush_io_cache(IO_CACHE *info) @@ -565,7 +574,9 @@ int flush_io_cache(IO_CACHE *info) length=(uint) (info->rc_pos - info->buffer); if (info->seek_not_done) { /* File touched, do seek */ - VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))); + if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) == + MY_FILEPOS_ERROR) + DBUG_RETURN((info->error= -1)); info->seek_not_done=0; } info->rc_pos=info->buffer; diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c new file mode 100644 index 00000000000..80cea47a80f --- /dev/null +++ b/mysys/mf_iocache2.c @@ -0,0 +1,212 @@ +/* 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 */ + +/* + More functions to be used with IO_CACHE files +*/ + +#define MAP_TO_USE_RAID +#include "mysys_priv.h" +#include <m_string.h> +#include <stdarg.h> +#include <m_ctype.h> + +/* +** Fix that next read will be made at certain position +** This only works with READ_CACHE +*/ + +void my_b_seek(IO_CACHE *info,my_off_t pos) +{ + info->seek_not_done=0; + info->pos_in_file=pos; + info->rc_pos=info->rc_end=info->buffer; +} + +/* +** Fill buffer +** return: 0 on error or EOF (info->error = -1 on error) +** number of characters +*/ + +uint my_b_fill(IO_CACHE *info) +{ + my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer); + my_off_t max_length; + uint diff_length,length; + if (info->seek_not_done) + { /* File touched, do seek */ + if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == + MY_FILEPOS_ERROR) + { + info->error= 0; + return 0; + } + info->seek_not_done=0; + } + diff_length=(uint) (pos_in_file & (IO_SIZE-1)); + max_length= (my_off_t) (info->end_of_file - pos_in_file); + if (max_length > (my_off_t) (info->read_length-diff_length)) + max_length=(my_off_t) (info->read_length-diff_length); + if (!max_length) + { + info->error= 0; + return 0; /* EOF */ + } + else if ((length=my_read(info->file,info->buffer,(uint) max_length, + info->myflags)) == (uint) -1) + { + info->error= -1; + return 0; + } + info->rc_pos=info->buffer; + info->rc_end=info->buffer+length; + info->pos_in_file=pos_in_file; + return length; +} + +/* +** Read a string ended by '\n' into a buffer of 'max_length' size. +** Returns number of characters read, 0 on error. +** last byte is set to '\0' +*/ + +uint my_b_gets(IO_CACHE *info, char *to, uint max_length) +{ + uint length; + max_length--; /* Save place for end \0 */ + /* Calculate number of characters in buffer */ + if (!(length= (uint) (info->rc_end - info->rc_pos))) + if (!(length=my_b_fill(info))) + return 0; + for (;;) + { + char *pos,*end; + if (length > max_length) + length=max_length; + for (pos=info->rc_pos,end=pos+length ; pos < end ;) + { + if ((*to++ = *pos++) == '\n') + { + length= (uint) (pos-info->rc_pos); + info->rc_pos=pos; + *to='\0'; + return length; + } + } + if (!(max_length-=length)) + { + /* Found enough charcters; Return found string */ + info->rc_pos=pos; + *to='\0'; + return length; + } + if (!(length=my_b_fill(info))) + return 0; + } +} + +/* + Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu" + Used for logging in MySQL + returns number of written character, or (uint) -1 on error +*/ + +uint my_b_printf(IO_CACHE *info, const char* fmt, ...) +{ + va_list args; + reg1 char *to= info->rc_pos; + char *end=info->rc_end; + uint out_length=0; + + va_start(args,fmt); + + for (; *fmt ; fmt++) + { + if (fmt[0] != '%') + { + /* Copy everything until '%' or end of string */ + const char *start=fmt; + uint length; + for (fmt++ ; *fmt && *fmt != '%' ; fmt++ ) ; + length= (uint) (fmt - start); + out_length+=length; + if (my_b_write(info, start, length)) + goto err; + if (!*fmt) /* End of format */ + { + va_end(args); + return out_length; + } + /* Found one '%' */ + } + /* Skipp if max size is used (to be compatible with printf) */ + while (isdigit(*fmt) || *fmt == '.' || *fmt == '-') + fmt++; + if (*fmt == 's') /* String parameter */ + { + reg2 char *par = va_arg(args, char *); + uint length = (uint) strlen(par); + out_length+=length; + if (my_b_write(info, par, length)) + goto err; + } + else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ + { + register int iarg; + uint length; + char buff[17]; + + iarg = va_arg(args, int); + if (*fmt == 'd') + length= (uint) (int10_to_str((long) iarg,buff, -10) - buff); + else + length= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff); + out_length+=length; + if (my_b_write(info, buff, length)) + goto err; + } + else if (*fmt == 'l' && fmt[1] == 'd' || fmt[1] == 'u')/* long parameter */ + { + register long iarg; + uint length; + char buff[17]; + + iarg = va_arg(args, long); + if (*++fmt == 'd') + length= (uint) (int10_to_str(iarg,buff, -10) - buff); + else + length= (uint) (int10_to_str(iarg,buff,10)- buff); + out_length+=length; + if (my_b_write(info, buff, length)) + goto err; + } + else + { + /* %% or unknown code */ + if (my_b_write(info, "%", 1)) + goto err; + out_length++; + } + } + va_end(args); + return out_length; + +err: + return (uint) -1; + va_end(args); +} diff --git a/mysys/my_vsnprintf.c b/mysys/my_vsnprintf.c index 63730926156..b394adf2a96 100644 --- a/mysys/my_vsnprintf.c +++ b/mysys/my_vsnprintf.c @@ -21,74 +21,49 @@ #include <stdarg.h> #include <m_ctype.h> - - -int my_vsnprintf(char* str, size_t n, const char* fmt, va_list ap) +int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { - uint olen = 0, plen; - const char *tpos; - reg1 char *endpos; - reg2 char * par; - char* ebuff = str; - - endpos=ebuff; - tpos = fmt; + char *start=to, *end=to+n-1; - while (*tpos) + for (; *fmt ; fmt++) { - if (tpos[0] != '%') + if (fmt[0] != '%') { - if(olen + 1 >= n) + if (to == end) /* End of buffer */ break; - - *endpos++= *tpos++; /* Copy ordinary char */ - olen++; + *to++= *fmt; /* Copy ordinary char */ continue; } - if (*++tpos == '%') /* test if %% */ - { - olen--; - } - else + /* Skipp if max size is used (to be compatible with printf) */ + while (isdigit(*fmt) || *fmt == '.' || *fmt == '-') + fmt++; + if (*fmt == 's') /* String parameter */ { - /* Skipp if max size is used (to be compatible with printf) */ - while (isdigit(*tpos) || *tpos == '.' || *tpos == '-') - tpos++; - if (*tpos == 's') /* String parameter */ - { - par = va_arg(ap, char *); - plen = (uint) strlen(par); - if (olen + plen < n) /* Replace if possible */ - { - endpos=strmov(endpos,par); - tpos++; - olen+=plen; - continue; - } - } - else if (*tpos == 'd' || *tpos == 'u') /* Integer parameter */ + reg2 char *par = va_arg(ap, char *); + uint plen = (uint) strlen(par); + if ((uint) (end-to) > plen) /* Replace if possible */ { - register int iarg; - iarg = va_arg(ap, int); - if(olen + 16 >= n) break; - - if (*tpos == 'd') - plen= (uint) (int2str((long) iarg,endpos, -10) - endpos); - else - plen= (uint) (int2str((long) (uint) iarg,endpos,10)- endpos); - if (olen + plen < n) /* Replace parameter if possible */ - { - endpos+=plen; - tpos++; - olen+=plen; - continue; - } + to=strmov(to,par); + continue; } } - *endpos++='%'; /* % used as % or unknown code */ + else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */ + { + register int iarg; + if ((uint) (end-to) < 16) + break; + iarg = va_arg(ap, int); + if (*fmt == 'd') + to=int10_to_str((long) iarg,to, -10); + else + to=int10_to_str((long) (uint) iarg,to,10); + continue; + } + /* We come here on '%%', unknown code or too long parameter */ + if (to == end) + break; + *to++='%'; /* % used as % or unknown code */ } - *endpos='\0'; - /* End of errmessage */ - return olen; + *to='\0'; /* End of errmessage */ + return (uint) (to - start); } - |