summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
authorsasha@mysql.sashanet.com <>2000-11-15 18:58:59 -0700
committersasha@mysql.sashanet.com <>2000-11-15 18:58:59 -0700
commiteb0a423e0ea8cefa04719226923755aa4bb8a961 (patch)
treed78befdf5251596d35567b37ed5edb3edae3f8bd /mysys
parent5faab668f7996ae58f645a2b563f5c290d37b76c (diff)
parenta9097ca323bf399c5fc45d94a9b121c304f7681e (diff)
downloadmariadb-git-eb0a423e0ea8cefa04719226923755aa4bb8a961.tar.gz
merged
Diffstat (limited to 'mysys')
-rw-r--r--mysys/Makefile.am4
-rw-r--r--mysys/hash.c3
-rw-r--r--mysys/mf_cache.c8
-rw-r--r--mysys/mf_iocache.c43
-rw-r--r--mysys/mf_iocache2.c212
-rw-r--r--mysys/my_vsnprintf.c91
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);
}
-