~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
/*
17
  Cashing of files with only does (sequential) read or writes of fixed-
18
  length records. A read isn't allowed to go over file-length. A read is ok
19
  if it ends at file-length and next read can try to read after file-length
20
  (and get a EOF-error).
21
  Possibly use of asyncronic io.
22
  macros for read and writes for faster io.
23
  Used instead of FILE when reading or writing whole files.
24
  This code makes mf_rec_cache obsolete (currently only used by ISAM)
25
  One can change info->pos_in_file to a higher value to skip bytes in file if
26
  also info->read_pos is set to info->read_end.
27
  If called through open_cached_file(), then the temporary file will
28
  only be created if a write exeeds the file buffer or if one calls
29
  my_b_flush_io_cache().
30
31
  If one uses SEQ_READ_APPEND, then two buffers are allocated, one for
32
  reading and another for writing.  Reads are first done from disk and
33
  then done from the write buffer.  This is an efficient way to read
34
  from a log file when one is writing to it at the same time.
35
  For this to work, the file has to be opened in append mode!
36
  Note that when one uses SEQ_READ_APPEND, one MUST write using
37
  my_b_append !  This is needed because we need to lock the mutex
38
  every time we access the write buffer.
39
40
TODO:
41
  When one SEQ_READ_APPEND and we are reading and writing at the same time,
42
  each time the write buffer gets full and it's written to disk, we will
43
  always do a disk read to read a part of the buffer from disk to the
44
  read buffer.
45
  This should be fixed so that when we do a my_b_flush_io_cache() and
46
  we have been reading the write buffer, we should transfer the rest of the
47
  write buffer to the read buffer before we start to reuse it.
48
*/
49
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
50
#include <config.h>
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
51
2241.4.14 by Stewart Smith
remove some includes from my_sys.h and instead only include where needed. This helps reduce the number of files that have to be rebuilt when you change some of the more widely included header files (such as the drizzled::identifier ones)
52
#include <drizzled/definitions.h>
53
#include <drizzled/error_t.h>
54
#include <drizzled/error.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
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>
1 by brian
clean slate
59
#include <errno.h>
492.1.7 by Monty Taylor
Moved test() to its own file.
60
#include <drizzled/util/test.h>
629.1.1 by Monty Taylor
More solaris fixes.
61
#include <stdlib.h>
1067.4.10 by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max.
62
#include <algorithm>
63
64
using namespace std;
629.1.1 by Monty Taylor
More solaris fixes.
65
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
66
namespace drizzled
67
{
68
namespace internal
69
{
70
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
71
static int _my_b_read(io_cache_st *info, unsigned char *Buffer, size_t Count);
72
static int _my_b_write(io_cache_st *info, const unsigned char *Buffer, size_t Count);
1165.1.147 by Stewart Smith
make _my_b_read() static to mysys/mf_iocache.cc
73
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
74
/**
75
 * @brief
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
76
 *   Lock appends for the io_cache_st if required (need_append_buffer_lock)   
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
77
 */
78
inline
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
79
static void lock_append_buffer(io_cache_st *, int )
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
80
{
81
}
82
83
/**
84
 * @brief
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
85
 *   Unlock appends for the io_cache_st if required (need_append_buffer_lock)   
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
86
 */
87
inline
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
88
static void unlock_append_buffer(io_cache_st *, int )
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
89
{
90
}
91
92
/**
93
 * @brief
94
 *   Round up to the nearest IO_SIZE boundary 
95
 */
96
inline
97
static size_t io_round_up(size_t x)
98
{
99
  return ((x+IO_SIZE-1) & ~(IO_SIZE-1));
100
}
101
102
/**
103
 * @brief
104
 *   Round down to the nearest IO_SIZE boundary   
105
 */
106
inline
107
static size_t io_round_dn(size_t x)
108
{
109
  return (x & ~(IO_SIZE-1));
110
}
111
112
113
/**
114
 * @brief 
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
115
 *   Setup internal pointers inside io_cache_st
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
116
 * 
117
 * @details
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
118
 *   This is called on automatically on init or reinit of io_cache_st
119
 *   It must be called externally if one moves or copies an io_cache_st object.
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
120
 * 
121
 * @param info Cache handler to setup
122
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
123
void io_cache_st::setup_io_cache()
1 by brian
clean slate
124
{
125
  /* Ensure that my_b_tell() and my_b_bytes_in_cache works */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
126
  if (type == WRITE_CACHE)
1 by brian
clean slate
127
  {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
128
    current_pos= &write_pos;
129
    current_end= &write_end;
1 by brian
clean slate
130
  }
131
  else
132
  {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
133
    current_pos= &read_pos;
134
    current_end= &read_end;
1 by brian
clean slate
135
  }
136
}
137
138
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
139
void io_cache_st::init_functions()
1 by brian
clean slate
140
{
141
  switch (type) {
142
  case READ_NET:
143
    /*
144
      Must be initialized by the caller. The problem is that
145
      _my_b_net_read has to be defined in sql directory because of
146
      the dependency on THD, and therefore cannot be visible to
147
      programs that link against mysys but know nothing about THD, such
148
      as myisamchk
149
    */
150
    break;
151
  default:
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
152
    read_function = _my_b_read;
153
    write_function = _my_b_write;
1 by brian
clean slate
154
  }
155
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
156
  setup_io_cache();
1 by brian
clean slate
157
}
158
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
159
/**
160
 * @brief
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
161
 *   Initialize an io_cache_st object
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
162
 *
163
 * @param file File that should be associated with the handler
164
 *                 If == -1 then real_open_cached_file() will be called when it's time to open file.
165
 * @param cachesize Size of buffer to allocate for read/write
166
 *                      If == 0 then use my_default_record_cache_size
167
 * @param type Type of cache
168
 * @param seek_offset Where cache should start reading/writing
169
 * @param use_async_io Set to 1 if we should use async_io (if avaiable)
170
 * @param cache_myflags Bitmap of different flags
171
                            MY_WME | MY_FAE | MY_NABP | MY_FNABP | MY_DONT_CHECK_FILESIZE
172
 * 
173
 * @retval 0 success
174
 * @retval # error
175
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
176
int io_cache_st::init_io_cache(int file_arg, size_t cachesize,
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
177
                               enum cache_type type_arg, my_off_t seek_offset,
178
                               bool use_async_io, myf cache_myflags)
1 by brian
clean slate
179
{
180
  size_t min_cache;
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
181
  off_t pos;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
182
  my_off_t end_of_file_local= ~(my_off_t) 0;
1 by brian
clean slate
183
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
184
  file= file_arg;
185
  type= TYPE_NOT_SET;	    /* Don't set it until mutex are created */
186
  pos_in_file= seek_offset;
187
  pre_close = pre_read = post_read = 0;
188
  arg = 0;
189
  alloced_buffer = 0;
190
  buffer=0;
191
  seek_not_done= 0;
1 by brian
clean slate
192
193
  if (file >= 0)
194
  {
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
195
    pos= lseek(file, 0, SEEK_CUR);
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
196
    if ((pos == MY_FILEPOS_ERROR) && (errno == ESPIPE))
1 by brian
clean slate
197
    {
198
      /*
199
         This kind of object doesn't support seek() or tell(). Don't set a
200
         flag that will make us again try to seek() later and fail.
201
      */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
202
      seek_not_done= 0;
1 by brian
clean slate
203
      /*
204
        Additionally, if we're supposed to start somewhere other than the
205
        the beginning of whatever this file is, then somebody made a bad
206
        assumption.
207
      */
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
208
      assert(seek_offset == 0);
1 by brian
clean slate
209
    }
210
    else
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
211
      seek_not_done= test(seek_offset != (my_off_t)pos);
1 by brian
clean slate
212
  }
213
214
  if (!cachesize && !(cachesize= my_default_record_cache_size))
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
215
    return 1;				/* No cache requested */
1 by brian
clean slate
216
  min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
217
  if (type_arg == READ_CACHE)
1 by brian
clean slate
218
  {						/* Assume file isn't growing */
219
    if (!(cache_myflags & MY_DONT_CHECK_FILESIZE))
220
    {
221
      /* Calculate end of file to avoid allocating oversized buffers */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
222
      end_of_file_local=lseek(file,0L,SEEK_END);
1 by brian
clean slate
223
      /* Need to reset seek_not_done now that we just did a seek. */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
224
      seek_not_done= end_of_file_local == seek_offset ? 0 : 1;
225
      if (end_of_file_local < seek_offset)
226
	end_of_file_local=seek_offset;
1 by brian
clean slate
227
      /* Trim cache size if the file is very small */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
228
      if ((my_off_t) cachesize > end_of_file_local-seek_offset+IO_SIZE*2-1)
1 by brian
clean slate
229
      {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
230
	cachesize= (size_t) (end_of_file_local-seek_offset)+IO_SIZE*2-1;
1 by brian
clean slate
231
	use_async_io=0;				/* No need to use async */
232
      }
233
    }
234
  }
235
  cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
236
  if (type_arg != READ_NET && type_arg != WRITE_NET)
1 by brian
clean slate
237
  {
238
    /* Retry allocating memory in smaller blocks until we get one */
239
    cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
2318.6.1 by Olaf van der Spek
Refactor
240
    if (cachesize < min_cache)
241
      cachesize = min_cache;
242
    size_t buffer_block= cachesize;
243
    if (type_arg == READ_CACHE && not global_read_buffer.add(buffer_block))
1 by brian
clean slate
244
    {
2318.6.1 by Olaf van der Spek
Refactor
245
      my_error(ER_OUT_OF_GLOBAL_READMEMORY, MYF(ME_ERROR+ME_WAITTANG));
246
      return 2;
1 by brian
clean slate
247
    }
2318.6.1 by Olaf van der Spek
Refactor
248
249
    buffer= (unsigned char*) malloc(buffer_block);
250
    write_buffer=buffer;
251
    alloced_buffer= true;
1 by brian
clean slate
252
  }
253
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
254
  read_length=buffer_length=cachesize;
255
  myflags=cache_myflags & ~(MY_NABP | MY_FNABP);
256
  request_pos= read_pos= write_pos = buffer;
1 by brian
clean slate
257
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
258
  if (type_arg == WRITE_CACHE)
259
    write_end=
260
      buffer+buffer_length- (seek_offset & (IO_SIZE-1));
1 by brian
clean slate
261
  else
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
262
    read_end=buffer;		/* Nothing in cache */
1 by brian
clean slate
263
264
  /* End_of_file may be changed by user later */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
265
  end_of_file= end_of_file_local;
266
  error= 0;
267
  type= type_arg;
268
  init_functions();
269
  return 0;
1 by brian
clean slate
270
}						/* init_io_cache */
271
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
272
/**
273
 * @brief 
274
 *   Reset the cache
275
 * 
276
 * @detail
277
 *   Use this to reset cache to re-start reading or to change the type 
278
 *   between READ_CACHE <-> WRITE_CACHE
279
 *   If we are doing a reinit of a cache where we have the start of the file
280
 *   in the cache, we are reusing this memory without flushing it to disk.
281
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
282
bool io_cache_st::reinit_io_cache(enum cache_type type_arg,
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
283
                                  my_off_t seek_offset,
2241.4.29 by Stewart Smith
remove HAVE_AIOWAIT ifdefs around the place - it turns out this wouldn't have compiled anyway (my_filename() was called but is never defined). I think this is all old code that was meant to use Solaris aiowait - certainly doesn't work now.
284
                                  bool,
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
285
                                  bool clear_cache)
1 by brian
clean slate
286
{
287
  /* One can't do reinit with the following types */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
288
  assert(type_arg != READ_NET && type != READ_NET &&
289
	      type_arg != WRITE_NET && type != WRITE_NET);
1 by brian
clean slate
290
291
  /* If the whole file is in memory, avoid flushing to disk */
292
  if (! clear_cache &&
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
293
      seek_offset >= pos_in_file &&
294
      seek_offset <= my_b_tell(this))
1 by brian
clean slate
295
  {
296
    /* Reuse current buffer without flushing it to disk */
481 by Brian Aker
Remove all of uchar.
297
    unsigned char *pos;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
298
    if (type == WRITE_CACHE && type_arg == READ_CACHE)
1 by brian
clean slate
299
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
300
      read_end=write_pos;
301
      end_of_file=my_b_tell(this);
1 by brian
clean slate
302
      /*
303
        Trigger a new seek only if we have a valid
304
        file handle.
305
      */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
306
      seek_not_done= (file != -1);
1 by brian
clean slate
307
    }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
308
    else if (type_arg == WRITE_CACHE)
1 by brian
clean slate
309
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
310
      if (type == READ_CACHE)
1 by brian
clean slate
311
      {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
312
	write_end=write_buffer+buffer_length;
313
	seek_not_done=1;
1 by brian
clean slate
314
      }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
315
      end_of_file = ~(my_off_t) 0;
1 by brian
clean slate
316
    }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
317
    pos=request_pos+(seek_offset-pos_in_file);
318
    if (type_arg == WRITE_CACHE)
319
      write_pos=pos;
1 by brian
clean slate
320
    else
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
321
      read_pos= pos;
1 by brian
clean slate
322
  }
323
  else
324
  {
325
    /*
326
      If we change from WRITE_CACHE to READ_CACHE, assume that everything
327
      after the current positions should be ignored
328
    */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
329
    if (type == WRITE_CACHE && type_arg == READ_CACHE)
330
      end_of_file=my_b_tell(this);
1 by brian
clean slate
331
    /* flush cache if we want to reuse it */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
332
    if (!clear_cache && my_b_flush_io_cache(this, 1))
333
      return 1;
334
    pos_in_file=seek_offset;
1 by brian
clean slate
335
    /* Better to do always do a seek */
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
336
    seek_not_done=1;
337
    request_pos=read_pos=write_pos=buffer;
338
    if (type_arg == READ_CACHE)
1 by brian
clean slate
339
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
340
      read_end=buffer;		/* Nothing in cache */
1 by brian
clean slate
341
    }
342
    else
343
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
344
      write_end=(buffer + buffer_length -
1 by brian
clean slate
345
		       (seek_offset & (IO_SIZE-1)));
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
346
      end_of_file= ~(my_off_t) 0;
1 by brian
clean slate
347
    }
348
  }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
349
  type= type_arg;
350
  error=0;
351
  init_functions();
1 by brian
clean slate
352
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
353
  return 0;
1 by brian
clean slate
354
} /* reinit_io_cache */
355
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
356
/**
357
 * @brief 
358
 *   Read buffered.
359
 * 
360
 * @detail
361
 *   This function is only called from the my_b_read() macro when there
362
 *   aren't enough characters in the buffer to satisfy the request.
363
 *
364
 * WARNING
365
 *   When changing this function, be careful with handling file offsets
366
 *   (end-of_file, pos_in_file). Do not cast them to possibly smaller
367
 *   types than my_off_t unless you can be sure that their value fits.
368
 *   Same applies to differences of file offsets.
369
 *
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
370
 * @param info io_cache_st pointer @param Buffer Buffer to retrieve count bytes
1578.4.3 by Brian Aker
Remove dead code in IO_CACHE for shared access.
371
 * from file @param Count Number of bytes to read into Buffer
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
372
 * 
373
 * @retval 0 We succeeded in reading all data
374
 * @retval 1 Error: can't read requested characters
375
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
376
static int _my_b_read(io_cache_st *info, unsigned char *Buffer, size_t Count)
1 by brian
clean slate
377
{
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
378
  size_t length_local,diff_length,left_length, max_length;
379
  my_off_t pos_in_file_local;
1 by brian
clean slate
380
381
  if ((left_length= (size_t) (info->read_end-info->read_pos)))
382
  {
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
383
    assert(Count >= left_length);	/* User is not using my_b_read() */
1 by brian
clean slate
384
    memcpy(Buffer,info->read_pos, left_length);
385
    Buffer+=left_length;
386
    Count-=left_length;
387
  }
388
389
  /* pos_in_file always point on where info->buffer was read */
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
390
  pos_in_file_local=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
1 by brian
clean slate
391
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
392
  /*
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
393
    Whenever a function which operates on io_cache_st flushes/writes
394
    some part of the io_cache_st to disk it will set the property
1 by brian
clean slate
395
    "seek_not_done" to indicate this to other functions operating
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
396
    on the io_cache_st.
1 by brian
clean slate
397
  */
398
  if (info->seek_not_done)
399
  {
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
400
    if ((lseek(info->file,pos_in_file_local,SEEK_SET) != MY_FILEPOS_ERROR))
1 by brian
clean slate
401
    {
402
      /* No error, reset seek_not_done flag. */
403
      info->seek_not_done= 0;
404
    }
405
    else
406
    {
407
      /*
408
        If the seek failed and the error number is ESPIPE, it is because
409
        info->file is a pipe or socket or FIFO.  We never should have tried
410
        to seek on that.  See Bugs#25807 and #22828 for more info.
411
      */
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
412
      assert(errno != ESPIPE);
1 by brian
clean slate
413
      info->error= -1;
2318.6.77 by Olaf van der Spek
Refactor
414
      return 1;
1 by brian
clean slate
415
    }
416
  }
417
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
418
  diff_length= (size_t) (pos_in_file_local & (IO_SIZE-1));
1 by brian
clean slate
419
  if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
420
  {					/* Fill first intern buffer */
421
    size_t read_length;
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
422
    if (info->end_of_file <= pos_in_file_local)
1 by brian
clean slate
423
    {					/* End of file */
424
      info->error= (int) left_length;
2318.6.77 by Olaf van der Spek
Refactor
425
      return 1;
1 by brian
clean slate
426
    }
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
427
    length_local=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
428
    if ((read_length= my_read(info->file,Buffer, length_local, info->myflags)) != length_local)
1 by brian
clean slate
429
    {
430
      info->error= (read_length == (size_t) -1 ? -1 :
431
		    (int) (read_length+left_length));
2318.6.77 by Olaf van der Spek
Refactor
432
      return 1;
1 by brian
clean slate
433
    }
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
434
    Count-= length_local;
435
    Buffer+= length_local;
436
    pos_in_file_local+= length_local;
437
    left_length+= length_local;
1 by brian
clean slate
438
    diff_length=0;
439
  }
440
441
  max_length= info->read_length-diff_length;
442
  if (info->type != READ_FIFO &&
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
443
      max_length > (info->end_of_file - pos_in_file_local))
444
    max_length= (size_t) (info->end_of_file - pos_in_file_local);
1 by brian
clean slate
445
  if (!max_length)
446
  {
447
    if (Count)
448
    {
1126.13.8 by Joe Daly
Fix up spacing in various files, also had new style casts in several places
449
      info->error= static_cast<int>(left_length);	/* We only got this many char */
2318.6.77 by Olaf van der Spek
Refactor
450
      return 1;
1 by brian
clean slate
451
    }
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
452
     length_local=0;				/* Didn't read any chars */
1 by brian
clean slate
453
  }
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
454
  else if (( length_local= my_read(info->file,info->buffer, max_length,
1 by brian
clean slate
455
                            info->myflags)) < Count ||
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
456
	    length_local == (size_t) -1)
1 by brian
clean slate
457
  {
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
458
    if ( length_local != (size_t) -1)
459
      memcpy(Buffer, info->buffer,  length_local);
460
    info->pos_in_file= pos_in_file_local;
461
    info->error=  length_local == (size_t) -1 ? -1 : (int) ( length_local+left_length);
1 by brian
clean slate
462
    info->read_pos=info->read_end=info->buffer;
2318.6.77 by Olaf van der Spek
Refactor
463
    return 1;
1 by brian
clean slate
464
  }
465
  info->read_pos=info->buffer+Count;
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
466
  info->read_end=info->buffer+ length_local;
467
  info->pos_in_file=pos_in_file_local;
1 by brian
clean slate
468
  memcpy(Buffer, info->buffer, Count);
2318.6.58 by Olaf van der Spek
Refactor
469
  return 0;
1 by brian
clean slate
470
}
471
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
472
/**
473
 * @brief
474
 *   Read one byte when buffer is empty
475
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
476
int _my_b_get(io_cache_st *info)
1 by brian
clean slate
477
{
481 by Brian Aker
Remove all of uchar.
478
  unsigned char buff;
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
479
  IO_CACHE_CALLBACK pre_read,post_read;
480
1 by brian
clean slate
481
  if ((pre_read = info->pre_read))
482
    (*pre_read)(info);
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
483
1 by brian
clean slate
484
  if ((*(info)->read_function)(info,&buff,1))
485
    return my_b_EOF;
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
486
1 by brian
clean slate
487
  if ((post_read = info->post_read))
488
    (*post_read)(info);
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
489
481 by Brian Aker
Remove all of uchar.
490
  return (int) (unsigned char) buff;
1 by brian
clean slate
491
}
492
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
493
/**
494
 * @brief
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
495
 *   Write a byte buffer to io_cache_st and flush to disk if io_cache_st is full.
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
496
 *
497
 * @retval -1 On error; errno contains error code.
498
 * @retval 0 On success
499
 * @retval 1 On error on write
500
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
501
int _my_b_write(io_cache_st *info, const unsigned char *Buffer, size_t Count)
1 by brian
clean slate
502
{
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
503
  size_t rest_length,length_local;
1 by brian
clean slate
504
505
  if (info->pos_in_file+info->buffer_length > info->end_of_file)
506
  {
1831.1.1 by Andrew Hutchings
Fix new warnings in GCC 4.5
507
    errno=EFBIG;
1 by brian
clean slate
508
    return info->error = -1;
509
  }
510
511
  rest_length= (size_t) (info->write_end - info->write_pos);
512
  memcpy(info->write_pos,Buffer,(size_t) rest_length);
513
  Buffer+=rest_length;
514
  Count-=rest_length;
515
  info->write_pos+=rest_length;
516
517
  if (my_b_flush_io_cache(info,1))
518
    return 1;
519
  if (Count >= IO_SIZE)
520
  {					/* Fill first intern buffer */
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
521
    length_local=Count & (size_t) ~(IO_SIZE-1);
1 by brian
clean slate
522
    if (info->seek_not_done)
523
    {
524
      /*
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
525
        Whenever a function which operates on io_cache_st flushes/writes
526
        some part of the io_cache_st to disk it will set the property
1 by brian
clean slate
527
        "seek_not_done" to indicate this to other functions operating
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
528
        on the io_cache_st.
1 by brian
clean slate
529
      */
656.1.39 by Monty Taylor
Removed my_seek, my_tell, my_fwrite, my_fseek.
530
      if (lseek(info->file,info->pos_in_file,SEEK_SET))
1 by brian
clean slate
531
      {
532
        info->error= -1;
533
        return (1);
534
      }
535
      info->seek_not_done=0;
536
    }
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
537
    if (my_write(info->file, Buffer, length_local, info->myflags | MY_NABP))
1 by brian
clean slate
538
      return info->error= -1;
539
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
540
    Count-=length_local;
541
    Buffer+=length_local;
542
    info->pos_in_file+=length_local;
1 by brian
clean slate
543
  }
544
  memcpy(info->write_pos,Buffer,(size_t) Count);
545
  info->write_pos+=Count;
546
  return 0;
547
}
548
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
549
/**
550
 * @brief
551
 *   Write a block to disk where part of the data may be inside the record buffer.
552
 *   As all write calls to the data goes through the cache,
553
 *   we will never get a seek over the end of the buffer.
554
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
555
int my_block_write(io_cache_st *info, const unsigned char *Buffer, size_t Count,
1241.13.1 by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys.
556
		   my_off_t pos)
1 by brian
clean slate
557
{
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
558
  size_t length_local;
1 by brian
clean slate
559
  int error=0;
560
561
  if (pos < info->pos_in_file)
562
  {
563
    /* Of no overlap, write everything without buffering */
564
    if (pos + Count <= info->pos_in_file)
32 by Brian Aker
More cleanup on pread()
565
      return (pwrite(info->file, Buffer, Count, pos) == 0);
1 by brian
clean slate
566
    /* Write the part of the block that is before buffer */
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
567
    length_local= (uint32_t) (info->pos_in_file - pos);
568
    if (pwrite(info->file, Buffer, length_local, pos) == 0)
1 by brian
clean slate
569
      info->error= error= -1;
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
570
    Buffer+=length_local;
571
    pos+=  length_local;
572
    Count-= length_local;
1 by brian
clean slate
573
  }
574
575
  /* Check if we want to write inside the used part of the buffer.*/
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
576
  length_local= (size_t) (info->write_end - info->buffer);
577
  if (pos < info->pos_in_file + length_local)
1 by brian
clean slate
578
  {
579
    size_t offset= (size_t) (pos - info->pos_in_file);
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
580
    length_local-=offset;
581
    if (length_local > Count)
582
      length_local=Count;
583
    memcpy(info->buffer+offset, Buffer, length_local);
584
    Buffer+=length_local;
585
    Count-= length_local;
586
    /* Fix length_local of buffer if the new data was larger */
587
    if (info->buffer+length_local > info->write_pos)
588
      info->write_pos=info->buffer+length_local;
1 by brian
clean slate
589
    if (!Count)
590
      return (error);
591
  }
592
  /* Write at the end of the current buffer; This is the normal case */
593
  if (_my_b_write(info, Buffer, Count))
594
    error= -1;
595
  return error;
596
}
597
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
598
/**
599
 * @brief
600
 *   Flush write cache 
601
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
602
int my_b_flush_io_cache(io_cache_st *info, int need_append_buffer_lock)
1 by brian
clean slate
603
{
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
604
  size_t length_local;
1578.4.4 by Brian Aker
Remove pthread mutex that is no longer used (since IO_CACHE is single
605
  bool append_cache= false;
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
606
  my_off_t pos_in_file_local;
1 by brian
clean slate
607
608
  if (info->type == WRITE_CACHE || append_cache)
609
  {
610
    if (info->file == -1)
611
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
612
      if (info->real_open_cached_file())
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
613
	return((info->error= -1));
1 by brian
clean slate
614
    }
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
615
    lock_append_buffer(info, need_append_buffer_lock);
1 by brian
clean slate
616
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
617
    if ((length_local=(size_t) (info->write_pos - info->write_buffer)))
1 by brian
clean slate
618
    {
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
619
      pos_in_file_local=info->pos_in_file;
1 by brian
clean slate
620
      /*
621
	If we have append cache, we always open the file with
622
	O_APPEND which moves the pos to EOF automatically on every write
623
      */
624
      if (!append_cache && info->seek_not_done)
625
      {					/* File touched, do seek */
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
626
	if (lseek(info->file,pos_in_file_local,SEEK_SET) == MY_FILEPOS_ERROR)
1 by brian
clean slate
627
	{
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
628
	  unlock_append_buffer(info, need_append_buffer_lock);
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
629
	  return((info->error= -1));
1 by brian
clean slate
630
	}
631
	if (!append_cache)
632
	  info->seek_not_done=0;
633
      }
634
      if (!append_cache)
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
635
	info->pos_in_file+=length_local;
1 by brian
clean slate
636
      info->write_end= (info->write_buffer+info->buffer_length-
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
637
			((pos_in_file_local+length_local) & (IO_SIZE-1)));
1 by brian
clean slate
638
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
639
      if (my_write(info->file,info->write_buffer,length_local,
1 by brian
clean slate
640
		   info->myflags | MY_NABP))
641
	info->error= -1;
642
      else
643
	info->error= 0;
644
      if (!append_cache)
645
      {
1909.1.2 by Brian Aker
Additional io_cache encapsulation.
646
        set_if_bigger(info->end_of_file,(pos_in_file_local+length_local));
1 by brian
clean slate
647
      }
648
      else
649
      {
650
	info->end_of_file+=(info->write_pos-info->append_read_pos);
1241.13.1 by Monty Taylor
Put my_off_t back... but this time localized only to myisam and mysys.
651
	my_off_t tell_ret= lseek(info->file, 0, SEEK_CUR);
632.1.15 by Monty
Finished fixing my_tell.
652
	assert(info->end_of_file == tell_ret);
1 by brian
clean slate
653
      }
654
655
      info->append_read_pos=info->write_pos=info->write_buffer;
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
656
      unlock_append_buffer(info, need_append_buffer_lock);
51.3.22 by Jay Pipes
Final round of removal of DBUG in mysys/, including Makefile
657
      return(info->error);
1 by brian
clean slate
658
    }
659
  }
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
660
  unlock_append_buffer(info, need_append_buffer_lock);
2318.6.58 by Olaf van der Spek
Refactor
661
  return 0;
1 by brian
clean slate
662
}
663
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
664
/**
665
 * @brief
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
666
 *   Free an io_cache_st object
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
667
 * 
668
 * @detail
669
 *   It's currently safe to call this if one has called init_io_cache()
670
 *   on the 'info' object, even if init_io_cache() failed.
671
 *   This function is also safe to call twice with the same handle.
672
 * 
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
673
 * @param info io_cache_st Handle to free
1507.1.1 by Sanders King
Changes to quote.cc and mf_iocache.cc: convert macros to inline functions; reformat comments to suit Doxygen
674
 * 
675
 * @retval 0 ok
676
 * @retval # Error
677
 */
2296.1.2 by Brian Aker
A couple of additional fixes for the IO Cache name,
678
int io_cache_st::end_io_cache()
1 by brian
clean slate
679
{
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
680
  int _error=0;
681
682
  if (pre_close)
683
  {
684
    (*pre_close)(this);
685
    pre_close= 0;
686
  }
687
  if (alloced_buffer)
688
  {
689
    if (type == READ_CACHE)
690
      global_read_buffer.sub(buffer_length);
691
    alloced_buffer=0;
692
    if (file != -1)			/* File doesn't exist */
693
      _error= my_b_flush_io_cache(this, 1);
694
    free((unsigned char*) buffer);
695
    buffer=read_pos=(unsigned char*) 0;
696
  }
697
698
  return _error;
1 by brian
clean slate
699
} /* end_io_cache */
700
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
701
} /* namespace internal */
702
} /* namespace drizzled */