00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #include <config.h>
00021
00022 #include "myisam.h"
00023 #include "myisampack.h"
00024 #include <drizzled/tree.h>
00025 #include <drizzled/internal/my_pthread.h>
00026 #include <drizzled/thr_lock.h>
00027 #include <drizzled/common.h>
00028 #include <drizzled/enum.h>
00029 #include <drizzled/dynamic_array.h>
00030
00031 #include <assert.h>
00032 #include <fcntl.h>
00033 #include <string.h>
00034 #include <list>
00035
00036 #include <boost/thread/mutex.hpp>
00037
00038 #if defined(my_write)
00039 #undef my_write
00040 #endif
00041
00042
00043 static const uint32_t KEY_CACHE_SIZE= 8*1024*1024;
00044
00045
00046 static const uint32_t KEY_CACHE_BLOCK_SIZE= 1024;
00047
00048 typedef struct st_mi_status_info
00049 {
00050 drizzled::ha_rows records;
00051 drizzled::ha_rows del;
00052 drizzled::internal::my_off_t empty;
00053 drizzled::internal::my_off_t key_empty;
00054 drizzled::internal::my_off_t key_file_length;
00055 drizzled::internal::my_off_t data_file_length;
00056 drizzled::internal::ha_checksum checksum;
00057 } MI_STATUS_INFO;
00058
00059 typedef struct st_mi_state_info
00060 {
00061 struct {
00062 unsigned char file_version[4];
00063 unsigned char options[2];
00064 unsigned char header_length[2];
00065 unsigned char state_info_length[2];
00066 unsigned char base_info_length[2];
00067 unsigned char base_pos[2];
00068 unsigned char key_parts[2];
00069 unsigned char unique_key_parts[2];
00070 unsigned char keys;
00071 unsigned char uniques;
00072 unsigned char language;
00073 unsigned char max_block_size_index;
00074 unsigned char fulltext_keys;
00075 unsigned char not_used;
00076 } header;
00077
00078 MI_STATUS_INFO state;
00079 drizzled::ha_rows split;
00080 drizzled::internal::my_off_t dellink;
00081 uint64_t auto_increment;
00082 ulong process;
00083 ulong unique;
00084 ulong update_count;
00085 ulong status;
00086 ulong *rec_per_key_part;
00087 drizzled::internal::my_off_t *key_root;
00088 drizzled::internal::my_off_t *key_del;
00089 drizzled::internal::my_off_t rec_per_key_rows;
00090
00091 ulong sec_index_changed;
00092 ulong sec_index_used;
00093 uint64_t key_map;
00094 drizzled::internal::ha_checksum checksum;
00095 ulong version;
00096 time_t create_time;
00097 time_t recover_time;
00098 time_t check_time;
00099 uint sortkey;
00100 uint32_t open_count;
00101 uint8_t changed;
00102
00103
00104 uint32_t state_diff_length;
00105 uint state_length;
00106 ulong *key_info;
00107 } MI_STATE_INFO;
00108
00109 #define MI_STATE_INFO_SIZE (24+14*8+7*4+2*2+8)
00110 #define MI_STATE_KEY_SIZE 8
00111 #define MI_STATE_KEYBLOCK_SIZE 8
00112 #define MI_STATE_KEYSEG_SIZE 4
00113 #define MI_STATE_EXTRA_SIZE ((MI_MAX_KEY+MI_MAX_KEY_BLOCK_SIZE)*MI_STATE_KEY_SIZE + MI_MAX_KEY*MI_MAX_KEY_SEG*MI_STATE_KEYSEG_SIZE)
00114 #define MI_KEYDEF_SIZE (2+ 5*2)
00115 #define MI_UNIQUEDEF_SIZE (2+1+1)
00116 #define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
00117 #define MI_COLUMNDEF_SIZE (2*3+1)
00118 #define MI_BASE_INFO_SIZE (5*8 + 8*4 + 4 + 4*2 + 16)
00119 #define MI_INDEX_BLOCK_MARGIN 16
00120
00121 typedef struct st_mi_base_info
00122 {
00123 drizzled::internal::my_off_t keystart;
00124 drizzled::internal::my_off_t max_data_file_length;
00125 drizzled::internal::my_off_t max_key_file_length;
00126 drizzled::internal::my_off_t margin_key_file_length;
00127 drizzled::ha_rows records,reloc;
00128 ulong mean_row_length;
00129 ulong reclength;
00130 ulong pack_reclength;
00131 ulong min_pack_length;
00132 ulong max_pack_length;
00133 ulong min_block_length;
00134 ulong fields,
00135 pack_fields;
00136 uint32_t rec_reflength;
00137 uint32_t key_reflength;
00138 uint32_t keys;
00139 uint32_t auto_key;
00140 uint32_t blobs;
00141 uint32_t pack_bits;
00142 uint32_t max_key_block_length;
00143 uint32_t max_key_length;
00144
00145 uint32_t extra_alloc_bytes;
00146 uint32_t extra_alloc_procent;
00147
00148 uint32_t raid_type,raid_chunks;
00149 uint32_t raid_chunksize;
00150
00151 uint32_t key_parts,all_key_parts;
00152 } MI_BASE_INFO;
00153
00154
00155
00156
00157 typedef struct st_mi_blob
00158 {
00159 ulong offset;
00160 uint32_t pack_length;
00161 ulong length;
00162 } MI_BLOB;
00163
00164
00165 typedef struct st_mi_isam_pack {
00166 ulong header_length;
00167 uint32_t ref_length;
00168 unsigned char version;
00169 } MI_PACK;
00170
00171 #define MAX_NONMAPPED_INSERTS 1000
00172
00173 namespace drizzled { class Session; }
00174
00175 typedef struct st_mi_isam_share {
00176 MI_STATE_INFO state;
00177 MI_BASE_INFO base;
00178 MI_KEYDEF ft2_keyinfo;
00179 MI_KEYDEF *keyinfo;
00180 MI_UNIQUEDEF *uniqueinfo;
00181 HA_KEYSEG *keyparts;
00182 drizzled::MI_COLUMNDEF *rec;
00183 MI_PACK pack;
00184 MI_BLOB *blobs;
00185 std::list<drizzled::Session *> *in_use;
00186 char *unique_file_name;
00187 char *data_file_name,
00188 *index_file_name;
00189 unsigned char *file_map;
00190 private:
00191 drizzled::KEY_CACHE key_cache;
00192 public:
00193 drizzled::KEY_CACHE *getKeyCache()
00194 {
00195 return &key_cache;
00196 }
00197
00198 void setKeyCache();
00199
00200 MI_DECODE_TREE *decode_trees;
00201 uint16_t *decode_tables;
00202 int (*read_record)(struct st_myisam_info*, drizzled::internal::my_off_t, unsigned char*);
00203 int (*write_record)(struct st_myisam_info*, const unsigned char*);
00204 int (*update_record)(struct st_myisam_info*, drizzled::internal::my_off_t, const unsigned char*);
00205 int (*delete_record)(struct st_myisam_info*);
00206 int (*read_rnd)(struct st_myisam_info*, unsigned char*, drizzled::internal::my_off_t, bool);
00207 int (*compare_record)(struct st_myisam_info*, const unsigned char *);
00208
00209 drizzled::internal::ha_checksum (*calc_checksum)(struct st_myisam_info*, const unsigned char *);
00210 int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
00211 const unsigned char *record, drizzled::internal::my_off_t pos);
00212 size_t (*file_read)(MI_INFO *, unsigned char *, size_t, drizzled::internal::my_off_t, drizzled::myf);
00213 size_t (*file_write)(MI_INFO *, const unsigned char *, size_t, drizzled::internal::my_off_t, drizzled::myf);
00214 ulong this_process;
00215 ulong last_process;
00216 ulong last_version;
00217 uint64_t options;
00218 ulong min_pack_length;
00219 ulong max_pack_length;
00220 ulong state_diff_length;
00221 uint rec_reflength;
00222 uint32_t unique_name_length;
00223 int kfile;
00224 int data_file;
00225 int mode;
00226 uint reopen;
00227 uint w_locks,r_locks,tot_locks;
00228 uint blocksize;
00229 drizzled::myf write_flag;
00230 enum drizzled::data_file_type data_file_type;
00231
00232 bool is_log_table;
00233
00234 bool changed,
00235 global_changed,
00236 not_flushed,
00237 temporary,delay_key_write,
00238 concurrent_insert;
00239 drizzled::internal::my_off_t mmaped_length;
00240 uint32_t nonmmaped_inserts;
00241
00242 } MYISAM_SHARE;
00243
00244
00245 typedef uint32_t mi_bit_type;
00246
00247 typedef struct st_mi_bit_buff {
00248 mi_bit_type current_byte;
00249 uint32_t bits;
00250 unsigned char *pos,*end,*blob_pos,*blob_end;
00251 uint32_t error;
00252 } MI_BIT_BUFF;
00253
00254
00255 typedef bool (*index_cond_func_t)(void *param);
00256
00257 struct st_myisam_info {
00258 MYISAM_SHARE *s;
00259 MI_STATUS_INFO *state,save_state;
00260 MI_BLOB *blobs;
00261 MI_BIT_BUFF bit_buff;
00262
00263 drizzled::TREE *bulk_insert;
00264 drizzled::Session *in_use;
00265 char *filename;
00266 unsigned char *buff,
00267 *lastkey,*lastkey2;
00268 unsigned char *first_mbr_key;
00269 unsigned char *rec_buff;
00270 unsigned char *int_keypos,
00271 *int_maxpos;
00272 uint32_t int_nod_flag;
00273 uint32_t int_keytree_version;
00274 int (*read_record)(struct st_myisam_info*, drizzled::internal::my_off_t, unsigned char*);
00275 ulong this_unique;
00276 ulong last_unique;
00277 ulong this_loop;
00278 ulong last_loop;
00279 drizzled::internal::my_off_t lastpos,
00280 nextpos;
00281 drizzled::internal::my_off_t save_lastpos;
00282 drizzled::internal::my_off_t pos;
00283 drizzled::internal::my_off_t last_keypage;
00284 drizzled::internal::my_off_t last_search_keypage;
00285 drizzled::internal::my_off_t dupp_key_pos;
00286 drizzled::internal::ha_checksum checksum;
00287
00288
00289 ulong packed_length,blob_length;
00290 int dfile;
00291 uint32_t opt_flag;
00292 uint32_t update;
00293 int lastinx;
00294 uint lastkey_length;
00295 uint last_rkey_length;
00296 enum drizzled::ha_rkey_function last_key_func;
00297 uint32_t save_lastkey_length;
00298 uint32_t pack_key_length;
00299 uint16_t last_used_keyseg;
00300 int errkey;
00301 int lock_type;
00302 int tmp_lock_type;
00303 uint data_changed;
00304 uint save_update;
00305 int save_lastinx;
00306 drizzled::internal::IO_CACHE rec_cache;
00307 uint32_t preload_buff_size;
00308 drizzled::myf lock_wait;
00309 bool was_locked;
00310 bool append_insert_at_end;
00311 bool quick_mode;
00312 bool page_changed;
00313 bool buff_used;
00314 bool once_flags;
00315
00316 index_cond_func_t index_cond_func;
00317 void *index_cond_func_arg;
00318 drizzled::THR_LOCK_DATA lock;
00319 unsigned char *rtree_recursion_state;
00320 int rtree_recursion_depth;
00321 };
00322
00323 typedef struct st_buffpek {
00324 off_t file_pos;
00325 unsigned char *base,*key;
00326 drizzled::ha_rows count;
00327 ulong mem_count;
00328 ulong max_keys;
00329 } BUFFPEK;
00330
00331 typedef struct st_mi_sort_param
00332 {
00333 pthread_t thr;
00334 drizzled::internal::IO_CACHE read_cache, tempfile, tempfile_for_exceptions;
00335 drizzled::DYNAMIC_ARRAY buffpek;
00336 MI_BIT_BUFF bit_buff;
00337
00338
00339
00340
00341
00342 uint64_t unique[MI_MAX_KEY_SEG+1];
00343 uint64_t notnull[MI_MAX_KEY_SEG+1];
00344
00345 drizzled::internal::my_off_t pos,max_pos,filepos,start_recpos;
00346 uint32_t key, key_length,real_key_length,sortbuff_size;
00347 uint32_t maxbuffers, keys, find_length, sort_keys_length;
00348 bool fix_datafile, master;
00349 bool calc_checksum;
00350 MI_KEYDEF *keyinfo;
00351 HA_KEYSEG *seg;
00352 SORT_INFO *sort_info;
00353 unsigned char **sort_keys;
00354 unsigned char *rec_buff;
00355 void *wordlist, *wordptr;
00356 drizzled::memory::Root wordroot;
00357 unsigned char *record;
00358 int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
00359 int (*key_read)(struct st_mi_sort_param *,void *);
00360 int (*key_write)(struct st_mi_sort_param *, const void *);
00361 void (*lock_in_memory)(MI_CHECK *);
00362 int (*write_keys)(struct st_mi_sort_param *, register unsigned char **,
00363 uint32_t , struct st_buffpek *, drizzled::internal::IO_CACHE *);
00364 unsigned int (*read_to_buffer)(drizzled::internal::IO_CACHE *,struct st_buffpek *, uint);
00365 int (*write_key)(struct st_mi_sort_param *, drizzled::internal::IO_CACHE *,unsigned char *,
00366 uint, uint);
00367 } MI_SORT_PARAM;
00368
00369
00370
00371 #define USE_WHOLE_KEY MI_MAX_KEY_BUFF*2
00372 #define F_EXTRA_LCK -1
00373
00374
00375 #define MEMMAP_USED 32
00376 #define REMEMBER_OLD_POS 64
00377
00378 #define WRITEINFO_UPDATE_KEYFILE 1
00379 #define WRITEINFO_NO_UNLOCK 2
00380
00381
00382 #define USE_PACKED_KEYS 1
00383 #define RRND_PRESERVE_LASTINX 2
00384
00385
00386
00387 #define STATE_CHANGED 1
00388 #define STATE_CRASHED 2
00389 #define STATE_CRASHED_ON_REPAIR 4
00390 #define STATE_NOT_ANALYZED 8
00391 #define STATE_NOT_OPTIMIZED_KEYS 16
00392 #define STATE_NOT_SORTED_PAGES 32
00393
00394
00395
00396 #define READING_NEXT 1
00397 #define READING_HEADER 2
00398
00399
00400 #define mi_getint(x) ((uint) mi_uint2korr(x) & 32767)
00401 #define mi_putint(x,y,nod) { uint16_t boh=(nod ? (uint16_t) 32768 : 0) + (uint16_t) (y);\
00402 mi_int2store(x,boh); }
00403 #define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
00404 #define mi_report_crashed(A, B) _mi_report_crashed((A), (B), __FILE__, __LINE__)
00405 #define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
00406 mi_report_crashed((x), 0); \
00407 }while(0)
00408 #define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
00409 STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
00410 (x)->update|= HA_STATE_CHANGED; \
00411 }while(0)
00412 #define mi_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
00413 #define mi_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
00414 #define mi_print_error(SHARE, ERRNO) \
00415 mi_report_error((ERRNO), (SHARE)->index_file_name)
00416
00417
00418
00419 #define store_key_length(key,length) \
00420 { if ((length) < 255) \
00421 { *(key)=(length); } \
00422 else \
00423 { *(key)=255; mi_int2store((key)+1,(length)); } \
00424 }
00425
00426 #define get_key_full_length(length,key) \
00427 { if ((unsigned char) *(key) != 255) \
00428 length= ((uint) (unsigned char) *((key)++))+1; \
00429 else \
00430 { length=mi_uint2korr((key)+1)+3; (key)+=3; } \
00431 }
00432
00433 #define get_key_full_length_rdonly(length,key) \
00434 { if ((unsigned char) *(key) != 255) \
00435 length= ((uint) (unsigned char) *((key)))+1; \
00436 else \
00437 { length=mi_uint2korr((key)+1)+3; } \
00438 }
00439
00440 #define get_pack_length(length) ((length) >= 255 ? 3 : 1)
00441
00442 #define MI_MIN_BLOCK_LENGTH 20
00443 #define MI_EXTEND_BLOCK_LENGTH 20
00444 #define MI_SPLIT_LENGTH ((MI_EXTEND_BLOCK_LENGTH+4)*2)
00445 #define MI_MAX_DYN_BLOCK_HEADER 20
00446 #define MI_BLOCK_INFO_HEADER_LENGTH 20
00447 #define MI_DYN_DELETE_BLOCK_HEADER 20
00448 #define MI_DYN_MAX_BLOCK_LENGTH ((1L << 24)-4L)
00449 #define MI_DYN_MAX_ROW_LENGTH (MI_DYN_MAX_BLOCK_LENGTH - MI_SPLIT_LENGTH)
00450 #define MI_DYN_ALIGN_SIZE 4
00451 #define MI_MAX_DYN_HEADER_BYTE 13
00452 #define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
00453 #define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32_t))
00454
00455 #define MEMMAP_EXTRA_MARGIN 7
00456
00457 #define PACK_TYPE_SELECTED 1
00458 #define PACK_TYPE_SPACE_FIELDS 2
00459 #define PACK_TYPE_ZERO_FILL 4
00460 #define MI_FOUND_WRONG_KEY 32738
00461
00462 #define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
00463 #define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
00464 #define MI_MAX_KEYPTR_SIZE 5
00465 #define MI_MIN_KEYBLOCK_LENGTH 50
00466
00467 #define MI_MIN_SIZE_BULK_INSERT_TREE 16384
00468 #define MI_MIN_ROWS_TO_USE_BULK_INSERT 100
00469 #define MI_MIN_ROWS_TO_DISABLE_INDEXES 100
00470 #define MI_MIN_ROWS_TO_USE_WRITE_CACHE 10
00471
00472
00473
00474 #define MI_UNIQUE_HASH_TYPE HA_KEYTYPE_ULONG_INT
00475 #define mi_unique_store(A,B) mi_int4store((A),(B))
00476
00477 extern boost::mutex THR_LOCK_myisam;
00478
00479
00480
00481 extern std::list<MI_INFO *> myisam_open_list;
00482 extern unsigned char myisam_file_magic[], myisam_pack_file_magic[];
00483 extern uint32_t myisam_read_vec[], myisam_readnext_vec[];
00484 extern uint32_t myisam_quick_table_bits;
00485 extern ulong myisam_pid;
00486
00487
00488
00489 typedef struct st_mi_s_param
00490 {
00491 uint ref_length,key_length,
00492 n_ref_length,
00493 n_length,
00494 totlength,
00495 part_of_prev_key,prev_length,pack_marker;
00496 unsigned char *key, *prev_key,*next_key_pos;
00497 bool store_not_null;
00498 } MI_KEY_PARAM;
00499
00500
00501
00502 extern int _mi_read_dynamic_record(MI_INFO *info,drizzled::internal::my_off_t filepos,unsigned char *buf);
00503 extern int _mi_write_dynamic_record(MI_INFO*, const unsigned char*);
00504 extern int _mi_update_dynamic_record(MI_INFO*, drizzled::internal::my_off_t, const unsigned char*);
00505 extern int _mi_delete_dynamic_record(MI_INFO *info);
00506 extern int _mi_cmp_dynamic_record(MI_INFO *info,const unsigned char *record);
00507 extern int _mi_read_rnd_dynamic_record(MI_INFO *, unsigned char *,drizzled::internal::my_off_t, bool);
00508 extern int _mi_write_blob_record(MI_INFO*, const unsigned char*);
00509 extern int _mi_update_blob_record(MI_INFO*, drizzled::internal::my_off_t, const unsigned char*);
00510 extern int _mi_read_static_record(MI_INFO *info, drizzled::internal::my_off_t filepos,unsigned char *buf);
00511 extern int _mi_write_static_record(MI_INFO*, const unsigned char*);
00512 extern int _mi_update_static_record(MI_INFO*, drizzled::internal::my_off_t, const unsigned char*);
00513 extern int _mi_delete_static_record(MI_INFO *info);
00514 extern int _mi_cmp_static_record(MI_INFO *info,const unsigned char *record);
00515 extern int _mi_read_rnd_static_record(MI_INFO*, unsigned char *,drizzled::internal::my_off_t, bool);
00516 extern int _mi_ck_write(MI_INFO *info,uint32_t keynr,unsigned char *key,uint32_t length);
00517 extern int _mi_ck_real_write_btree(MI_INFO *info, MI_KEYDEF *keyinfo,
00518 unsigned char *key, uint32_t key_length,
00519 drizzled::internal::my_off_t *root, uint32_t comp_flag);
00520 extern int _mi_enlarge_root(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key, drizzled::internal::my_off_t *root);
00521 extern int _mi_insert(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
00522 unsigned char *anc_buff,unsigned char *key_pos,unsigned char *key_buff,
00523 unsigned char *father_buff, unsigned char *father_keypos,
00524 drizzled::internal::my_off_t father_page, bool insert_last);
00525 extern int _mi_split_page(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
00526 unsigned char *buff,unsigned char *key_buff, bool insert_last);
00527 extern unsigned char *_mi_find_half_pos(uint32_t nod_flag,MI_KEYDEF *keyinfo,unsigned char *page,
00528 unsigned char *key,uint32_t *return_key_length,
00529 unsigned char **after_key);
00530 extern int _mi_calc_static_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
00531 unsigned char *key_pos, unsigned char *org_key,
00532 unsigned char *key_buff,
00533 unsigned char *key, MI_KEY_PARAM *s_temp);
00534 extern int _mi_calc_var_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
00535 unsigned char *key_pos, unsigned char *org_key,
00536 unsigned char *key_buff,
00537 unsigned char *key, MI_KEY_PARAM *s_temp);
00538 extern int _mi_calc_var_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
00539 unsigned char *key_pos, unsigned char *org_key,
00540 unsigned char *prev_key,
00541 unsigned char *key, MI_KEY_PARAM *s_temp);
00542 extern int _mi_calc_bin_pack_key_length(MI_KEYDEF *keyinfo,uint32_t nod_flag,
00543 unsigned char *key_pos,unsigned char *org_key,
00544 unsigned char *prev_key,
00545 unsigned char *key, MI_KEY_PARAM *s_temp);
00546 void _mi_store_static_key(MI_KEYDEF *keyinfo, unsigned char *key_pos,
00547 MI_KEY_PARAM *s_temp);
00548 void _mi_store_var_pack_key(MI_KEYDEF *keyinfo, unsigned char *key_pos,
00549 MI_KEY_PARAM *s_temp);
00550 #ifdef NOT_USED
00551 void _mi_store_pack_key(MI_KEYDEF *keyinfo, unsigned char *key_pos,
00552 MI_KEY_PARAM *s_temp);
00553 #endif
00554 void _mi_store_bin_pack_key(MI_KEYDEF *keyinfo, unsigned char *key_pos,
00555 MI_KEY_PARAM *s_temp);
00556
00557 extern int _mi_ck_delete(MI_INFO *info,uint32_t keynr,unsigned char *key,uint32_t key_length);
00558 int _mi_readinfo(MI_INFO *info,int lock_flag,int check_keybuffer);
00559 extern int _mi_writeinfo(MI_INFO *info,uint32_t options);
00560 extern int _mi_test_if_changed(MI_INFO *info);
00561 extern int _mi_mark_file_changed(MI_INFO *info);
00562 extern int _mi_decrement_open_count(MI_INFO *info);
00563 extern int _mi_check_index(MI_INFO *info,int inx);
00564 extern int _mi_search(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,uint32_t key_len,
00565 uint32_t nextflag,drizzled::internal::my_off_t pos);
00566 extern int _mi_bin_search(struct st_myisam_info *info,MI_KEYDEF *keyinfo,
00567 unsigned char *page,unsigned char *key,uint32_t key_len,uint32_t comp_flag,
00568 unsigned char * *ret_pos,unsigned char *buff, bool *was_last_key);
00569 extern int _mi_seq_search(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *page,
00570 unsigned char *key,uint32_t key_len,uint32_t comp_flag,
00571 unsigned char **ret_pos,unsigned char *buff, bool *was_last_key);
00572 extern int _mi_prefix_search(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *page,
00573 unsigned char *key,uint32_t key_len,uint32_t comp_flag,
00574 unsigned char **ret_pos,unsigned char *buff, bool *was_last_key);
00575 extern drizzled::internal::my_off_t _mi_kpos(uint32_t nod_flag,unsigned char *after_key);
00576 extern void _mi_kpointer(MI_INFO *info,unsigned char *buff,drizzled::internal::my_off_t pos);
00577 extern drizzled::internal::my_off_t _mi_dpos(MI_INFO *info, uint32_t nod_flag,unsigned char *after_key);
00578 extern drizzled::internal::my_off_t _mi_rec_pos(MYISAM_SHARE *info, unsigned char *ptr);
00579 void _mi_dpointer(MI_INFO *info, unsigned char *buff,drizzled::internal::my_off_t pos);
00580 extern uint32_t _mi_get_static_key(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char * *page,
00581 unsigned char *key);
00582 extern uint32_t _mi_get_pack_key(MI_KEYDEF *keyinfo,uint32_t nod_flag,unsigned char * *page,
00583 unsigned char *key);
00584 extern uint32_t _mi_get_binary_pack_key(MI_KEYDEF *keyinfo, uint32_t nod_flag,
00585 unsigned char **page_pos, unsigned char *key);
00586 extern unsigned char *_mi_get_last_key(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *keypos,
00587 unsigned char *lastkey,unsigned char *endpos,
00588 uint32_t *return_key_length);
00589 extern unsigned char *_mi_get_key(MI_INFO *info, MI_KEYDEF *keyinfo, unsigned char *page,
00590 unsigned char *key, unsigned char *keypos, uint32_t *return_key_length);
00591 extern uint32_t _mi_keylength(MI_KEYDEF *keyinfo,unsigned char *key);
00592 extern uint32_t _mi_keylength_part(MI_KEYDEF *keyinfo, register unsigned char *key,
00593 HA_KEYSEG *end);
00594 extern unsigned char *_mi_move_key(MI_KEYDEF *keyinfo,unsigned char *to,unsigned char *from);
00595 extern int _mi_search_next(MI_INFO *info,MI_KEYDEF *keyinfo,unsigned char *key,
00596 uint32_t key_length,uint32_t nextflag,drizzled::internal::my_off_t pos);
00597 extern int _mi_search_first(MI_INFO *info,MI_KEYDEF *keyinfo,drizzled::internal::my_off_t pos);
00598 extern int _mi_search_last(MI_INFO *info,MI_KEYDEF *keyinfo,drizzled::internal::my_off_t pos);
00599 extern unsigned char *_mi_fetch_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,drizzled::internal::my_off_t page,
00600 int level,unsigned char *buff,int return_buffer);
00601 extern int _mi_write_keypage(MI_INFO *info,MI_KEYDEF *keyinfo,drizzled::internal::my_off_t page,
00602 int level, unsigned char *buff);
00603 extern int _mi_dispose(MI_INFO *info,MI_KEYDEF *keyinfo,drizzled::internal::my_off_t pos,
00604 int level);
00605 extern drizzled::internal::my_off_t _mi_new(MI_INFO *info,MI_KEYDEF *keyinfo,int level);
00606 extern uint32_t _mi_make_key(MI_INFO *info,uint32_t keynr,unsigned char *key,
00607 const unsigned char *record,drizzled::internal::my_off_t filepos);
00608 extern uint32_t _mi_pack_key(register MI_INFO *info, uint32_t keynr, unsigned char *key,
00609 unsigned char *old, drizzled::key_part_map keypart_map,
00610 HA_KEYSEG **last_used_keyseg);
00611 extern int _mi_read_key_record(MI_INFO *info,drizzled::internal::my_off_t filepos,unsigned char *buf);
00612 extern int _mi_read_cache(drizzled::internal::IO_CACHE *info,unsigned char *buff,drizzled::internal::my_off_t pos,
00613 uint32_t length,int re_read_if_possibly);
00614 extern uint64_t retrieve_auto_increment(MI_INFO *info,const unsigned char *record);
00615
00616 unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf);
00617 #define mi_get_rec_buff_ptr(info,buf) \
00618 ((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
00619 (buf) - MI_REC_BUFF_OFFSET : (buf))
00620 #define mi_get_rec_buff_len(info,buf) \
00621 (*((uint32_t *)(mi_get_rec_buff_ptr(info,buf))))
00622
00623 extern ulong _mi_rec_unpack(MI_INFO *info,unsigned char *to,unsigned char *from,
00624 ulong reclength);
00625 extern bool _mi_rec_check(MI_INFO *info,const unsigned char *record, unsigned char *packpos,
00626 ulong packed_length, bool with_checkum);
00627 extern int _mi_write_part_record(MI_INFO *info,drizzled::internal::my_off_t filepos,ulong length,
00628 drizzled::internal::my_off_t next_filepos,unsigned char **record,
00629 ulong *reclength,int *flag);
00630 extern void _mi_print_key(FILE *stream,HA_KEYSEG *keyseg,const unsigned char *key,
00631 uint32_t length);
00632 extern bool _mi_read_pack_info(MI_INFO *info,bool fix_keys);
00633 extern int _mi_read_pack_record(MI_INFO *info,drizzled::internal::my_off_t filepos,unsigned char *buf);
00634 extern int _mi_read_rnd_pack_record(MI_INFO*, unsigned char *,drizzled::internal::my_off_t, bool);
00635 extern int _mi_pack_rec_unpack(MI_INFO *info, MI_BIT_BUFF *bit_buff,
00636 unsigned char *to, unsigned char *from, ulong reclength);
00637
00638 struct st_sort_info;
00639
00640
00641 typedef struct st_mi_block_info {
00642 unsigned char header[MI_BLOCK_INFO_HEADER_LENGTH];
00643 ulong rec_len;
00644 ulong data_len;
00645 ulong block_len;
00646 ulong blob_len;
00647 drizzled::internal::my_off_t filepos;
00648 drizzled::internal::my_off_t next_filepos;
00649 drizzled::internal::my_off_t prev_filepos;
00650 uint32_t second_read;
00651 uint32_t offset;
00652 } MI_BLOCK_INFO;
00653
00654
00655
00656 #define BLOCK_FIRST 1
00657 #define BLOCK_LAST 2
00658 #define BLOCK_DELETED 4
00659 #define BLOCK_ERROR 8
00660 #define BLOCK_SYNC_ERROR 16
00661 #define BLOCK_FATAL_ERROR 32
00662
00663 #define NEED_MEM ((uint) 10*4*(IO_SIZE+32)+32)
00664 #define MAXERR 20
00665 #define BUFFERS_WHEN_SORTING 16
00666 #define WRITE_COUNT 1000
00667 #define INDEX_TMP_EXT ".TMM"
00668 #define DATA_TMP_EXT ".TMD"
00669
00670 #define UPDATE_TIME 1
00671 #define UPDATE_STAT 2
00672 #define UPDATE_SORT 4
00673 #define UPDATE_AUTO_INC 8
00674 #define UPDATE_OPEN_COUNT 16
00675
00676 #define USE_BUFFER_INIT (((1024L*512L-MALLOC_OVERHEAD)/IO_SIZE)*IO_SIZE)
00677 #define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD)
00678 #define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD)
00679 #define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
00680
00681 #define fast_mi_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _mi_writeinfo((INFO),0)
00682 #define fast_mi_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _mi_readinfo((INFO),F_RDLCK,1)
00683
00684 extern uint32_t _mi_get_block_info(MI_BLOCK_INFO *,int, drizzled::internal::my_off_t);
00685 extern uint32_t _mi_rec_pack(MI_INFO *info,unsigned char *to,const unsigned char *from);
00686 extern uint32_t _mi_pack_get_block_info(MI_INFO *myisam, MI_BIT_BUFF *bit_buff,
00687 MI_BLOCK_INFO *info, unsigned char **rec_buff_p,
00688 int file, drizzled::internal::my_off_t filepos);
00689 extern void _my_store_blob_length(unsigned char *pos,uint32_t pack_length,uint32_t length);
00690 extern void mi_report_error(int errcode, const char *file_name);
00691 extern void mi_report_error(drizzled::error_t errcode, const char *file_name);
00692 extern size_t mi_mmap_pread(MI_INFO *info, unsigned char *Buffer,
00693 size_t Count, drizzled::internal::my_off_t offset, drizzled::myf MyFlags);
00694 extern size_t mi_mmap_pwrite(MI_INFO *info, const unsigned char *Buffer,
00695 size_t Count, drizzled::internal::my_off_t offset, drizzled::myf MyFlags);
00696 extern size_t mi_nommap_pread(MI_INFO *info, unsigned char *Buffer,
00697 size_t Count, drizzled::internal::my_off_t offset, drizzled::myf MyFlags);
00698 extern size_t mi_nommap_pwrite(MI_INFO *info, const unsigned char *Buffer,
00699 size_t Count, drizzled::internal::my_off_t offset, drizzled::myf MyFlags);
00700
00701 uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite);
00702 uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead);
00703 uint32_t mi_base_info_write(int file, MI_BASE_INFO *base);
00704 int mi_keyseg_write(int file, const HA_KEYSEG *keyseg);
00705 uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef);
00706 uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *keydef);
00707 uint32_t mi_recinfo_write(int file, drizzled::MI_COLUMNDEF *recinfo);
00708 extern int mi_disable_indexes(MI_INFO *info);
00709 extern int mi_enable_indexes(MI_INFO *info);
00710 extern int mi_indexes_are_disabled(MI_INFO *info);
00711 ulong _my_calc_total_blob_length(MI_INFO *info, const unsigned char *record);
00712 drizzled::internal::ha_checksum mi_checksum(MI_INFO *info, const unsigned char *buf);
00713 drizzled::internal::ha_checksum mi_static_checksum(MI_INFO *info, const unsigned char *buf);
00714 bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, unsigned char *record,
00715 drizzled::internal::ha_checksum unique_hash, drizzled::internal::my_off_t pos);
00716 drizzled::internal::ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const unsigned char *buf);
00717 int _mi_cmp_static_unique(MI_INFO *info, MI_UNIQUEDEF *def,
00718 const unsigned char *record, drizzled::internal::my_off_t pos);
00719 int _mi_cmp_dynamic_unique(MI_INFO *info, MI_UNIQUEDEF *def,
00720 const unsigned char *record, drizzled::internal::my_off_t pos);
00721 int mi_unique_comp(MI_UNIQUEDEF *def, const unsigned char *a, const unsigned char *b,
00722 bool null_are_equal);
00723
00724 extern MI_INFO *test_if_reopen(char *filename);
00725 bool check_table_is_closed(const char *name, const char *where);
00726 int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup);
00727 int mi_open_keyfile(MYISAM_SHARE *share);
00728 void mi_setup_functions(register MYISAM_SHARE *share);
00729 bool mi_dynmap_file(MI_INFO *info, drizzled::internal::my_off_t size);
00730 void mi_remap_file(MI_INFO *info, drizzled::internal::my_off_t size);
00731
00732 int mi_check_index_cond(register MI_INFO *info, uint32_t keynr, unsigned char *record);
00733
00734
00735 volatile int *killed_ptr(MI_CHECK *param);
00736 void mi_check_print_error(MI_CHECK *param, const char *fmt,...);
00737 void mi_check_print_warning(MI_CHECK *param, const char *fmt,...);
00738 void mi_check_print_info(MI_CHECK *param, const char *fmt,...);
00739 int flush_pending_blocks(MI_SORT_PARAM *param);
00740 int thr_write_keys(MI_SORT_PARAM *sort_param);
00741 int flush_blocks(MI_CHECK *param, drizzled::KEY_CACHE *key_cache, int file);
00742
00743 int sort_write_record(MI_SORT_PARAM *sort_param);
00744 int _create_index_by_sort(MI_SORT_PARAM *info,bool no_messages, size_t);
00745
00746 extern void mi_set_index_cond_func(MI_INFO *info, index_cond_func_t func,
00747 void *func_arg);
00748
00749 extern size_t my_pwrite(int Filedes,const unsigned char *Buffer,size_t Count,
00750 drizzled::internal::my_off_t offset,drizzled::myf MyFlags);
00751 extern size_t my_pread(int Filedes,unsigned char *Buffer,size_t Count,drizzled::internal::my_off_t offset,
00752 drizzled::myf MyFlags);
00753
00754
00755 void mi_disable_non_unique_index(MI_INFO *info, drizzled::ha_rows rows);
00756 void _mi_report_crashed(MI_INFO *file, const char *message, const char *sfile,
00757 uint32_t sline);
00758