16 #include "myisam_priv.h"
17 #include <drizzled/util/test.h>
18 #include <sys/types.h>
24 using namespace drizzled;
27 static void mi_extra_keyflag(
MI_INFO *info,
enum ha_extra_function
function);
46 int mi_extra(
MI_INFO *info,
enum ha_extra_function
function,
void *extra_arg)
53 case HA_EXTRA_RESET_STATE:
55 info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR;
58 if (info->opt_flag & READ_CACHE_USED)
61 (
bool) (info->lock_type != F_UNLCK),
62 (
bool) test(info->update & HA_STATE_ROW_CHANGED));
64 info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
68 if (info->lock_type == F_UNLCK &&
69 (share->options & HA_OPTION_PACK_RECORD))
75 if (info->s->file_map)
77 if (info->opt_flag & WRITE_CACHE_USED)
79 info->opt_flag&= ~WRITE_CACHE_USED;
83 if (!(info->opt_flag &
84 (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
86 cache_size= (extra_arg ? *(uint32_t*) extra_arg :
87 internal::my_default_record_cache_size);
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))))
92 info->opt_flag|=READ_CACHE_USED;
93 info->update&= ~HA_STATE_ROW_CHANGED;
95 if (share->concurrent_insert)
96 info->rec_cache.end_of_file=info->state->data_file_length;
99 case HA_EXTRA_REINIT_CACHE:
100 if (info->opt_flag & READ_CACHE_USED)
103 (
bool) (info->lock_type != F_UNLCK),
104 (
bool) test(info->update & HA_STATE_ROW_CHANGED));
105 info->update&= ~HA_STATE_ROW_CHANGED;
106 if (share->concurrent_insert)
107 info->rec_cache.end_of_file=info->state->data_file_length;
110 case HA_EXTRA_WRITE_CACHE:
111 if (info->lock_type == F_UNLCK)
117 cache_size= (extra_arg ? *(uint32_t*) extra_arg :
118 internal::my_default_record_cache_size);
119 if (not (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) && !share->state.header.uniques)
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))))
126 info->opt_flag|=WRITE_CACHE_USED;
127 info->update&= ~(HA_STATE_ROW_CHANGED |
128 HA_STATE_WRITE_AT_END |
129 HA_STATE_EXTEND_BLOCK);
133 case HA_EXTRA_PREPARE_FOR_UPDATE:
134 if (info->s->data_file_type != DYNAMIC_RECORD)
137 case HA_EXTRA_NO_CACHE:
138 if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
140 info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
144 #if !defined(TARGET_OS_SOLARIS)
145 if (info->opt_flag & MEMMAP_USED)
146 madvise((
char*) share->file_map, share->state.state.data_file_length,
150 case HA_EXTRA_FLUSH_CACHE:
151 if (info->opt_flag & WRITE_CACHE_USED)
153 if ((error= info->rec_cache.flush()))
155 mi_print_error(info->s, HA_ERR_CRASHED);
156 mi_mark_crashed(info);
160 case HA_EXTRA_NO_READCHECK:
161 info->opt_flag&= ~READ_CHECK_USED;
163 case HA_EXTRA_READCHECK:
164 info->opt_flag|= READ_CHECK_USED;
166 case HA_EXTRA_KEYREAD:
167 case HA_EXTRA_REMEMBER_POS:
168 info->opt_flag |= REMEMBER_OLD_POS;
169 memmove(info->lastkey+share->base.max_key_length*2,
170 info->lastkey,info->lastkey_length);
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)
178 case HA_EXTRA_KEYREAD_CHANGE_POS:
179 info->opt_flag |= KEY_READ_USED;
180 info->read_record=_mi_read_key_record;
182 case HA_EXTRA_NO_KEYREAD:
183 case HA_EXTRA_RESTORE_POS:
184 if (info->opt_flag & REMEMBER_OLD_POS)
186 memmove(info->lastkey,
187 info->lastkey+share->base.max_key_length*2,
188 info->save_lastkey_length);
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;
194 info->read_record= share->read_record;
195 info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
197 case HA_EXTRA_NO_USER_CHANGE:
198 info->lock_type= F_EXTRA_LCK;
200 case HA_EXTRA_WAIT_LOCK:
203 case HA_EXTRA_NO_WAIT_LOCK:
204 info->lock_wait=MY_DONT_WAIT;
206 case HA_EXTRA_NO_KEYS:
207 if (info->lock_type == F_UNLCK)
212 if (mi_is_any_key_active(share->state.key_map))
216 for (i=0 ; i < share->base.keys ; i++,key++)
218 if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
220 mi_clear_key_active(share->state.key_map, i);
221 info->update|= HA_STATE_CHANGED;
227 share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
229 if (!share->global_changed)
231 share->global_changed=1;
232 share->state.open_count++;
235 share->state.state= *info->state;
236 error=mi_state_info_write(share->kfile,&share->state,1 | 2);
239 case HA_EXTRA_FORCE_REOPEN:
240 THR_LOCK_myisam.lock();
241 share->last_version= 0L;
242 THR_LOCK_myisam.unlock();
244 case HA_EXTRA_PREPARE_FOR_DROP:
245 THR_LOCK_myisam.lock();
246 share->last_version= 0L;
247 #ifdef __WIN__REMOVE_OBSOLETE_WORKAROUND
249 if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
251 info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
252 error=end_io_cache(&info->rec_cache);
254 if (info->lock_type != F_UNLCK && ! info->was_locked)
256 info->was_locked=info->lock_type;
257 if (mi_lock_database(info,F_UNLCK))
259 info->lock_type = F_UNLCK;
261 if (share->kfile >= 0)
262 _mi_decrement_open_count(info);
263 if (share->kfile >= 0 && internal::my_close(share->kfile,MYF(0)))
266 list<MI_INFO *>::iterator it= myisam_open_list.begin();
267 while (it != myisam_open_list.end())
270 if (tmpinfo->s == info->s)
272 if (tmpinfo->dfile >= 0 && internal::my_close(tmpinfo->dfile,MYF(0)))
281 THR_LOCK_myisam.unlock();
285 _mi_decrement_open_count(info);
287 if (share->not_flushed)
289 share->not_flushed=
false;
291 if (share->base.blobs)
292 mi_alloc_rec_buff(info, SIZE_MAX, &info->rec_buff);
294 case HA_EXTRA_NORMAL:
300 case HA_EXTRA_NO_ROWS:
301 if (!share->state.header.uniques)
302 info->opt_flag|= OPT_NO_ROWS;
304 case HA_EXTRA_PRELOAD_BUFFER_SIZE:
305 info->preload_buff_size= *((uint32_t *) extra_arg);
307 case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
308 case HA_EXTRA_CHANGE_KEY_TO_DUP:
309 mi_extra_keyflag(info,
function);
311 case HA_EXTRA_KEY_CACHE:
312 case HA_EXTRA_NO_KEY_CACHE:
324 static void mi_extra_keyflag(
MI_INFO *info,
enum ha_extra_function
function)
328 for (idx= 0; idx< info->s->base.keys; idx++)
331 case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
332 info->s->keyinfo[idx].flag|= HA_NOSAME;
334 case HA_EXTRA_CHANGE_KEY_TO_DUP:
335 info->s->keyinfo[idx].flag&= ~(HA_NOSAME);
355 if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
357 info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
360 if (share->base.blobs)
361 mi_alloc_rec_buff(info, SIZE_MAX, &info->rec_buff);
362 #if !defined(TARGET_OS_SOLARIS)
363 if (info->opt_flag & MEMMAP_USED)
364 madvise((
char*) share->file_map, share->state.state.data_file_length,
367 info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
370 info->last_search_keypage= info->lastpos= HA_OFFSET_ERROR;
371 info->page_changed= 1;
372 info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
373 HA_STATE_PREV_FOUND);