53 #include <drizzled/error_t.h>
54 #include <drizzled/error.h>
55 #include <drizzled/internal/my_sys.h>
56 #include <drizzled/internal/m_string.h>
57 #include <drizzled/drizzled.h>
58 #include <drizzled/internal/iocache.h>
60 #include <drizzled/util/test.h>
69 static int _my_b_read(io_cache_st *info,
unsigned char *Buffer,
size_t Count);
70 static int _my_b_write(io_cache_st *info,
const unsigned char *Buffer,
size_t Count);
77 static void lock_append_buffer(io_cache_st *,
int )
86 static void unlock_append_buffer(io_cache_st *,
int )
95 static size_t io_round_up(
size_t x)
97 return ((x+IO_SIZE-1) & ~(IO_SIZE-1));
105 static size_t io_round_dn(
size_t x)
107 return (x & ~(IO_SIZE-1));
121 void io_cache_st::setup_io_cache()
124 if (type == WRITE_CACHE)
126 current_pos= &write_pos;
127 current_end= &write_end;
131 current_pos= &read_pos;
132 current_end= &read_end;
137 void io_cache_st::init_functions()
150 read_function = _my_b_read;
151 write_function = _my_b_write;
174 int io_cache_st::init_io_cache(
int file_arg,
size_t cachesize,
175 enum cache_type type_arg, my_off_t seek_offset,
176 bool use_async_io, myf cache_myflags)
180 my_off_t end_of_file_local= ~(my_off_t) 0;
184 pos_in_file= seek_offset;
185 pre_close = pre_read = post_read = 0;
193 pos= lseek(file, 0, SEEK_CUR);
194 if ((pos == MY_FILEPOS_ERROR) && (errno == ESPIPE))
206 assert(seek_offset == 0);
209 seek_not_done= test(seek_offset != (my_off_t)pos);
212 if (!cachesize && !(cachesize= my_default_record_cache_size))
214 min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
215 if (type_arg == READ_CACHE)
217 if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
220 end_of_file_local=lseek(file,0L,SEEK_END);
222 seek_not_done= end_of_file_local == seek_offset ? 0 : 1;
223 if (end_of_file_local < seek_offset)
224 end_of_file_local=seek_offset;
226 if ((my_off_t) cachesize > end_of_file_local-seek_offset+IO_SIZE*2-1)
228 cachesize= (size_t) (end_of_file_local-seek_offset)+IO_SIZE*2-1;
233 cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
234 if (type_arg != READ_NET && type_arg != WRITE_NET)
237 cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
238 if (cachesize < min_cache)
239 cachesize = min_cache;
240 size_t buffer_block= cachesize;
241 if (type_arg == READ_CACHE && not global_read_buffer.add(buffer_block))
243 my_error(ER_OUT_OF_GLOBAL_READMEMORY, MYF(ME_ERROR+ME_WAITTANG));
247 buffer= (
unsigned char*) malloc(buffer_block);
249 alloced_buffer=
true;
252 read_length=buffer_length=cachesize;
253 myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
254 request_pos= read_pos= write_pos = buffer;
256 if (type_arg == WRITE_CACHE)
258 buffer+buffer_length- (seek_offset & (IO_SIZE-1));
263 end_of_file= end_of_file_local;
280 bool io_cache_st::reinit_io_cache(
enum cache_type type_arg,
281 my_off_t seek_offset,
286 assert(type_arg != READ_NET && type != READ_NET &&
287 type_arg != WRITE_NET && type != WRITE_NET);
291 seek_offset >= pos_in_file &&
292 seek_offset <= tell())
296 if (type == WRITE_CACHE && type_arg == READ_CACHE)
304 seek_not_done= (file != -1);
306 else if (type_arg == WRITE_CACHE)
308 if (type == READ_CACHE)
310 write_end=write_buffer+buffer_length;
313 end_of_file = ~(my_off_t) 0;
315 pos=request_pos+(seek_offset-pos_in_file);
316 if (type_arg == WRITE_CACHE)
327 if (type == WRITE_CACHE && type_arg == READ_CACHE)
330 if (!clear_cache && flush(1))
332 pos_in_file=seek_offset;
335 request_pos=read_pos=write_pos=buffer;
336 if (type_arg == READ_CACHE)
342 write_end= (buffer + buffer_length - (seek_offset & (IO_SIZE-1)));
343 end_of_file= ~(my_off_t) 0;
373 static int _my_b_read(
io_cache_st *info,
unsigned char *Buffer,
size_t Count)
375 size_t length_local,diff_length,left_length, max_length;
376 my_off_t pos_in_file_local;
378 if ((left_length= (
size_t) (info->read_end-info->read_pos)))
380 assert(Count >= left_length);
381 memcpy(Buffer,info->read_pos, left_length);
387 pos_in_file_local=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
395 if (info->seek_not_done)
397 if ((lseek(info->file,pos_in_file_local,SEEK_SET) != MY_FILEPOS_ERROR))
400 info->seek_not_done= 0;
409 assert(errno != ESPIPE);
415 diff_length= (size_t) (pos_in_file_local & (IO_SIZE-1));
416 if (Count >= (
size_t) (IO_SIZE+(IO_SIZE-diff_length)))
419 if (info->end_of_file <= pos_in_file_local)
421 info->error= (int) left_length;
424 length_local=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
425 if ((read_length= my_read(info->file,Buffer, length_local, info->myflags)) != length_local)
427 info->error= (read_length == (size_t) -1 ? -1 :
428 (
int) (read_length+left_length));
431 Count-= length_local;
432 Buffer+= length_local;
433 pos_in_file_local+= length_local;
434 left_length+= length_local;
438 max_length= info->read_length-diff_length;
439 if (info->type != READ_FIFO &&
440 max_length > (info->end_of_file - pos_in_file_local))
441 max_length= (
size_t) (info->end_of_file - pos_in_file_local);
446 info->error=
static_cast<int>(left_length);
451 else if (( length_local= my_read(info->file,info->buffer, max_length,
452 info->myflags)) < Count ||
453 length_local == (
size_t) -1)
455 if ( length_local != (
size_t) -1)
456 memcpy(Buffer, info->buffer, length_local);
457 info->pos_in_file= pos_in_file_local;
458 info->error= length_local == (size_t) -1 ? -1 : (
int) ( length_local+left_length);
459 info->read_pos=info->read_end=info->buffer;
462 info->read_pos=info->buffer+Count;
463 info->read_end=info->buffer+ length_local;
464 info->pos_in_file=pos_in_file_local;
465 memcpy(Buffer, info->buffer, Count);
473 int io_cache_st::get()
475 if (read_pos != read_end)
482 if (read_function(
this, &buff, 1))
499 int _my_b_write(
io_cache_st *info,
const unsigned char *Buffer,
size_t Count)
501 size_t rest_length,length_local;
503 if (info->pos_in_file+info->buffer_length > info->end_of_file)
506 return info->error = -1;
509 rest_length= (size_t) (info->write_end - info->write_pos);
510 memcpy(info->write_pos,Buffer,(
size_t) rest_length);
513 info->write_pos+=rest_length;
517 if (Count >= IO_SIZE)
519 length_local=Count & (size_t) ~(IO_SIZE-1);
520 if (info->seek_not_done)
528 if (lseek(info->file,info->pos_in_file,SEEK_SET))
533 info->seek_not_done=0;
535 if (my_write(info->file, Buffer, length_local, info->myflags | MY_NABP))
536 return info->error= -1;
539 Buffer+=length_local;
540 info->pos_in_file+=length_local;
542 memcpy(info->write_pos,Buffer,(
size_t) Count);
543 info->write_pos+=Count;
553 static int my_block_write(io_cache_st *info,
const unsigned char *Buffer,
size_t Count, my_off_t pos)
558 if (pos < info->pos_in_file)
561 if (pos + Count <= info->pos_in_file)
562 return (pwrite(info->file, Buffer, Count, pos) == 0);
564 length_local= (uint32_t) (info->pos_in_file - pos);
565 if (pwrite(info->file, Buffer, length_local, pos) == 0)
566 info->error= error= -1;
567 Buffer+=length_local;
569 Count-= length_local;
573 length_local= (size_t) (info->write_end - info->buffer);
574 if (pos < info->pos_in_file + length_local)
576 size_t offset= (size_t) (pos - info->pos_in_file);
577 length_local-=offset;
578 if (length_local > Count)
580 memcpy(info->buffer+offset, Buffer, length_local);
581 Buffer+=length_local;
582 Count-= length_local;
584 if (info->buffer+length_local > info->write_pos)
585 info->write_pos=info->buffer+length_local;
590 if (_my_b_write(info, Buffer, Count))
595 int io_cache_st::block_write(
const void* Buffer,
size_t Count, my_off_t pos)
597 return my_block_write(
this, reinterpret_cast<const unsigned char*>(Buffer), Count, pos);
604 static int my_b_flush_io_cache(io_cache_st *info,
int need_append_buffer_lock)
607 bool append_cache=
false;
608 my_off_t pos_in_file_local;
610 if (info->type == WRITE_CACHE || append_cache)
612 if (info->file == -1)
614 if (info->real_open_cached_file())
615 return((info->error= -1));
617 lock_append_buffer(info, need_append_buffer_lock);
619 if ((length_local=(
size_t) (info->write_pos - info->write_buffer)))
621 pos_in_file_local=info->pos_in_file;
626 if (!append_cache && info->seek_not_done)
628 if (lseek(info->file,pos_in_file_local,SEEK_SET) == MY_FILEPOS_ERROR)
630 unlock_append_buffer(info, need_append_buffer_lock);
631 return((info->error= -1));
634 info->seek_not_done=0;
637 info->pos_in_file+=length_local;
638 info->write_end= (info->write_buffer+info->buffer_length-
639 ((pos_in_file_local+length_local) & (IO_SIZE-1)));
641 if (my_write(info->file,info->write_buffer,length_local,
642 info->myflags | MY_NABP))
648 set_if_bigger(info->end_of_file,(pos_in_file_local+length_local));
652 info->end_of_file+=(info->write_pos-info->append_read_pos);
653 my_off_t tell_ret= lseek(info->file, 0, SEEK_CUR);
654 assert(info->end_of_file == tell_ret);
657 info->append_read_pos=info->write_pos=info->write_buffer;
658 unlock_append_buffer(info, need_append_buffer_lock);
662 unlock_append_buffer(info, need_append_buffer_lock);
666 int io_cache_st::flush(
int need_append_buffer_lock)
668 return my_b_flush_io_cache(
this, need_append_buffer_lock);
685 int io_cache_st::end_io_cache()
696 if (type == READ_CACHE)
697 global_read_buffer.sub(buffer_length);
700 _error= my_b_flush_io_cache(
this, 1);
701 free((
unsigned char*) buffer);
702 buffer=read_pos=(
unsigned char*) 0;
TODO: Rename this file - func.h is stupid.