47
47
write buffer to the read buffer before we start to reuse it.
50
#include "drizzled/internal/mysys_priv.h"
51
#include "drizzled/internal/m_string.h"
50
#define MAP_TO_USE_RAID
51
#include "mysys_priv.h"
52
#include <mystrings/m_string.h>
52
53
#ifdef HAVE_AIOWAIT
53
#include "drizzled/my_error.h"
54
#include "drizzled/internal/aio_result.h"
54
#include "mysys_err.h"
55
55
static void my_aiowait(my_aio_result *result);
57
#include "drizzled/internal/iocache.h"
59
#include <drizzled/util/test.h>
66
static int _my_b_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count);
67
static int _my_b_read_r(register IO_CACHE *cache, unsigned char *Buffer, size_t Count);
68
static int _my_b_seq_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count);
69
static int _my_b_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count);
72
59
#define lock_append_buffer(info) \
73
60
pthread_mutex_lock(&(info)->append_buffer_lock)
161
int init_io_cache(IO_CACHE *info, int file, size_t cachesize,
148
int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
162
149
enum cache_type type, my_off_t seek_offset,
163
150
bool use_async_io, myf cache_myflags)
165
152
size_t min_cache;
167
154
my_off_t end_of_file= ~(my_off_t) 0;
169
156
info->file= file;
180
pos= lseek(file, 0, SEEK_CUR);
181
if ((pos == MY_FILEPOS_ERROR) && (errno == ESPIPE))
167
pos= my_tell(file, MYF(0));
168
if ((pos == (my_off_t) -1) && (my_errno == ESPIPE))
184
171
This kind of object doesn't support seek() or tell(). Don't set a
206
194
if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
208
196
/* Calculate end of file to avoid allocating oversized buffers */
209
end_of_file=lseek(file,0L,SEEK_END);
197
end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
210
198
/* Need to reset seek_not_done now that we just did a seek. */
211
199
info->seek_not_done= end_of_file == seek_offset ? 0 : 1;
212
200
if (end_of_file < seek_offset)
233
221
if (type == SEQ_READ_APPEND)
234
222
buffer_block *= 2;
235
223
if ((info->buffer=
236
(unsigned char*) malloc(buffer_block)) != 0)
224
(uchar*) my_malloc(buffer_block,
225
MYF((cache_myflags & ~ MY_WME) |
226
(cachesize == min_cache ? MY_WME : 0)))) != 0)
238
228
info->write_buffer=info->buffer;
239
229
if (type == SEQ_READ_APPEND)
392
389
#ifdef HAVE_AIOWAIT
393
390
if (use_async_io && ! my_disable_async_io &&
394
((uint32_t) info->buffer_length <
395
(uint32_t) (info->end_of_file - seek_offset)))
391
((ulong) info->buffer_length <
392
(ulong) (info->end_of_file - seek_offset)))
397
394
info->read_length=info->buffer_length/2;
398
395
info->read_function=_my_b_async_read;
405
400
} /* reinit_io_cache */
434
429
1 Error: can't read requested characters
437
static int _my_b_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count)
432
int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
439
434
size_t length,diff_length,left_length, max_length;
440
435
my_off_t pos_in_file;
894
890
1 Error: can't read requested characters
897
extern "C" int _my_b_read_r(register IO_CACHE *cache, unsigned char *Buffer, size_t Count)
893
int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
899
895
my_off_t pos_in_file;
900
896
size_t length, diff_length, left_length;
1062
1059
1 Failed to read
1065
extern "C" int _my_b_seq_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count)
1062
int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
1067
1064
size_t length, diff_length, left_length, save_count, max_length;
1068
1065
my_off_t pos_in_file;
1087
1084
With read-append cache we must always do a seek before we read,
1088
1085
because the write could have moved the file pointer astray
1090
if (lseek(info->file,pos_in_file,SEEK_SET) == MY_FILEPOS_ERROR)
1087
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == MY_FILEPOS_ERROR)
1092
1089
info->error= -1;
1093
1090
unlock_append_buffer(info);
1219
1216
Count Number of bytes to read into Buffer
1222
-1 An error has occurred; errno is set.
1219
-1 An error has occurred; my_errno is set.
1224
1221
1 An error has occurred; IO_CACHE to error state.
1227
int _my_b_async_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count)
1224
int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
1229
1226
size_t length,read_length,diff_length,left_length,use_length,org_Count;
1230
1227
size_t max_length;
1231
1228
my_off_t next_pos_in_file;
1232
unsigned char *read_buffer;
1234
1231
memcpy(Buffer,info->read_pos,
1235
1232
(left_length= (size_t) (info->read_end-info->read_pos)));
1247
1244
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
1248
1245
my_filename(info->file),
1249
1246
info->aio_result.result.aio_errno);
1250
errno=info->aio_result.result.aio_errno;
1247
my_errno=info->aio_result.result.aio_errno;
1251
1248
info->error= -1;
1254
1251
if (! (read_length= (size_t) info->aio_result.result.aio_return) ||
1255
1252
read_length == (size_t) -1)
1257
errno=0; /* For testing */
1254
my_errno=0; /* For testing */
1258
1255
info->error= (read_length == (size_t) -1 ? -1 :
1259
1256
(int) (read_length+left_length));
1331
1329
{ /* Didn't find hole block */
1332
1330
if (info->myflags & (MY_WME | MY_FAE | MY_FNABP) && Count != org_Count)
1333
1331
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
1334
my_filename(info->file),errno);
1332
my_filename(info->file),my_errno);
1335
1333
info->error=(int) (read_length+left_length);
1365
1363
info->aio_result.result.aio_errno=AIO_INPROGRESS; /* Marker for test */
1366
1364
if (aioread(info->file,read_buffer, max_length,
1367
(my_off_t) next_pos_in_file,SEEK_SET,
1365
(my_off_t) next_pos_in_file,MY_SEEK_SET,
1368
1366
&info->aio_result.result))
1369
1367
{ /* Skip async io */
1371
1369
if (info->request_pos != info->buffer)
1373
memmove(info->buffer, info->request_pos,
1374
(size_t) (info->read_end - info->read_pos));
1371
memcpy(info->buffer, info->request_pos,
1372
(size_t) (info->read_end - info->read_pos));
1375
1373
info->request_pos=info->buffer;
1376
1374
info->read_pos-=info->read_length;
1377
1375
info->read_end-=info->read_length;
1399
1397
return my_b_EOF;
1400
1398
if ((post_read = info->post_read))
1401
1399
(*post_read)(info);
1402
return (int) (unsigned char) buff;
1400
return (int) (uchar) buff;
1406
1404
Write a byte buffer to IO_CACHE and flush to disk
1407
1405
if IO_CACHE is full.
1410
1408
1 On error on write
1412
-1 On error; errno contains error code.
1410
-1 On error; my_errno contains error code.
1415
extern "C" int _my_b_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count)
1413
int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
1417
1415
size_t rest_length,length;
1419
1417
if (info->pos_in_file+info->buffer_length > info->end_of_file)
1419
my_errno=errno=EFBIG;
1422
1420
return info->error = -1;
1477
Append a block to the write buffer.
1478
This is done with the buffer locked to ensure that we don't read from
1479
the write buffer before we are ready with it.
1482
int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
1484
size_t rest_length,length;
1487
Assert that we cannot come here with a shared cache. If we do one
1488
day, we might need to add a call to copy_to_read_buffer().
1490
assert(!info->share);
1492
lock_append_buffer(info);
1493
rest_length= (size_t) (info->write_end - info->write_pos);
1494
if (Count <= rest_length)
1496
memcpy(info->write_pos, Buffer, rest_length);
1497
Buffer+=rest_length;
1499
info->write_pos+=rest_length;
1500
if (my_b_flush_io_cache(info,0))
1502
unlock_append_buffer(info);
1505
if (Count >= IO_SIZE)
1506
{ /* Fill first intern buffer */
1507
length=Count & (size_t) ~(IO_SIZE-1);
1508
if (my_write(info->file,Buffer, length, info->myflags | MY_NABP))
1510
unlock_append_buffer(info);
1511
return info->error= -1;
1515
info->end_of_file+=length;
1519
memcpy(info->write_pos,Buffer,(size_t) Count);
1520
info->write_pos+=Count;
1521
unlock_append_buffer(info);
1526
int my_b_safe_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
1529
Sasha: We are not writing this with the ? operator to avoid hitting
1530
a possible compiler bug. At least gcc 2.95 cannot deal with
1531
several layers of ternary operators that evaluated comma(,) operator
1532
expressions inside - I do have a test case if somebody wants it
1534
if (info->type == SEQ_READ_APPEND)
1535
return my_b_append(info, Buffer, Count);
1536
return my_b_write(info, Buffer, Count);
1478
1541
Write a block to disk where part of the data may be inside the record
1479
1542
buffer. As all write calls to the data goes through the cache,
1480
1543
we will never get a seek over the end of the buffer
1483
int my_block_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count,
1546
int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
1498
1561
if (pos + Count <= info->pos_in_file)
1499
1562
return (pwrite(info->file, Buffer, Count, pos) == 0);
1500
1563
/* Write the part of the block that is before buffer */
1501
length= (uint32_t) (info->pos_in_file - pos);
1564
length= (uint) (info->pos_in_file - pos);
1502
1565
if (pwrite(info->file, Buffer, length, pos) == 0)
1503
1566
info->error= error= -1;
1504
1567
Buffer+=length;
1506
1569
Count-= length;
1571
info->seek_not_done=1;
1509
1575
/* Check if we want to write inside the used part of the buffer.*/
1574
1640
if (!append_cache && info->seek_not_done)
1575
1641
{ /* File touched, do seek */
1576
if (lseek(info->file,pos_in_file,SEEK_SET) == MY_FILEPOS_ERROR)
1642
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
1578
1645
UNLOCK_APPEND_BUFFER;
1579
1646
return((info->error= -1));
1600
1667
info->end_of_file+=(info->write_pos-info->append_read_pos);
1601
my_off_t tell_ret= lseek(info->file, 0, SEEK_CUR);
1602
assert(info->end_of_file == tell_ret);
1668
assert(info->end_of_file == my_tell(info->file,MYF(0)));
1605
1671
info->append_read_pos=info->write_pos=info->write_buffer;
1672
++info->disk_writes;
1606
1673
UNLOCK_APPEND_BUFFER;
1607
1674
return(info->error);
1656
1723
info->alloced_buffer=0;
1657
1724
if (info->file != -1) /* File doesn't exist */
1658
1725
error= my_b_flush_io_cache(info,1);
1659
free((unsigned char*) info->buffer);
1660
info->buffer=info->read_pos=(unsigned char*) 0;
1726
my_free((uchar*) info->buffer,MYF(MY_WME));
1727
info->buffer=info->read_pos=(uchar*) 0;
1662
1729
if (info->type == SEQ_READ_APPEND)
1716
1783
char* block, *block_end;
1717
1784
MY_INIT(argv[0]);
1718
1785
max_block = cache_size*3;
1719
if (!(block=(char*)malloc(max_block)))
1786
if (!(block=(char*)my_malloc(max_block,MYF(MY_WME))))
1720
1787
die("Not enough memory to allocate test block");
1721
1788
block_end = block + max_block;
1722
1789
for (p = block,i=0; p < block_end;i++)
1740
1807
total_bytes += 4+block_size;
1742
1809
close_file(&sra_cache);
1810
my_free(block,MYF(MY_WME));
1744
1811
if (!my_stat(fname,&status,MYF(MY_WME)))
1745
1812
die("%s failed to stat, but I had just closed it,\
1746
1813
wonder how that happened");