00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #include <drizzled/common_fwd.h>
00021 #include <drizzled/key_map.h>
00022 #include <drizzled/base.h>
00023 #include <plugin/myisam/my_handler.h>
00024 #include <drizzled/internal/iocache.h>
00025
00026
00027
00028
00029
00030 #if MAX_INDEXES > HA_MAX_POSSIBLE_KEY
00031 #define MI_MAX_KEY HA_MAX_POSSIBLE_KEY
00032 #else
00033 #define MI_MAX_KEY MAX_INDEXES
00034 #endif
00035
00036
00037
00038
00039
00040 #define MI_MAX_KEY_LENGTH 1332
00041 #define MI_MAX_KEY_SEG 16
00042
00043 #define MI_MAX_POSSIBLE_KEY_BUFF (MI_MAX_KEY_LENGTH + 6 + 6)
00044
00045 #define MI_MAX_KEY_BUFF (MI_MAX_KEY_LENGTH+MI_MAX_KEY_SEG*6+8+8)
00046 #define MI_MAX_MSG_BUF 1024
00047 #define MI_NAME_IEXT ".MYI"
00048 #define MI_NAME_DEXT ".MYD"
00049
00050 #define MI_MAX_TEMP_LENGTH 2*1024L*1024L*1024L
00051
00052
00053 #define MI_KEY_BLOCK_LENGTH 1024
00054 #define MI_MIN_KEY_BLOCK_LENGTH 1024
00055 #define MI_MAX_KEY_BLOCK_LENGTH 16384
00056
00057
00058
00059
00060
00061
00062
00063
00064 #define MI_KEYMAP_BITS (64)
00065 #define MI_KEYMAP_HIGH_MASK (1UL << (MI_KEYMAP_BITS - 1))
00066 #define mi_get_mask_all_keys_active(_keys_) \
00067 (((_keys_) < MI_KEYMAP_BITS) ? \
00068 ((1UL << (_keys_)) - 1UL) : \
00069 (~ 0UL))
00070
00071 #if MI_MAX_KEY > MI_KEYMAP_BITS
00072
00073 #define mi_is_key_active(_keymap_,_keyno_) \
00074 (((_keyno_) < MI_KEYMAP_BITS) ? \
00075 test((_keymap_) & (1UL << (_keyno_))) : \
00076 test((_keymap_) & MI_KEYMAP_HIGH_MASK))
00077 #define mi_set_key_active(_keymap_,_keyno_) \
00078 (_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \
00079 (1UL << (_keyno_)) : \
00080 MI_KEYMAP_HIGH_MASK)
00081 #define mi_clear_key_active(_keymap_,_keyno_) \
00082 (_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \
00083 (~ (1UL << (_keyno_))) : \
00084 (~ (0UL)) )
00085
00086 #else
00087
00088 #define mi_is_key_active(_keymap_,_keyno_) \
00089 test((_keymap_) & (1UL << (_keyno_)))
00090 #define mi_set_key_active(_keymap_,_keyno_) \
00091 (_keymap_)|= (1UL << (_keyno_))
00092 #define mi_clear_key_active(_keymap_,_keyno_) \
00093 (_keymap_)&= (~ (1UL << (_keyno_)))
00094
00095 #endif
00096
00097 #define mi_is_any_key_active(_keymap_) \
00098 test((_keymap_))
00099 #define mi_is_all_keys_active(_keymap_,_keys_) \
00100 ((_keymap_) == mi_get_mask_all_keys_active(_keys_))
00101 #define mi_set_all_keys_active(_keymap_,_keys_) \
00102 (_keymap_)= mi_get_mask_all_keys_active(_keys_)
00103 #define mi_clear_all_keys_active(_keymap_) \
00104 (_keymap_)= 0
00105 #define mi_intersect_keys_active(_to_,_from_) \
00106 (_to_)&= (_from_)
00107 #define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \
00108 ((_keymap1_) & (_keymap2_) & \
00109 mi_get_mask_all_keys_active(_keys_))
00110 #define mi_copy_keys_active(_to_,_maxkeys_,_from_) \
00111 (_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \
00112 (_from_))
00113
00114 typedef uint32_t ha_checksum;
00115
00116
00117 typedef struct st_mi_isaminfo
00118 {
00119 drizzled::ha_rows records;
00120 drizzled::ha_rows deleted;
00121 drizzled::internal::my_off_t recpos;
00122 drizzled::internal::my_off_t newrecpos;
00123 drizzled::internal::my_off_t dupp_key_pos;
00124 drizzled::internal::my_off_t data_file_length,
00125 max_data_file_length,
00126 index_file_length,
00127 max_index_file_length,
00128 delete_length;
00129 ulong reclength;
00130 ulong mean_reclength;
00131 uint64_t auto_increment;
00132 uint64_t key_map;
00133 char *data_file_name, *index_file_name;
00134 uint32_t keys;
00135 uint options;
00136 int errkey,
00137 sortkey;
00138 int filenr;
00139 time_t create_time;
00140 time_t check_time;
00141 time_t update_time;
00142 uint32_t reflength;
00143 ulong record_offset;
00144 ulong *rec_per_key;
00145 } MI_ISAMINFO;
00146
00147
00148 typedef struct st_mi_create_info
00149 {
00150 const char *index_file_name, *data_file_name;
00151 drizzled::ha_rows max_rows;
00152 drizzled::ha_rows reloc_rows;
00153 uint64_t auto_increment;
00154 uint64_t data_file_length;
00155 uint64_t key_file_length;
00156 uint32_t old_options;
00157 uint8_t language;
00158 bool with_auto_increment;
00159
00160 st_mi_create_info():
00161 index_file_name(0),
00162 data_file_name(0),
00163 max_rows(0),
00164 reloc_rows(0),
00165 auto_increment(0),
00166 data_file_length(0),
00167 key_file_length(0),
00168 old_options(0),
00169 language(0),
00170 with_auto_increment(0)
00171 { }
00172
00173 } MI_CREATE_INFO;
00174
00175 struct st_myisam_info;
00176 struct st_mi_isam_share;
00177 typedef struct st_myisam_info MI_INFO;
00178 struct st_mi_s_param;
00179
00180 typedef struct st_mi_keydef
00181 {
00182 struct st_mi_isam_share *share;
00183 uint16_t keysegs;
00184 uint16_t flag;
00185
00186 uint8_t key_alg;
00187 uint16_t block_length;
00188 uint16_t underflow_block_length;
00189 uint16_t keylength;
00190 uint16_t minlength;
00191 uint16_t maxlength;
00192 uint16_t block_size_index;
00193 uint32_t version;
00194
00195 HA_KEYSEG *seg,*end;
00196
00197 int (*bin_search)(struct st_myisam_info *info,struct st_mi_keydef *keyinfo,
00198 unsigned char *page,unsigned char *key,
00199 uint32_t key_len,uint32_t comp_flag,unsigned char * *ret_pos,
00200 unsigned char *buff, bool *was_last_key);
00201 uint32_t (*get_key)(struct st_mi_keydef *keyinfo,uint32_t nod_flag,unsigned char * *page,
00202 unsigned char *key);
00203 int (*pack_key)(struct st_mi_keydef *keyinfo,uint32_t nod_flag,unsigned char *next_key,
00204 unsigned char *org_key, unsigned char *prev_key, unsigned char *key,
00205 struct st_mi_s_param *s_temp);
00206 void (*store_key)(struct st_mi_keydef *keyinfo, unsigned char *key_pos,
00207 struct st_mi_s_param *s_temp);
00208 int (*ck_insert)(struct st_myisam_info *inf, uint32_t k_nr, unsigned char *k, uint32_t klen);
00209 int (*ck_delete)(struct st_myisam_info *inf, uint32_t k_nr, unsigned char *k, uint32_t klen);
00210 } MI_KEYDEF;
00211
00212
00213 #define MI_UNIQUE_HASH_LENGTH 4
00214
00215 typedef struct st_unique_def
00216 {
00217 uint16_t keysegs;
00218 unsigned char key;
00219 uint8_t null_are_equal;
00220 HA_KEYSEG *seg,*end;
00221 } MI_UNIQUEDEF;
00222
00223 typedef struct st_mi_decode_tree
00224 {
00225 uint16_t *table;
00226 uint quick_table_bits;
00227 unsigned char *intervalls;
00228 } MI_DECODE_TREE;
00229
00230
00231 struct st_mi_bit_buff;
00232
00233
00234
00235
00236
00237
00238
00239 namespace drizzled
00240 {
00241
00242 typedef struct st_columndef
00243 {
00244 int16_t type;
00245 uint16_t length;
00246 uint32_t offset;
00247 uint8_t null_bit;
00248 uint16_t null_pos;
00249
00250 #ifndef NOT_PACKED_DATABASES
00251 void (*unpack)(struct st_columndef *rec,struct st_mi_bit_buff *buff,
00252 unsigned char *start,unsigned char *end);
00253 enum drizzled::en_fieldtype base_type;
00254 uint32_t space_length_bits,pack_type;
00255 MI_DECODE_TREE *huff_tree;
00256 #endif
00257 } MI_COLUMNDEF;
00258
00259 }
00260
00261
00262 extern char * myisam_log_filename;
00263 extern uint32_t myisam_block_size;
00264 extern uint32_t myisam_concurrent_insert;
00265 extern uint32_t myisam_bulk_insert_tree_size;
00266 extern uint32_t data_pointer_size;
00267
00268
00269
00270 extern int mi_close(struct st_myisam_info *file);
00271 extern int mi_delete(struct st_myisam_info *file,const unsigned char *buff);
00272 extern struct st_myisam_info *mi_open(const drizzled::identifier::Table &identifier,
00273 int mode,
00274 uint32_t wait_if_locked);
00275 extern int mi_panic(enum drizzled::ha_panic_function function);
00276 extern int mi_rfirst(struct st_myisam_info *file,unsigned char *buf,int inx);
00277 extern int mi_rkey(MI_INFO *info, unsigned char *buf, int inx, const unsigned char *key,
00278 drizzled::key_part_map keypart_map, enum drizzled::ha_rkey_function search_flag);
00279 extern int mi_rlast(struct st_myisam_info *file,unsigned char *buf,int inx);
00280 extern int mi_rnext(struct st_myisam_info *file,unsigned char *buf,int inx);
00281 extern int mi_rnext_same(struct st_myisam_info *info, unsigned char *buf);
00282 extern int mi_rprev(struct st_myisam_info *file,unsigned char *buf,int inx);
00283 extern int mi_rrnd(struct st_myisam_info *file,unsigned char *buf, drizzled::internal::my_off_t pos);
00284 extern int mi_scan_init(struct st_myisam_info *file);
00285 extern int mi_scan(struct st_myisam_info *file,unsigned char *buf);
00286 extern int mi_rsame(struct st_myisam_info *file,unsigned char *record,int inx);
00287 extern int mi_update(struct st_myisam_info *file,const unsigned char *old,
00288 unsigned char *new_record);
00289 extern int mi_write(struct st_myisam_info *file,unsigned char *buff);
00290 extern drizzled::internal::my_off_t mi_position(struct st_myisam_info *file);
00291 extern int mi_status(struct st_myisam_info *info, MI_ISAMINFO *x, uint32_t flag);
00292 extern int mi_lock_database(struct st_myisam_info *file,int lock_type);
00293 extern int mi_create(const char *name,uint32_t keys,MI_KEYDEF *keydef,
00294 uint32_t columns, drizzled::MI_COLUMNDEF *columndef,
00295 uint32_t uniques, MI_UNIQUEDEF *uniquedef,
00296 MI_CREATE_INFO *create_info, uint32_t flags);
00297 extern int mi_delete_table(const char *name);
00298 extern int mi_rename(const char *from, const char *to);
00299 extern int mi_extra(struct st_myisam_info *file,
00300 enum drizzled::ha_extra_function function,
00301 void *extra_arg);
00302 extern int mi_reset(struct st_myisam_info *file);
00303 extern drizzled::ha_rows mi_records_in_range(MI_INFO *info, int inx,
00304 drizzled::key_range *min_key, drizzled::key_range *max_key);
00305 extern int mi_log(int activate_log);
00306 extern int mi_delete_all_rows(struct st_myisam_info *info);
00307 extern ulong _mi_calc_blob_length(uint32_t length , const unsigned char *pos);
00308 extern uint32_t mi_get_pointer_length(uint64_t file_length, uint32_t def);
00309
00310
00311
00312 #define MYISAMCHK_REPAIR 1
00313 #define MYISAMCHK_VERIFY 2
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 #define T_AUTO_INC 1
00326 #define T_AUTO_REPAIR 2
00327 #define T_CALC_CHECKSUM 8
00328 #define T_CHECK 16
00329 #define T_CHECK_ONLY_CHANGED 32
00330 #define T_CREATE_MISSING_KEYS 64
00331 #define T_DESCRIPT 128
00332 #define T_DONT_CHECK_CHECKSUM 256
00333 #define T_EXTEND 512
00334 #define T_FAST (1L << 10)
00335 #define T_FORCE_CREATE (1L << 11)
00336 #define T_FORCE_UNIQUENESS (1L << 12)
00337 #define T_INFO (1L << 13)
00338 #define T_MEDIUM (1L << 14)
00339 #define T_QUICK (1L << 15)
00340 #define T_READONLY (1L << 16)
00341 #define T_REP (1L << 17)
00342 #define T_REP_BY_SORT (1L << 18)
00343 #define T_REP_PARALLEL (1L << 19)
00344 #define T_RETRY_WITHOUT_QUICK (1L << 20)
00345 #define T_SAFE_REPAIR (1L << 21)
00346 #define T_SILENT (1L << 22)
00347 #define T_SORT_INDEX (1L << 23)
00348 #define T_SORT_RECORDS (1L << 24)
00349 #define T_STATISTICS (1L << 25)
00350 #define T_UNPACK (1L << 26)
00351 #define T_UPDATE_STATE (1L << 27)
00352 #define T_VERBOSE (1L << 28)
00353 #define T_VERY_SILENT (1L << 29)
00354 #define T_WAIT_FOREVER (1L << 30)
00355 #define T_WRITE_LOOP ((ulong) 1L << 31)
00356
00357 #define T_REP_ANY (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
00358
00359 #define O_NEW_INDEX 1
00360 #define O_NEW_DATA 2
00361 #define O_DATA_LOST 4
00362
00363
00364
00365 typedef struct st_sort_key_blocks
00366 {
00367 unsigned char *buff,*end_pos;
00368 unsigned char lastkey[MI_MAX_POSSIBLE_KEY_BUFF];
00369 uint32_t last_length;
00370 int inited;
00371 } SORT_KEY_BLOCKS;
00372
00373
00374
00375
00376
00377
00378
00379
00380 typedef enum
00381 {
00382
00383 MI_STATS_METHOD_NULLS_NOT_EQUAL,
00384
00385 MI_STATS_METHOD_NULLS_EQUAL,
00386
00387 MI_STATS_METHOD_IGNORE_NULLS
00388 } enum_mi_stats_method;
00389
00390 typedef struct st_mi_check_param
00391 {
00392 uint64_t auto_increment_value;
00393 uint64_t max_data_file_length;
00394 uint64_t keys_in_use;
00395 uint64_t max_record_length;
00396 drizzled::internal::my_off_t search_after_block;
00397 drizzled::internal::my_off_t new_file_pos,key_file_blocks;
00398 drizzled::internal::my_off_t keydata,totaldata,key_blocks,start_check_pos;
00399 drizzled::ha_rows total_records,total_deleted;
00400 ha_checksum record_checksum,glob_crc;
00401 uint64_t use_buffers;
00402 size_t read_buffer_length, write_buffer_length,
00403 sort_buffer_length, sort_key_blocks;
00404 uint32_t out_flag,warning_printed,error_printed,verbose;
00405 uint32_t opt_sort_key,total_files,max_level;
00406 uint32_t testflag, key_cache_block_size;
00407 uint8_t language;
00408 bool using_global_keycache, opt_lock_memory, opt_follow_links;
00409 bool retry_repair, force_sort;
00410 char temp_filename[FN_REFLEN],*isam_file_name;
00411 int tmpfile_createflag;
00412 drizzled::myf myf_rw;
00413 drizzled::internal::io_cache_st read_cache;
00414
00415
00416
00417
00418
00419 uint64_t unique_count[MI_MAX_KEY_SEG+1];
00420 uint64_t notnull_count[MI_MAX_KEY_SEG+1];
00421
00422 ha_checksum key_crc[HA_MAX_POSSIBLE_KEY];
00423 ulong rec_per_key_part[MI_MAX_KEY_SEG*HA_MAX_POSSIBLE_KEY];
00424 void *session;
00425 const char *db_name, *table_name;
00426 const char *op_name;
00427 enum_mi_stats_method stats_method;
00428 } MI_CHECK;
00429
00430 typedef struct st_sort_info
00431 {
00432 drizzled::internal::my_off_t filelength,dupp,buff_length;
00433 drizzled::ha_rows max_records;
00434 uint32_t current_key, total_keys;
00435 drizzled::myf myf_rw;
00436 enum drizzled::data_file_type new_data_file_type;
00437 MI_INFO *info;
00438 MI_CHECK *param;
00439 unsigned char *buff;
00440 SORT_KEY_BLOCKS *key_block,*key_block_end;
00441
00442 uint32_t got_error, threads_running;
00443 pthread_mutex_t mutex;
00444 pthread_cond_t cond;
00445 } SORT_INFO;
00446
00447
00448 void myisamchk_init(MI_CHECK *param);
00449 int chk_status(MI_CHECK *param, MI_INFO *info);
00450 int chk_del(MI_CHECK *param, register MI_INFO *info, uint32_t test_flag);
00451 int chk_size(MI_CHECK *param, MI_INFO *info);
00452 int chk_key(MI_CHECK *param, MI_INFO *info);
00453 int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend);
00454 int mi_repair(MI_CHECK *param, register MI_INFO *info,
00455 char * name, int rep_quick);
00456 int mi_sort_index(MI_CHECK *param, register MI_INFO *info, char * name);
00457 int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
00458 const char * name, int rep_quick);
00459 int change_to_newfile(const char * filename, const char * old_ext,
00460 const char * new_ext, uint32_t raid_chunks,
00461 drizzled::myf myflags);
00462 void lock_memory(MI_CHECK *param);
00463 void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
00464 bool repair);
00465 int update_state_info(MI_CHECK *param, MI_INFO *info,uint32_t update);
00466 void update_key_parts(MI_KEYDEF *keyinfo, ulong *rec_per_key_part,
00467 uint64_t *unique, uint64_t *notnull,
00468 uint64_t records);
00469 int filecopy(MI_CHECK *param, int to,int from,drizzled::internal::my_off_t start,
00470 drizzled::internal::my_off_t length, const char *type);
00471 int movepoint(MI_INFO *info,unsigned char *record,drizzled::internal::my_off_t oldpos,
00472 drizzled::internal::my_off_t newpos, uint32_t prot_key);
00473 int write_data_suffix(SORT_INFO *sort_info, bool fix_datafile);
00474 int test_if_almost_full(MI_INFO *info);
00475 bool mi_test_if_sort_rep(MI_INFO *info, drizzled::ha_rows rows, uint64_t key_map,
00476 bool force);
00477
00478 int mi_init_bulk_insert(MI_INFO *info, uint32_t cache_size, drizzled::ha_rows rows);
00479 void mi_flush_bulk_insert(MI_INFO *info, uint32_t inx);
00480 void mi_end_bulk_insert(MI_INFO *info);
00481 int mi_preload(MI_INFO *info, uint64_t key_map, bool ignore_leaves);
00482