~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2005 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
1130.3.28 by Monty Taylor
Moved heapdef.h and myisamdef.h to *_priv.h for easier filtering for include guard check.
16
#include "myisam_priv.h"
492.3.27 by Lee
merge latest changes from the trunk and changes to get drizzle building on Soalris 10 (SPARC)
17
#include <drizzled/util/test.h>
18
#include <sys/types.h>
1 by brian
clean slate
19
#include <sys/mman.h>
20
612.2.13 by Monty Taylor
Work on removing global.h from headers that should be installed.
21
#include <string.h>
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
22
#include <algorithm>
612.2.13 by Monty Taylor
Work on removing global.h from headers that should be installed.
23
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
24
using namespace drizzled;
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
25
using namespace std;
26
1 by brian
clean slate
27
static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function);
28
29
30
/*
31
  Set options and buffers to optimize table handling
32
33
  SYNOPSIS
34
    mi_extra()
35
    info	open table
36
    function	operation
304 by Brian Aker
ulong cleanup, remove log code from myisam.
37
    extra_arg	Pointer to extra argument (normally pointer to uint32_t)
1 by brian
clean slate
38
    		Used when function is one of:
39
		HA_EXTRA_WRITE_CACHE
40
		HA_EXTRA_CACHE
41
  RETURN VALUES
42
    0  ok
43
    #  error
44
*/
45
46
int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
47
{
48
  int error=0;
304 by Brian Aker
ulong cleanup, remove log code from myisam.
49
  uint32_t cache_size;
1 by brian
clean slate
50
  MYISAM_SHARE *share=info->s;
51
52
  switch (function) {
53
  case HA_EXTRA_RESET_STATE:		/* Reset state (don't free buffers) */
54
    info->lastinx= 0;			/* Use first index as def */
55
    info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR;
56
    info->page_changed=1;
57
					/* Next/prev gives first/last */
58
    if (info->opt_flag & READ_CACHE_USED)
59
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
60
      info->rec_cache.reinit_io_cache(internal::READ_CACHE,0,
61
                                      (bool) (info->lock_type != F_UNLCK),
62
                                      (bool) test(info->update & HA_STATE_ROW_CHANGED));
1 by brian
clean slate
63
    }
64
    info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
65
		   HA_STATE_PREV_FOUND);
66
    break;
67
  case HA_EXTRA_CACHE:
68
    if (info->lock_type == F_UNLCK &&
69
	(share->options & HA_OPTION_PACK_RECORD))
70
    {
71
      error=1;			/* Not possibly if not locked */
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
72
      errno=EACCES;
1 by brian
clean slate
73
      break;
74
    }
75
    if (info->s->file_map) /* Don't use cache if mmap */
76
      break;
77
    if (info->opt_flag & WRITE_CACHE_USED)
78
    {
79
      info->opt_flag&= ~WRITE_CACHE_USED;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
80
      if ((error= info->rec_cache.end_io_cache()))
1 by brian
clean slate
81
	break;
82
    }
83
    if (!(info->opt_flag &
84
	  (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
85
    {
304 by Brian Aker
ulong cleanup, remove log code from myisam.
86
      cache_size= (extra_arg ? *(uint32_t*) extra_arg :
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
87
		   internal::my_default_record_cache_size);
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
88
      if (!(info->rec_cache.init_io_cache(info->dfile, (uint) min((uint32_t)info->state->data_file_length+1, cache_size),
89
                                          internal::READ_CACHE,0L,(bool) (info->lock_type != F_UNLCK),
90
                                          MYF(share->write_flag & MY_WAIT_IF_FULL))))
1 by brian
clean slate
91
      {
92
	info->opt_flag|=READ_CACHE_USED;
93
	info->update&= ~HA_STATE_ROW_CHANGED;
94
      }
95
      if (share->concurrent_insert)
96
	info->rec_cache.end_of_file=info->state->data_file_length;
97
    }
98
    break;
99
  case HA_EXTRA_REINIT_CACHE:
100
    if (info->opt_flag & READ_CACHE_USED)
101
    {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
102
      info->rec_cache.reinit_io_cache(internal::READ_CACHE,info->nextpos,
154 by Brian Aker
Removed oddball types in my_global.h
103
		      (bool) (info->lock_type != F_UNLCK),
104
		      (bool) test(info->update & HA_STATE_ROW_CHANGED));
1 by brian
clean slate
105
      info->update&= ~HA_STATE_ROW_CHANGED;
106
      if (share->concurrent_insert)
107
	info->rec_cache.end_of_file=info->state->data_file_length;
108
    }
109
    break;
110
  case HA_EXTRA_WRITE_CACHE:
111
    if (info->lock_type == F_UNLCK)
112
    {
113
      error=1;			/* Not possibly if not locked */
114
      break;
115
    }
116
304 by Brian Aker
ulong cleanup, remove log code from myisam.
117
    cache_size= (extra_arg ? *(uint32_t*) extra_arg :
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
118
		 internal::my_default_record_cache_size);
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
119
    if (not (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) && !share->state.header.uniques)
120
    {
121
      if (not (info->rec_cache.init_io_cache(info->dfile, cache_size,
122
                                             internal::WRITE_CACHE,info->state->data_file_length,
123
                                             (bool) (info->lock_type != F_UNLCK),
124
                                             MYF(share->write_flag & MY_WAIT_IF_FULL))))
1 by brian
clean slate
125
      {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
126
        info->opt_flag|=WRITE_CACHE_USED;
127
        info->update&= ~(HA_STATE_ROW_CHANGED |
1 by brian
clean slate
128
			 HA_STATE_WRITE_AT_END |
129
			 HA_STATE_EXTEND_BLOCK);
130
      }
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
131
    }
1 by brian
clean slate
132
    break;
133
  case HA_EXTRA_PREPARE_FOR_UPDATE:
134
    if (info->s->data_file_type != DYNAMIC_RECORD)
135
      break;
136
    /* Remove read/write cache if dynamic rows */
137
  case HA_EXTRA_NO_CACHE:
138
    if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
139
    {
140
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
141
      error= info->rec_cache.end_io_cache();
1 by brian
clean slate
142
      /* Sergei will insert full text index caching here */
143
    }
1192.3.43 by Monty Taylor
Removed many, many checks for functions that do not need to be checked.
144
#if !defined(TARGET_OS_SOLARIS)
1 by brian
clean slate
145
    if (info->opt_flag & MEMMAP_USED)
146
      madvise((char*) share->file_map, share->state.state.data_file_length,
147
              MADV_RANDOM);
148
#endif
149
    break;
150
  case HA_EXTRA_FLUSH_CACHE:
151
    if (info->opt_flag & WRITE_CACHE_USED)
152
    {
153
      if ((error=flush_io_cache(&info->rec_cache)))
154
      {
155
        mi_print_error(info->s, HA_ERR_CRASHED);
156
	mi_mark_crashed(info);			/* Fatal error found */
157
      }
158
    }
159
    break;
160
  case HA_EXTRA_NO_READCHECK:
161
    info->opt_flag&= ~READ_CHECK_USED;		/* No readcheck */
162
    break;
163
  case HA_EXTRA_READCHECK:
164
    info->opt_flag|= READ_CHECK_USED;
165
    break;
166
  case HA_EXTRA_KEYREAD:			/* Read only keys to record */
167
  case HA_EXTRA_REMEMBER_POS:
168
    info->opt_flag |= REMEMBER_OLD_POS;
629.3.4 by Kristian Nielsen
Take Mats'es changes from bmove()->memcpy(), and fix all of them to be
169
    memmove(info->lastkey+share->base.max_key_length*2,
170
            info->lastkey,info->lastkey_length);
1 by brian
clean slate
171
    info->save_update=	info->update;
172
    info->save_lastinx= info->lastinx;
173
    info->save_lastpos= info->lastpos;
174
    info->save_lastkey_length=info->lastkey_length;
175
    if (function == HA_EXTRA_REMEMBER_POS)
176
      break;
177
    /* fall through */
178
  case HA_EXTRA_KEYREAD_CHANGE_POS:
179
    info->opt_flag |= KEY_READ_USED;
180
    info->read_record=_mi_read_key_record;
181
    break;
182
  case HA_EXTRA_NO_KEYREAD:
183
  case HA_EXTRA_RESTORE_POS:
184
    if (info->opt_flag & REMEMBER_OLD_POS)
185
    {
629.3.4 by Kristian Nielsen
Take Mats'es changes from bmove()->memcpy(), and fix all of them to be
186
      memmove(info->lastkey,
187
              info->lastkey+share->base.max_key_length*2,
188
              info->save_lastkey_length);
1 by brian
clean slate
189
      info->update=	info->save_update | HA_STATE_WRITTEN;
190
      info->lastinx=	info->save_lastinx;
191
      info->lastpos=	info->save_lastpos;
192
      info->lastkey_length=info->save_lastkey_length;
193
    }
194
    info->read_record=	share->read_record;
195
    info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
196
    break;
197
  case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */
198
    info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
199
    break;
200
  case HA_EXTRA_WAIT_LOCK:
201
    info->lock_wait=0;
202
    break;
203
  case HA_EXTRA_NO_WAIT_LOCK:
204
    info->lock_wait=MY_DONT_WAIT;
205
    break;
206
  case HA_EXTRA_NO_KEYS:
207
    if (info->lock_type == F_UNLCK)
208
    {
209
      error=1;					/* Not possibly if not lock */
210
      break;
211
    }
212
    if (mi_is_any_key_active(share->state.key_map))
213
    {
214
      MI_KEYDEF *key=share->keyinfo;
482 by Brian Aker
Remove uint.
215
      uint32_t i;
1 by brian
clean slate
216
      for (i=0 ; i < share->base.keys ; i++,key++)
217
      {
218
        if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
219
        {
220
          mi_clear_key_active(share->state.key_map, i);
221
          info->update|= HA_STATE_CHANGED;
222
        }
223
      }
224
225
      if (!share->changed)
226
      {
227
	share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
228
	share->changed=1;			/* Update on close */
229
	if (!share->global_changed)
230
	{
231
	  share->global_changed=1;
232
	  share->state.open_count++;
233
	}
234
      }
235
      share->state.state= *info->state;
236
      error=mi_state_info_write(share->kfile,&share->state,1 | 2);
237
    }
238
    break;
239
  case HA_EXTRA_FORCE_REOPEN:
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
240
    THR_LOCK_myisam.lock();
1 by brian
clean slate
241
    share->last_version= 0L;			/* Impossible version */
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
242
    THR_LOCK_myisam.unlock();
1 by brian
clean slate
243
    break;
244
  case HA_EXTRA_PREPARE_FOR_DROP:
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
245
    THR_LOCK_myisam.lock();
1 by brian
clean slate
246
    share->last_version= 0L;			/* Impossible version */
247
#ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND
248
    /* Close the isam and data files as Win32 can't drop an open table */
249
    if (flush_key_blocks(share->key_cache, share->kfile,
250
			 (function == HA_EXTRA_FORCE_REOPEN ?
251
			  FLUSH_RELEASE : FLUSH_IGNORE_CHANGED)))
252
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
253
      error=errno;
1 by brian
clean slate
254
      share->changed=1;
255
      mi_print_error(info->s, HA_ERR_CRASHED);
256
      mi_mark_crashed(info);			/* Fatal error found */
257
    }
258
    if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
259
    {
260
      info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
261
      error=end_io_cache(&info->rec_cache);
262
    }
263
    if (info->lock_type != F_UNLCK && ! info->was_locked)
264
    {
265
      info->was_locked=info->lock_type;
266
      if (mi_lock_database(info,F_UNLCK))
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
267
	error=errno;
1 by brian
clean slate
268
      info->lock_type = F_UNLCK;
269
    }
270
    if (share->kfile >= 0)
271
      _mi_decrement_open_count(info);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
272
    if (share->kfile >= 0 && internal::my_close(share->kfile,MYF(0)))
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
273
      error=errno;
1 by brian
clean slate
274
    {
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
275
      list<MI_INFO *>::iterator it= myisam_open_list.begin();
276
      while (it != myisam_open_list.end())
1 by brian
clean slate
277
      {
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
278
	MI_INFO *tmpinfo= *it;
1 by brian
clean slate
279
	if (tmpinfo->s == info->s)
280
	{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
281
	  if (tmpinfo->dfile >= 0 && internal::my_close(tmpinfo->dfile,MYF(0)))
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
282
	    error = errno;
1 by brian
clean slate
283
	  tmpinfo->dfile= -1;
284
	}
916.1.32 by Padraig O'Sullivan
Refactoring MyISAM storage engine again based on LIST replacement with
285
        ++it;
1 by brian
clean slate
286
      }
287
    }
288
    share->kfile= -1;				/* Files aren't open anymore */
289
#endif
1703.1.3 by Brian Aker
Replace pthread mutex with boost based one for myisam.
290
    THR_LOCK_myisam.unlock();
1 by brian
clean slate
291
    break;
292
  case HA_EXTRA_FLUSH:
293
    if (!share->temporary)
1689.2.15 by Brian Aker
Encapsulate the key cache object in myisam.
294
      flush_key_blocks(share->getKeyCache(), share->kfile, FLUSH_KEEP);
1 by brian
clean slate
295
#ifdef HAVE_PWRITE
296
    _mi_decrement_open_count(info);
297
#endif
298
    if (share->not_flushed)
299
    {
1689.2.29 by Brian Aker
Remove sync() call (just temp tables).
300
      share->not_flushed= false;
1 by brian
clean slate
301
    }
302
    if (share->base.blobs)
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
303
      mi_alloc_rec_buff(info, SIZE_MAX, &info->rec_buff);
1 by brian
clean slate
304
    break;
305
  case HA_EXTRA_NORMAL:				/* Theese isn't in use */
306
    info->quick_mode=0;
307
    break;
308
  case HA_EXTRA_QUICK:
309
    info->quick_mode=1;
310
    break;
311
  case HA_EXTRA_NO_ROWS:
312
    if (!share->state.header.uniques)
313
      info->opt_flag|= OPT_NO_ROWS;
314
    break;
315
  case HA_EXTRA_PRELOAD_BUFFER_SIZE:
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
316
    info->preload_buff_size= *((uint32_t *) extra_arg);
1 by brian
clean slate
317
    break;
318
  case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
319
  case HA_EXTRA_CHANGE_KEY_TO_DUP:
320
    mi_extra_keyflag(info, function);
321
    break;
322
  case HA_EXTRA_KEY_CACHE:
323
  case HA_EXTRA_NO_KEY_CACHE:
324
  default:
325
    break;
326
  }
304 by Brian Aker
ulong cleanup, remove log code from myisam.
327
51.1.99 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
328
  return(error);
1 by brian
clean slate
329
} /* mi_extra */
330
331
332
/*
333
    Start/Stop Inserting Duplicates Into a Table, WL#1648.
334
 */
335
static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function)
336
{
482 by Brian Aker
Remove uint.
337
  uint32_t  idx;
1 by brian
clean slate
338
339
  for (idx= 0; idx< info->s->base.keys; idx++)
340
  {
341
    switch (function) {
342
    case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
343
      info->s->keyinfo[idx].flag|= HA_NOSAME;
344
      break;
345
    case HA_EXTRA_CHANGE_KEY_TO_DUP:
346
      info->s->keyinfo[idx].flag&= ~(HA_NOSAME);
347
      break;
348
    default:
349
      break;
350
    }
351
  }
352
}
353
354
355
int mi_reset(MI_INFO *info)
356
{
357
  int error= 0;
358
  MYISAM_SHARE *share=info->s;
359
  /*
360
    Free buffers and reset the following flags:
361
    EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
362
363
    If the row buffer cache is large (for dynamic tables), reduce it
364
    to save memory.
365
  */
366
  if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
367
  {
368
    info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
369
    error= info->rec_cache.end_io_cache();
1 by brian
clean slate
370
  }
371
  if (share->base.blobs)
1816.2.4 by Monty Taylor
Cleaned up a bunch more warnings.
372
    mi_alloc_rec_buff(info, SIZE_MAX, &info->rec_buff);
1192.3.43 by Monty Taylor
Removed many, many checks for functions that do not need to be checked.
373
#if !defined(TARGET_OS_SOLARIS)
1 by brian
clean slate
374
  if (info->opt_flag & MEMMAP_USED)
375
    madvise((char*) share->file_map, share->state.state.data_file_length,
376
            MADV_RANDOM);
377
#endif
378
  info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
379
  info->quick_mode=0;
380
  info->lastinx= 0;			/* Use first index as def */
381
  info->last_search_keypage= info->lastpos= HA_OFFSET_ERROR;
382
  info->page_changed= 1;
383
  info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
384
                 HA_STATE_PREV_FOUND);
51.1.99 by Jay Pipes
Removed/replaced DBUG symbols and TRUE/FALSE
385
  return(error);
1 by brian
clean slate
386
}