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