~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/internal/mf_iocache.cc

  • Committer: lbieber
  • Date: 2010-10-01 12:16:18 UTC
  • mfrom: (1802.1.1 fix-bug-651256)
  • Revision ID: lbieber@orisndriz08-20101001121618-uqcboygpjwbiglem
Merge Vijay - fix bug 651256 - Remove --help-extended

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
17
  Cashing of files with only does (sequential) read or writes of fixed-
51
51
 
52
52
#include "drizzled/internal/my_sys.h"
53
53
#include "drizzled/internal/m_string.h"
54
 
#include "drizzled/drizzled.h"
55
54
#ifdef HAVE_AIOWAIT
56
55
#include "drizzled/error.h"
57
56
#include "drizzled/internal/aio_result.h"
70
69
namespace internal
71
70
{
72
71
 
73
 
static int _my_b_read(register st_io_cache *info, unsigned char *Buffer, size_t Count);
74
 
static int _my_b_write(register st_io_cache *info, const unsigned char *Buffer, size_t Count);
 
72
static int _my_b_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count);
 
73
static int _my_b_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count);
75
74
 
76
75
/**
77
76
 * @brief
78
 
 *   Lock appends for the st_io_cache if required (need_append_buffer_lock)   
 
77
 *   Lock appends for the IO_CACHE if required (need_append_buffer_lock)   
79
78
 */
80
79
inline
81
 
static void lock_append_buffer(register st_io_cache *, int )
 
80
static void lock_append_buffer(register IO_CACHE *, int )
82
81
{
83
82
}
84
83
 
85
84
/**
86
85
 * @brief
87
 
 *   Unlock appends for the st_io_cache if required (need_append_buffer_lock)   
 
86
 *   Unlock appends for the IO_CACHE if required (need_append_buffer_lock)   
88
87
 */
89
88
inline
90
 
static void unlock_append_buffer(register st_io_cache *, int )
 
89
static void unlock_append_buffer(register IO_CACHE *, int )
91
90
{
92
91
}
93
92
 
114
113
 
115
114
/**
116
115
 * @brief 
117
 
 *   Setup internal pointers inside st_io_cache
 
116
 *   Setup internal pointers inside IO_CACHE
118
117
 * 
119
118
 * @details
120
 
 *   This is called on automatically on init or reinit of st_io_cache
121
 
 *   It must be called externally if one moves or copies an st_io_cache object.
 
119
 *   This is called on automatically on init or reinit of IO_CACHE
 
120
 *   It must be called externally if one moves or copies an IO_CACHE object.
122
121
 * 
123
122
 * @param info Cache handler to setup
124
123
 */
125
 
void st_io_cache::setup_io_cache()
 
124
void setup_io_cache(IO_CACHE* info)
126
125
{
127
126
  /* Ensure that my_b_tell() and my_b_bytes_in_cache works */
128
 
  if (type == WRITE_CACHE)
 
127
  if (info->type == WRITE_CACHE)
129
128
  {
130
 
    current_pos= &write_pos;
131
 
    current_end= &write_end;
 
129
    info->current_pos= &info->write_pos;
 
130
    info->current_end= &info->write_end;
132
131
  }
133
132
  else
134
133
  {
135
 
    current_pos= &read_pos;
136
 
    current_end= &read_end;
 
134
    info->current_pos= &info->read_pos;
 
135
    info->current_end= &info->read_end;
137
136
  }
138
137
}
139
138
 
140
139
 
141
 
void st_io_cache::init_functions()
 
140
static void
 
141
init_functions(IO_CACHE* info)
142
142
{
 
143
  enum cache_type type= info->type;
143
144
  switch (type) {
144
145
  case READ_NET:
145
146
    /*
151
152
    */
152
153
    break;
153
154
  default:
154
 
    read_function = _my_b_read;
155
 
    write_function = _my_b_write;
 
155
    info->read_function = _my_b_read;
 
156
    info->write_function = _my_b_write;
156
157
  }
157
158
 
158
 
  setup_io_cache();
 
159
  setup_io_cache(info);
159
160
}
160
161
 
161
162
/**
162
163
 * @brief
163
 
 *   Initialize an st_io_cache object
 
164
 *   Initialize an IO_CACHE object
164
165
 *
 
166
 * @param info Cache handler to initialize
165
167
 * @param file File that should be associated with the handler
166
168
 *                 If == -1 then real_open_cached_file() will be called when it's time to open file.
167
169
 * @param cachesize Size of buffer to allocate for read/write
175
177
 * @retval 0 success
176
178
 * @retval # error
177
179
 */
178
 
int st_io_cache::init_io_cache(int file_arg, size_t cachesize,
179
 
                               enum cache_type type_arg, my_off_t seek_offset,
180
 
                               bool use_async_io, myf cache_myflags)
 
180
int init_io_cache(IO_CACHE *info, int file, size_t cachesize,
 
181
                  enum cache_type type, my_off_t seek_offset,
 
182
                  bool use_async_io, myf cache_myflags)
181
183
{
182
184
  size_t min_cache;
183
185
  off_t pos;
184
 
  my_off_t end_of_file_local= ~(my_off_t) 0;
 
186
  my_off_t end_of_file= ~(my_off_t) 0;
185
187
 
186
 
  file= file_arg;
187
 
  type= TYPE_NOT_SET;       /* Don't set it until mutex are created */
188
 
  pos_in_file= seek_offset;
189
 
  pre_close = pre_read = post_read = 0;
190
 
  arg = 0;
191
 
  alloced_buffer = 0;
192
 
  buffer=0;
193
 
  seek_not_done= 0;
 
188
  info->file= file;
 
189
  info->type= TYPE_NOT_SET;         /* Don't set it until mutex are created */
 
190
  info->pos_in_file= seek_offset;
 
191
  info->pre_close = info->pre_read = info->post_read = 0;
 
192
  info->arg = 0;
 
193
  info->alloced_buffer = 0;
 
194
  info->buffer=0;
 
195
  info->seek_not_done= 0;
194
196
 
195
197
  if (file >= 0)
196
198
  {
201
203
         This kind of object doesn't support seek() or tell(). Don't set a
202
204
         flag that will make us again try to seek() later and fail.
203
205
      */
204
 
      seek_not_done= 0;
 
206
      info->seek_not_done= 0;
205
207
      /*
206
208
        Additionally, if we're supposed to start somewhere other than the
207
209
        the beginning of whatever this file is, then somebody made a bad
210
212
      assert(seek_offset == 0);
211
213
    }
212
214
    else
213
 
      seek_not_done= test(seek_offset != (my_off_t)pos);
 
215
      info->seek_not_done= test(seek_offset != (my_off_t)pos);
214
216
  }
215
217
 
216
218
  if (!cachesize && !(cachesize= my_default_record_cache_size))
217
 
    return 1;                           /* No cache requested */
 
219
    return(1);                          /* No cache requested */
218
220
  min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
219
 
  if (type_arg == READ_CACHE)
 
221
  if (type == READ_CACHE)
220
222
  {                                             /* Assume file isn't growing */
221
223
    if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
222
224
    {
223
225
      /* Calculate end of file to avoid allocating oversized buffers */
224
 
      end_of_file_local=lseek(file,0L,SEEK_END);
 
226
      end_of_file=lseek(file,0L,SEEK_END);
225
227
      /* Need to reset seek_not_done now that we just did a seek. */
226
 
      seek_not_done= end_of_file_local == seek_offset ? 0 : 1;
227
 
      if (end_of_file_local < seek_offset)
228
 
        end_of_file_local=seek_offset;
 
228
      info->seek_not_done= end_of_file == seek_offset ? 0 : 1;
 
229
      if (end_of_file < seek_offset)
 
230
        end_of_file=seek_offset;
229
231
      /* Trim cache size if the file is very small */
230
 
      if ((my_off_t) cachesize > end_of_file_local-seek_offset+IO_SIZE*2-1)
 
232
      if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
231
233
      {
232
 
        cachesize= (size_t) (end_of_file_local-seek_offset)+IO_SIZE*2-1;
 
234
        cachesize= (size_t) (end_of_file-seek_offset)+IO_SIZE*2-1;
233
235
        use_async_io=0;                         /* No need to use async */
234
236
      }
235
237
    }
236
238
  }
237
239
  cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
238
 
  if (type_arg != READ_NET && type_arg != WRITE_NET)
 
240
  if (type != READ_NET && type != WRITE_NET)
239
241
  {
240
242
    /* Retry allocating memory in smaller blocks until we get one */
241
243
    cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
245
247
      if (cachesize < min_cache)
246
248
        cachesize = min_cache;
247
249
      buffer_block= cachesize;
248
 
      if ((type_arg == READ_CACHE) and (not global_read_buffer.add(buffer_block)))
249
 
      {
250
 
        my_error(ER_OUT_OF_GLOBAL_READMEMORY, MYF(ME_ERROR+ME_WAITTANG));
251
 
        return 2;
252
 
      }
253
 
 
254
 
      if ((buffer=
 
250
      if ((info->buffer=
255
251
           (unsigned char*) malloc(buffer_block)) != 0)
256
252
      {
257
 
        write_buffer=buffer;
258
 
        alloced_buffer= true;
 
253
        info->write_buffer=info->buffer;
 
254
        info->alloced_buffer= true;
259
255
        break;                                  /* Enough memory found */
260
256
      }
261
257
      if (cachesize == min_cache)
262
 
      {
263
 
        if (type_arg == READ_CACHE)
264
 
          global_read_buffer.sub(buffer_block);
265
 
        return 2;                               /* Can't alloc cache */
266
 
      }
 
258
        return(2);                              /* Can't alloc cache */
267
259
      /* Try with less memory */
268
 
      if (type_arg == READ_CACHE)
269
 
        global_read_buffer.sub(buffer_block);
270
260
      cachesize= (cachesize*3/4 & ~(min_cache-1));
271
261
    }
272
262
  }
273
263
 
274
 
  read_length=buffer_length=cachesize;
275
 
  myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
276
 
  request_pos= read_pos= write_pos = buffer;
 
264
  info->read_length=info->buffer_length=cachesize;
 
265
  info->myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
 
266
  info->request_pos= info->read_pos= info->write_pos = info->buffer;
277
267
 
278
 
  if (type_arg == WRITE_CACHE)
279
 
    write_end=
280
 
      buffer+buffer_length- (seek_offset & (IO_SIZE-1));
 
268
  if (type == WRITE_CACHE)
 
269
    info->write_end=
 
270
      info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));
281
271
  else
282
 
    read_end=buffer;            /* Nothing in cache */
 
272
    info->read_end=info->buffer;                /* Nothing in cache */
283
273
 
284
274
  /* End_of_file may be changed by user later */
285
 
  end_of_file= end_of_file_local;
286
 
  error= 0;
287
 
  type= type_arg;
288
 
  init_functions();
 
275
  info->end_of_file= end_of_file;
 
276
  info->error=0;
 
277
  info->type= type;
 
278
  init_functions(info);
289
279
#ifdef HAVE_AIOWAIT
290
280
  if (use_async_io && ! my_disable_async_io)
291
281
  {
292
 
    read_length/=2;
293
 
    read_function=_my_b_async_read;
 
282
    info->read_length/=2;
 
283
    info->read_function=_my_b_async_read;
294
284
  }
295
 
  inited= aio_result.pending= 0;
 
285
  info->inited=info->aio_result.pending=0;
296
286
#endif
297
 
  return 0;
 
287
  return(0);
298
288
}                                               /* init_io_cache */
299
289
 
300
290
        /* Wait until current request is ready */
319
309
        break;
320
310
    }
321
311
  }
 
312
  return;
322
313
}
323
314
#endif
324
315
 
332
323
 *   If we are doing a reinit of a cache where we have the start of the file
333
324
 *   in the cache, we are reusing this memory without flushing it to disk.
334
325
 */
335
 
bool st_io_cache::reinit_io_cache(enum cache_type type_arg,
336
 
                                  my_off_t seek_offset,
337
 
                                  bool use_async_io,
338
 
                                  bool clear_cache)
 
326
bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
 
327
                        my_off_t seek_offset,
 
328
                        bool use_async_io,
 
329
                        bool clear_cache)
339
330
{
340
331
  /* One can't do reinit with the following types */
341
 
  assert(type_arg != READ_NET && type != READ_NET &&
342
 
              type_arg != WRITE_NET && type != WRITE_NET);
 
332
  assert(type != READ_NET && info->type != READ_NET &&
 
333
              type != WRITE_NET && info->type != WRITE_NET);
343
334
 
344
335
  /* If the whole file is in memory, avoid flushing to disk */
345
336
  if (! clear_cache &&
346
 
      seek_offset >= pos_in_file &&
347
 
      seek_offset <= my_b_tell(this))
 
337
      seek_offset >= info->pos_in_file &&
 
338
      seek_offset <= my_b_tell(info))
348
339
  {
349
340
    /* Reuse current buffer without flushing it to disk */
350
341
    unsigned char *pos;
351
 
    if (type == WRITE_CACHE && type_arg == READ_CACHE)
 
342
    if (info->type == WRITE_CACHE && type == READ_CACHE)
352
343
    {
353
 
      read_end=write_pos;
354
 
      end_of_file=my_b_tell(this);
 
344
      info->read_end=info->write_pos;
 
345
      info->end_of_file=my_b_tell(info);
355
346
      /*
356
347
        Trigger a new seek only if we have a valid
357
348
        file handle.
358
349
      */
359
 
      seek_not_done= (file != -1);
 
350
      info->seek_not_done= (info->file != -1);
360
351
    }
361
 
    else if (type_arg == WRITE_CACHE)
 
352
    else if (type == WRITE_CACHE)
362
353
    {
363
 
      if (type == READ_CACHE)
 
354
      if (info->type == READ_CACHE)
364
355
      {
365
 
        write_end=write_buffer+buffer_length;
366
 
        seek_not_done=1;
 
356
        info->write_end=info->write_buffer+info->buffer_length;
 
357
        info->seek_not_done=1;
367
358
      }
368
 
      end_of_file = ~(my_off_t) 0;
 
359
      info->end_of_file = ~(my_off_t) 0;
369
360
    }
370
 
    pos=request_pos+(seek_offset-pos_in_file);
371
 
    if (type_arg == WRITE_CACHE)
372
 
      write_pos=pos;
 
361
    pos=info->request_pos+(seek_offset-info->pos_in_file);
 
362
    if (type == WRITE_CACHE)
 
363
      info->write_pos=pos;
373
364
    else
374
 
      read_pos= pos;
 
365
      info->read_pos= pos;
375
366
#ifdef HAVE_AIOWAIT
376
 
    my_aiowait(&aio_result);            /* Wait for outstanding req */
 
367
    my_aiowait(&info->aio_result);              /* Wait for outstanding req */
377
368
#endif
378
369
  }
379
370
  else
382
373
      If we change from WRITE_CACHE to READ_CACHE, assume that everything
383
374
      after the current positions should be ignored
384
375
    */
385
 
    if (type == WRITE_CACHE && type_arg == READ_CACHE)
386
 
      end_of_file=my_b_tell(this);
 
376
    if (info->type == WRITE_CACHE && type == READ_CACHE)
 
377
      info->end_of_file=my_b_tell(info);
387
378
    /* flush cache if we want to reuse it */
388
 
    if (!clear_cache && my_b_flush_io_cache(this, 1))
389
 
      return 1;
390
 
    pos_in_file=seek_offset;
 
379
    if (!clear_cache && my_b_flush_io_cache(info,1))
 
380
      return(1);
 
381
    info->pos_in_file=seek_offset;
391
382
    /* Better to do always do a seek */
392
 
    seek_not_done=1;
393
 
    request_pos=read_pos=write_pos=buffer;
394
 
    if (type_arg == READ_CACHE)
 
383
    info->seek_not_done=1;
 
384
    info->request_pos=info->read_pos=info->write_pos=info->buffer;
 
385
    if (type == READ_CACHE)
395
386
    {
396
 
      read_end=buffer;          /* Nothing in cache */
 
387
      info->read_end=info->buffer;              /* Nothing in cache */
397
388
    }
398
389
    else
399
390
    {
400
 
      write_end=(buffer + buffer_length -
 
391
      info->write_end=(info->buffer + info->buffer_length -
401
392
                       (seek_offset & (IO_SIZE-1)));
402
 
      end_of_file= ~(my_off_t) 0;
 
393
      info->end_of_file= ~(my_off_t) 0;
403
394
    }
404
395
  }
405
 
  type= type_arg;
406
 
  error=0;
407
 
  init_functions();
 
396
  info->type=type;
 
397
  info->error=0;
 
398
  init_functions(info);
408
399
 
409
400
#ifdef HAVE_AIOWAIT
410
401
  if (use_async_io && ! my_disable_async_io &&
411
 
      ((uint32_t) buffer_length <
412
 
       (uint32_t) (end_of_file - seek_offset)))
 
402
      ((uint32_t) info->buffer_length <
 
403
       (uint32_t) (info->end_of_file - seek_offset)))
413
404
  {
414
 
    read_length=buffer_length/2;
415
 
    read_function=_my_b_async_read;
 
405
    info->read_length=info->buffer_length/2;
 
406
    info->read_function=_my_b_async_read;
416
407
  }
417
 
  inited= 0;
 
408
  info->inited=0;
418
409
#else
419
410
  (void)use_async_io;
420
411
#endif
421
 
  return 0;
 
412
  return(0);
422
413
} /* reinit_io_cache */
423
414
 
424
415
/**
435
426
 *   types than my_off_t unless you can be sure that their value fits.
436
427
 *   Same applies to differences of file offsets.
437
428
 *
438
 
 * @param info st_io_cache pointer @param Buffer Buffer to retrieve count bytes
 
429
 * @param info IO_CACHE pointer @param Buffer Buffer to retrieve count bytes
439
430
 * from file @param Count Number of bytes to read into Buffer
440
431
 * 
441
432
 * @retval 0 We succeeded in reading all data
442
433
 * @retval 1 Error: can't read requested characters
443
434
 */
444
 
static int _my_b_read(register st_io_cache *info, unsigned char *Buffer, size_t Count)
 
435
static int _my_b_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count)
445
436
{
446
 
  size_t length_local,diff_length,left_length, max_length;
447
 
  my_off_t pos_in_file_local;
 
437
  size_t length,diff_length,left_length, max_length;
 
438
  my_off_t pos_in_file;
448
439
 
449
440
  if ((left_length= (size_t) (info->read_end-info->read_pos)))
450
441
  {
455
446
  }
456
447
 
457
448
  /* pos_in_file always point on where info->buffer was read */
458
 
  pos_in_file_local=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
 
449
  pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
459
450
 
460
451
  /*
461
 
    Whenever a function which operates on st_io_cache flushes/writes
462
 
    some part of the st_io_cache to disk it will set the property
 
452
    Whenever a function which operates on IO_CACHE flushes/writes
 
453
    some part of the IO_CACHE to disk it will set the property
463
454
    "seek_not_done" to indicate this to other functions operating
464
 
    on the st_io_cache.
 
455
    on the IO_CACHE.
465
456
  */
466
457
  if (info->seek_not_done)
467
458
  {
468
 
    if ((lseek(info->file,pos_in_file_local,SEEK_SET) != MY_FILEPOS_ERROR))
 
459
    if ((lseek(info->file,pos_in_file,SEEK_SET) != MY_FILEPOS_ERROR))
469
460
    {
470
461
      /* No error, reset seek_not_done flag. */
471
462
      info->seek_not_done= 0;
483
474
    }
484
475
  }
485
476
 
486
 
  diff_length= (size_t) (pos_in_file_local & (IO_SIZE-1));
 
477
  diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
487
478
  if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
488
479
  {                                     /* Fill first intern buffer */
489
480
    size_t read_length;
490
 
    if (info->end_of_file <= pos_in_file_local)
 
481
    if (info->end_of_file <= pos_in_file)
491
482
    {                                   /* End of file */
492
483
      info->error= (int) left_length;
493
484
      return(1);
494
485
    }
495
 
    length_local=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
496
 
    if ((read_length= my_read(info->file,Buffer, length_local, info->myflags)) != length_local)
 
486
    length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
 
487
    if ((read_length= my_read(info->file,Buffer, length, info->myflags))
 
488
        != length)
497
489
    {
498
490
      info->error= (read_length == (size_t) -1 ? -1 :
499
491
                    (int) (read_length+left_length));
500
492
      return(1);
501
493
    }
502
 
    Count-= length_local;
503
 
    Buffer+= length_local;
504
 
    pos_in_file_local+= length_local;
505
 
    left_length+= length_local;
 
494
    Count-=length;
 
495
    Buffer+=length;
 
496
    pos_in_file+=length;
 
497
    left_length+=length;
506
498
    diff_length=0;
507
499
  }
508
500
 
509
501
  max_length= info->read_length-diff_length;
510
502
  if (info->type != READ_FIFO &&
511
 
      max_length > (info->end_of_file - pos_in_file_local))
512
 
    max_length= (size_t) (info->end_of_file - pos_in_file_local);
 
503
      max_length > (info->end_of_file - pos_in_file))
 
504
    max_length= (size_t) (info->end_of_file - pos_in_file);
513
505
  if (!max_length)
514
506
  {
515
507
    if (Count)
517
509
      info->error= static_cast<int>(left_length);       /* We only got this many char */
518
510
      return(1);
519
511
    }
520
 
     length_local=0;                            /* Didn't read any chars */
 
512
    length=0;                           /* Didn't read any chars */
521
513
  }
522
 
  else if (( length_local= my_read(info->file,info->buffer, max_length,
 
514
  else if ((length= my_read(info->file,info->buffer, max_length,
523
515
                            info->myflags)) < Count ||
524
 
            length_local == (size_t) -1)
 
516
           length == (size_t) -1)
525
517
  {
526
 
    if ( length_local != (size_t) -1)
527
 
      memcpy(Buffer, info->buffer,  length_local);
528
 
    info->pos_in_file= pos_in_file_local;
529
 
    info->error=  length_local == (size_t) -1 ? -1 : (int) ( length_local+left_length);
 
518
    if (length != (size_t) -1)
 
519
      memcpy(Buffer, info->buffer, length);
 
520
    info->pos_in_file= pos_in_file;
 
521
    info->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
530
522
    info->read_pos=info->read_end=info->buffer;
531
523
    return(1);
532
524
  }
533
525
  info->read_pos=info->buffer+Count;
534
 
  info->read_end=info->buffer+ length_local;
535
 
  info->pos_in_file=pos_in_file_local;
 
526
  info->read_end=info->buffer+length;
 
527
  info->pos_in_file=pos_in_file;
536
528
  memcpy(Buffer, info->buffer, Count);
537
529
  return(0);
538
530
}
542
534
 
543
535
/**
544
536
 * @brief
545
 
 *   Read from the st_io_cache into a buffer and feed asynchronously from disk when needed.
 
537
 *   Read from the IO_CACHE into a buffer and feed asynchronously from disk when needed.
546
538
 *
547
 
 * @param info st_io_cache pointer
 
539
 * @param info IO_CACHE pointer
548
540
 * @param Buffer Buffer to retrieve count bytes from file
549
541
 * @param Count Number of bytes to read into Buffer
550
542
 * 
551
543
 * @retval -1 An error has occurred; errno is set.
552
544
 * @retval 0 Success
553
 
 * @retval 1 An error has occurred; st_io_cache to error state.
 
545
 * @retval 1 An error has occurred; IO_CACHE to error state.
554
546
 */
555
 
int _my_b_async_read(register st_io_cache *info, unsigned char *Buffer, size_t Count)
 
547
int _my_b_async_read(register IO_CACHE *info, unsigned char *Buffer, size_t Count)
556
548
{
557
 
  size_t length_local,read_length,diff_length,left_length,use_length,org_Count;
 
549
  size_t length,read_length,diff_length,left_length,use_length,org_Count;
558
550
  size_t max_length;
559
551
  my_off_t next_pos_in_file;
560
552
  unsigned char *read_buffer;
615
607
      }
616
608
    }
617
609
        /* Copy found bytes to buffer */
618
 
    length_local=min(Count,read_length);
619
 
    memcpy(Buffer,info->read_pos,(size_t) length_local);
620
 
    Buffer+=length_local;
621
 
    Count-=length_local;
622
 
    left_length+=length_local;
 
610
    length=min(Count,read_length);
 
611
    memcpy(Buffer,info->read_pos,(size_t) length);
 
612
    Buffer+=length;
 
613
    Count-=length;
 
614
    left_length+=length;
623
615
    info->read_end=info->rc_pos+read_length;
624
 
    info->read_pos+=length_local;
 
616
    info->read_pos+=length;
625
617
  }
626
618
  else
627
619
    next_pos_in_file=(info->pos_in_file+ (size_t)
719
711
 * @brief
720
712
 *   Read one byte when buffer is empty
721
713
 */
722
 
int _my_b_get(st_io_cache *info)
 
714
int _my_b_get(IO_CACHE *info)
723
715
{
724
716
  unsigned char buff;
725
717
  IO_CACHE_CALLBACK pre_read,post_read;
734
726
 
735
727
/**
736
728
 * @brief
737
 
 *   Write a byte buffer to st_io_cache and flush to disk if st_io_cache is full.
 
729
 *   Write a byte buffer to IO_CACHE and flush to disk if IO_CACHE is full.
738
730
 *
739
731
 * @retval -1 On error; errno contains error code.
740
732
 * @retval 0 On success
741
733
 * @retval 1 On error on write
742
734
 */
743
 
int _my_b_write(register st_io_cache *info, const unsigned char *Buffer, size_t Count)
 
735
int _my_b_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count)
744
736
{
745
 
  size_t rest_length,length_local;
 
737
  size_t rest_length,length;
746
738
 
747
739
  if (info->pos_in_file+info->buffer_length > info->end_of_file)
748
740
  {
749
 
    errno=EFBIG;
 
741
    errno=errno=EFBIG;
750
742
    return info->error = -1;
751
743
  }
752
744
 
760
752
    return 1;
761
753
  if (Count >= IO_SIZE)
762
754
  {                                     /* Fill first intern buffer */
763
 
    length_local=Count & (size_t) ~(IO_SIZE-1);
 
755
    length=Count & (size_t) ~(IO_SIZE-1);
764
756
    if (info->seek_not_done)
765
757
    {
766
758
      /*
767
 
        Whenever a function which operates on st_io_cache flushes/writes
768
 
        some part of the st_io_cache to disk it will set the property
 
759
        Whenever a function which operates on IO_CACHE flushes/writes
 
760
        some part of the IO_CACHE to disk it will set the property
769
761
        "seek_not_done" to indicate this to other functions operating
770
 
        on the st_io_cache.
 
762
        on the IO_CACHE.
771
763
      */
772
764
      if (lseek(info->file,info->pos_in_file,SEEK_SET))
773
765
      {
776
768
      }
777
769
      info->seek_not_done=0;
778
770
    }
779
 
    if (my_write(info->file, Buffer, length_local, info->myflags | MY_NABP))
 
771
    if (my_write(info->file, Buffer, length, info->myflags | MY_NABP))
780
772
      return info->error= -1;
781
773
 
782
 
    Count-=length_local;
783
 
    Buffer+=length_local;
784
 
    info->pos_in_file+=length_local;
 
774
    Count-=length;
 
775
    Buffer+=length;
 
776
    info->pos_in_file+=length;
785
777
  }
786
778
  memcpy(info->write_pos,Buffer,(size_t) Count);
787
779
  info->write_pos+=Count;
794
786
 *   As all write calls to the data goes through the cache,
795
787
 *   we will never get a seek over the end of the buffer.
796
788
 */
797
 
int my_block_write(register st_io_cache *info, const unsigned char *Buffer, size_t Count,
 
789
int my_block_write(register IO_CACHE *info, const unsigned char *Buffer, size_t Count,
798
790
                   my_off_t pos)
799
791
{
800
 
  size_t length_local;
 
792
  size_t length;
801
793
  int error=0;
802
794
 
803
795
  if (pos < info->pos_in_file)
806
798
    if (pos + Count <= info->pos_in_file)
807
799
      return (pwrite(info->file, Buffer, Count, pos) == 0);
808
800
    /* Write the part of the block that is before buffer */
809
 
    length_local= (uint32_t) (info->pos_in_file - pos);
810
 
    if (pwrite(info->file, Buffer, length_local, pos) == 0)
 
801
    length= (uint32_t) (info->pos_in_file - pos);
 
802
    if (pwrite(info->file, Buffer, length, pos) == 0)
811
803
      info->error= error= -1;
812
 
    Buffer+=length_local;
813
 
    pos+=  length_local;
814
 
    Count-= length_local;
 
804
    Buffer+=length;
 
805
    pos+=  length;
 
806
    Count-= length;
815
807
  }
816
808
 
817
809
  /* Check if we want to write inside the used part of the buffer.*/
818
 
  length_local= (size_t) (info->write_end - info->buffer);
819
 
  if (pos < info->pos_in_file + length_local)
 
810
  length= (size_t) (info->write_end - info->buffer);
 
811
  if (pos < info->pos_in_file + length)
820
812
  {
821
813
    size_t offset= (size_t) (pos - info->pos_in_file);
822
 
    length_local-=offset;
823
 
    if (length_local > Count)
824
 
      length_local=Count;
825
 
    memcpy(info->buffer+offset, Buffer, length_local);
826
 
    Buffer+=length_local;
827
 
    Count-= length_local;
828
 
    /* Fix length_local of buffer if the new data was larger */
829
 
    if (info->buffer+length_local > info->write_pos)
830
 
      info->write_pos=info->buffer+length_local;
 
814
    length-=offset;
 
815
    if (length > Count)
 
816
      length=Count;
 
817
    memcpy(info->buffer+offset, Buffer, length);
 
818
    Buffer+=length;
 
819
    Count-= length;
 
820
    /* Fix length of buffer if the new data was larger */
 
821
    if (info->buffer+length > info->write_pos)
 
822
      info->write_pos=info->buffer+length;
831
823
    if (!Count)
832
824
      return (error);
833
825
  }
841
833
 * @brief
842
834
 *   Flush write cache 
843
835
 */
844
 
int my_b_flush_io_cache(st_io_cache *info, int need_append_buffer_lock)
 
836
int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
845
837
{
846
 
  size_t length_local;
 
838
  size_t length;
847
839
  bool append_cache= false;
848
 
  my_off_t pos_in_file_local;
 
840
  my_off_t pos_in_file;
849
841
 
850
842
  if (info->type == WRITE_CACHE || append_cache)
851
843
  {
852
844
    if (info->file == -1)
853
845
    {
854
 
      if (info->real_open_cached_file())
 
846
      if (real_open_cached_file(info))
855
847
        return((info->error= -1));
856
848
    }
857
849
    lock_append_buffer(info, need_append_buffer_lock);
858
850
 
859
 
    if ((length_local=(size_t) (info->write_pos - info->write_buffer)))
 
851
    if ((length=(size_t) (info->write_pos - info->write_buffer)))
860
852
    {
861
 
      pos_in_file_local=info->pos_in_file;
 
853
      pos_in_file=info->pos_in_file;
862
854
      /*
863
855
        If we have append cache, we always open the file with
864
856
        O_APPEND which moves the pos to EOF automatically on every write
865
857
      */
866
858
      if (!append_cache && info->seek_not_done)
867
859
      {                                 /* File touched, do seek */
868
 
        if (lseek(info->file,pos_in_file_local,SEEK_SET) == MY_FILEPOS_ERROR)
 
860
        if (lseek(info->file,pos_in_file,SEEK_SET) == MY_FILEPOS_ERROR)
869
861
        {
870
862
          unlock_append_buffer(info, need_append_buffer_lock);
871
863
          return((info->error= -1));
874
866
          info->seek_not_done=0;
875
867
      }
876
868
      if (!append_cache)
877
 
        info->pos_in_file+=length_local;
 
869
        info->pos_in_file+=length;
878
870
      info->write_end= (info->write_buffer+info->buffer_length-
879
 
                        ((pos_in_file_local+length_local) & (IO_SIZE-1)));
 
871
                        ((pos_in_file+length) & (IO_SIZE-1)));
880
872
 
881
 
      if (my_write(info->file,info->write_buffer,length_local,
 
873
      if (my_write(info->file,info->write_buffer,length,
882
874
                   info->myflags | MY_NABP))
883
875
        info->error= -1;
884
876
      else
885
877
        info->error= 0;
886
878
      if (!append_cache)
887
879
      {
888
 
        set_if_bigger(info->end_of_file,(pos_in_file_local+length_local));
 
880
        set_if_bigger(info->end_of_file,(pos_in_file+length));
889
881
      }
890
882
      else
891
883
      {
912
904
 
913
905
/**
914
906
 * @brief
915
 
 *   Free an st_io_cache object
 
907
 *   Free an IO_CACHE object
916
908
 * 
917
909
 * @detail
918
910
 *   It's currently safe to call this if one has called init_io_cache()
919
911
 *   on the 'info' object, even if init_io_cache() failed.
920
912
 *   This function is also safe to call twice with the same handle.
921
913
 * 
922
 
 * @param info st_io_cache Handle to free
 
914
 * @param info IO_CACHE Handle to free
923
915
 * 
924
916
 * @retval 0 ok
925
917
 * @retval # Error
926
918
 */
927
 
int st_io_cache::end_io_cache()
 
919
int end_io_cache(IO_CACHE *info)
928
920
{
929
 
  int _error=0;
930
 
 
931
 
  if (pre_close)
932
 
  {
933
 
    (*pre_close)(this);
934
 
    pre_close= 0;
935
 
  }
936
 
  if (alloced_buffer)
937
 
  {
938
 
    if (type == READ_CACHE)
939
 
      global_read_buffer.sub(buffer_length);
940
 
    alloced_buffer=0;
941
 
    if (file != -1)                     /* File doesn't exist */
942
 
      _error= my_b_flush_io_cache(this, 1);
943
 
    free((unsigned char*) buffer);
944
 
    buffer=read_pos=(unsigned char*) 0;
945
 
  }
946
 
 
947
 
  return _error;
 
921
  int error=0;
 
922
  IO_CACHE_CALLBACK pre_close;
 
923
 
 
924
  if ((pre_close=info->pre_close))
 
925
  {
 
926
    (*pre_close)(info);
 
927
    info->pre_close= 0;
 
928
  }
 
929
  if (info->alloced_buffer)
 
930
  {
 
931
    info->alloced_buffer=0;
 
932
    if (info->file != -1)                       /* File doesn't exist */
 
933
      error= my_b_flush_io_cache(info,1);
 
934
    free((unsigned char*) info->buffer);
 
935
    info->buffer=info->read_pos=(unsigned char*) 0;
 
936
  }
 
937
 
 
938
  return(error);
948
939
} /* end_io_cache */
949
940
 
950
941
} /* namespace internal */