diff --git a/storage/maria/ma_hash_table.h b/storage/maria/ma_hash_table.h new file mode 100644 index 0000000..c8e4578 --- /dev/null +++ b/storage/maria/ma_hash_table.h @@ -0,0 +1,45 @@ +#include"../../mysys/my_malloc.c" +#include"../../include/my_global.h" +typedef struct ma_hash_table_element{ + unsigned int hash_code; + unsigned int record_offset; + struct ma_hash_table * next; //we will use single link list because no delete operations +} ma_hash_table_element; + +typedef struct ma_hash_table{ + unsigned int size; + ma_hash_table_element * h_t_e; +}ma_hash_table; +ma_hash_table * ma_create_hash_table(int size){ + ma_hash_table_element * _ht = (ma_hash_table *)my_malloc(sizeof(ma_hash_table)*size,MYF(MY_WME)); + ma_hash_table_element * temp=_ht; + for(int i=0;inext=NULL; + temp++; + } + ma_hash_table *temp_hash_table = (ma_hash_table *)my_malloc(sizeof(ma_hash_table),MYF(MY_WME)); + temp_hash_table->size =size; + temp_hash_table->h_t_e = _ht; + return temp_hash_table; +} + +int add_key_to_hash_table(ma_hash_table *_ht,unsigned int key , unsigned int offset){ + int hash_position = key % _ht->size; //just a simple logic thinking of upgrading it may we whatever + ma_hash_table_element *tmp= _ht->h_t_e; + tmp = tmp+hash_position; + ma_hash_table_element *parent; + //transverse the whole list + while(tmp!=NULL){ + if(tmp->hash_code==key) + return 1; + parent=tmp; + tmp=tmp->next; + } + ma_hash_table_element *temp_hash = (ma_hash_table_element *)my_malloc(sizeof(ma_hash_table_element),MYF(MY_WME)); + temp_hash->hash_code=key; + temp_hash->record_offset=offset; + temp_hash->next=NULL; + parent->next=temp_hash; + return 0; +} + diff --git a/storage/maria/ma_state.h b/storage/maria/ma_state.h index 2903986..d89324f 100644 --- a/storage/maria/ma_state.h +++ b/storage/maria/ma_state.h @@ -14,7 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Struct to store tables in use by one transaction */ - +//#include"ma_hash_table.h" typedef struct st_maria_status_info { ha_rows records; /* Rows in table */ @@ -24,6 +24,7 @@ typedef struct st_maria_status_info my_off_t key_file_length; my_off_t data_file_length; ha_checksum checksum; + void * hash_table; uint32 changed:1, /* Set if table was changed */ no_transid:1; /* Set if no transid was set on rows */ } MARIA_STATUS_INFO; diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index f57c462..b31f5a7 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -21,7 +21,7 @@ #include "trnman.h" #include "ma_key_recover.h" #include "ma_blockrec.h" - +#include "ma_hash_table.h" /* Functions declared in this file */ static int w_search(MARIA_HA *info, uint32 comp_flag, @@ -93,6 +93,7 @@ int maria_write(MARIA_HA *info, uchar *record) my_bool lock_tree= share->lock_key_trees; my_bool fatal_error; MARIA_KEYDEF *keyinfo; + ma_hash_table *ht; DBUG_ENTER("maria_write"); DBUG_PRINT("enter",("index_file: %d data_file: %d", share->kfile.file, info->dfile.file)); @@ -121,26 +122,35 @@ int maria_write(MARIA_HA *info, uchar *record) } if (_ma_mark_file_changed(share)) goto err2; - + /* Calculate and check all unique constraints */ + if(!info->state->hash_table){ + info->state->hash_table = ma_create_hash_table(100000); + } + ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo,record); + if(add_key_to_hash_table((ma_hash_table*)info->state->hash_table,unique_hash,info->state->records)){ + //here check for duplicates + //i really do not know to get record by record offset + goto err2; + } +// if (share->state.header.uniques) +// { +// for (i=0 ; i < share->state.header.uniques ; i++) +// { +// MARIA_UNIQUEDEF *def= share->uniqueinfo + i; +// ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo+i,record); +// if (maria_is_key_active(share->state.key_map, def->key)) +// { +// if (_ma_check_unique(info, def, record, +// unique_hash, HA_OFFSET_ERROR)) +// goto err2; +// } +// else +// maria_unique_store(record+ share->keyinfo[def->key].seg->start, +// unique_hash); +// } +// } - if (share->state.header.uniques) - { - for (i=0 ; i < share->state.header.uniques ; i++) - { - MARIA_UNIQUEDEF *def= share->uniqueinfo + i; - ha_checksum unique_hash= _ma_unique_hash(share->uniqueinfo+i,record); - if (maria_is_key_active(share->state.key_map, def->key)) - { - if (_ma_check_unique(info, def, record, - unique_hash, HA_OFFSET_ERROR)) - goto err2; - } - else - maria_unique_store(record+ share->keyinfo[def->key].seg->start, - unique_hash); - } - } /* Ensure we don't try to restore auto_increment if it doesn't change */ info->last_auto_increment= ~(ulonglong) 0; @@ -160,122 +170,122 @@ int maria_write(MARIA_HA *info, uchar *record) /* Write all keys to indextree */ buff= info->lastkey_buff2; - for (i=0, keyinfo= share->keyinfo ; i < share->base.keys ; i++, keyinfo++) - { - MARIA_KEY int_key; - if (maria_is_key_active(share->state.key_map, i)) - { - my_bool local_lock_tree= (lock_tree && - !(info->bulk_insert && - is_tree_inited(&info->bulk_insert[i]))); - if (local_lock_tree) - { - mysql_rwlock_wrlock(&keyinfo->root_lock); - keyinfo->version++; - } - if (keyinfo->flag & HA_FULLTEXT ) - { - if (_ma_ft_add(info,i, buff,record,filepos)) - { - if (local_lock_tree) - mysql_rwlock_unlock(&keyinfo->root_lock); - DBUG_PRINT("error",("Got error: %d on write",my_errno)); - goto err; - } - } - else - { - while (keyinfo->ck_insert(info, - (*keyinfo->make_key)(info, &int_key, i, - buff, record, filepos, - info->trn->trid))) - { - TRN *blocker; - DBUG_PRINT("error",("Got error: %d on write",my_errno)); - /* - explicit check to filter out temp tables, they aren't - transactional and don't have a proper TRN so the code - below doesn't work for them. - Also, filter out non-thread maria use, and table modified in - the same transaction. - At last, filter out non-dup-unique errors. - */ - if (!local_lock_tree) - goto err; - if (info->dup_key_trid == info->trn->trid || - my_errno != HA_ERR_FOUND_DUPP_KEY) - { - mysql_rwlock_unlock(&keyinfo->root_lock); - goto err; - } - /* Different TrIDs: table must be transactional */ - DBUG_ASSERT(share->base.born_transactional); - /* - If transactions are disabled, and dup_key_trid is different from - our TrID, it must be ALTER TABLE with dup_key_trid==0 (no - transaction). ALTER TABLE does have MARIA_HA::TRN not dummy but - puts TrID=0 in rows/keys. - */ - DBUG_ASSERT(share->now_transactional || - (info->dup_key_trid == 0)); - blocker= trnman_trid_to_trn(info->trn, info->dup_key_trid); - /* - if blocker TRN was not found, it means that the conflicting - transaction was committed long time ago. It could not be - aborted, as it would have to wait on the key tree lock - to remove the conflicting key it has inserted. - */ - if (!blocker || blocker->commit_trid != ~(TrID)0) - { /* committed */ - if (blocker) - mysql_mutex_unlock(& blocker->state_lock); - mysql_rwlock_unlock(&keyinfo->root_lock); - goto err; - } - mysql_rwlock_unlock(&keyinfo->root_lock); - { - /* running. now we wait */ - WT_RESOURCE_ID rc; - int res; - PSI_stage_info old_stage_info; - - rc.type= &ma_rc_dup_unique; - /* TODO savepoint id when we'll have them */ - rc.value= (intptr)blocker; - res= wt_thd_will_wait_for(info->trn->wt, blocker->wt, & rc); - if (res != WT_OK) - { - mysql_mutex_unlock(& blocker->state_lock); - my_errno= HA_ERR_LOCK_DEADLOCK; - goto err; - } - proc_info_hook(0, &stage_waiting_for_a_resource, &old_stage_info, - __func__, __FILE__, __LINE__); - res= wt_thd_cond_timedwait(info->trn->wt, & blocker->state_lock); - proc_info_hook(0, &old_stage_info, 0, __func__, __FILE__, __LINE__); - - mysql_mutex_unlock(& blocker->state_lock); - if (res != WT_OK) - { - my_errno= res == WT_TIMEOUT ? HA_ERR_LOCK_WAIT_TIMEOUT - : HA_ERR_LOCK_DEADLOCK; - goto err; - } - } - mysql_rwlock_wrlock(&keyinfo->root_lock); -#ifndef MARIA_CANNOT_ROLLBACK - keyinfo->version++; -#endif - } - } - - /* The above changed info->lastkey2. Inform maria_rnext_same(). */ - info->update&= ~HA_STATE_RNEXT_SAME; - - if (local_lock_tree) - mysql_rwlock_unlock(&keyinfo->root_lock); - } - } +// for (i=0, keyinfo= share->keyinfo ; i < share->base.keys ; i++, keyinfo++) +// { +// MARIA_KEY int_key; +// if (maria_is_key_active(share->state.key_map, i)) +// { +// my_bool local_lock_tree= (lock_tree && +// !(info->bulk_insert && +// is_tree_inited(&info->bulk_insert[i]))); +// if (local_lock_tree) +// { +// mysql_rwlock_wrlock(&keyinfo->root_lock); +// keyinfo->version++; +// } +// if (keyinfo->flag & HA_FULLTEXT ) +// { +// if (_ma_ft_add(info,i, buff,record,filepos)) +// { +// if (local_lock_tree) +// mysql_rwlock_unlock(&keyinfo->root_lock); +// DBUG_PRINT("error",("Got error: %d on write",my_errno)); +// goto err; +// } +// } +// else +// { +// while (keyinfo->ck_insert(info, +// (*keyinfo->make_key)(info, &int_key, i, +// buff, record, filepos, +// info->trn->trid))) +// { +// TRN *blocker; +// DBUG_PRINT("error",("Got error: %d on write",my_errno)); +// /* +// explicit check to filter out temp tables, they aren't +// transactional and don't have a proper TRN so the code +// below doesn't work for them. +// Also, filter out non-thread maria use, and table modified in +// the same transaction. +// At last, filter out non-dup-unique errors. +// */ +// if (!local_lock_tree) +// goto err; +// if (info->dup_key_trid == info->trn->trid || +// my_errno != HA_ERR_FOUND_DUPP_KEY) +// { +// mysql_rwlock_unlock(&keyinfo->root_lock); +// goto err; +// } +// /* Different TrIDs: table must be transactional */ +// DBUG_ASSERT(share->base.born_transactional); +// /* +// If transactions are disabled, and dup_key_trid is different from +// our TrID, it must be ALTER TABLE with dup_key_trid==0 (no +// transaction). ALTER TABLE does have MARIA_HA::TRN not dummy but +// puts TrID=0 in rows/keys. +// */ +// DBUG_ASSERT(share->now_transactional || +// (info->dup_key_trid == 0)); +// blocker= trnman_trid_to_trn(info->trn, info->dup_key_trid); +// /* +// if blocker TRN was not found, it means that the conflicting +// transaction was committed long time ago. It could not be +// aborted, as it would have to wait on the key tree lock +// to remove the conflicting key it has inserted. +// */ +// if (!blocker || blocker->commit_trid != ~(TrID)0) +// { /* committed */ +// if (blocker) +// mysql_mutex_unlock(& blocker->state_lock); +// mysql_rwlock_unlock(&keyinfo->root_lock); +// goto err; +// } +// mysql_rwlock_unlock(&keyinfo->root_lock); +// { +// /* running. now we wait */ +// WT_RESOURCE_ID rc; +// int res; +// PSI_stage_info old_stage_info; +// +// rc.type= &ma_rc_dup_unique; +// /* TODO savepoint id when we'll have them */ +// rc.value= (intptr)blocker; +// res= wt_thd_will_wait_for(info->trn->wt, blocker->wt, & rc); +// if (res != WT_OK) +// { +// mysql_mutex_unlock(& blocker->state_lock); +// my_errno= HA_ERR_LOCK_DEADLOCK; +// goto err; +// } +// proc_info_hook(0, &stage_waiting_for_a_resource, &old_stage_info, +// __func__, __FILE__, __LINE__); +// res= wt_thd_cond_timedwait(info->trn->wt, & blocker->state_lock); +// proc_info_hook(0, &old_stage_info, 0, __func__, __FILE__, __LINE__); +// +// mysql_mutex_unlock(& blocker->state_lock); +// if (res != WT_OK) +// { +// my_errno= res == WT_TIMEOUT ? HA_ERR_LOCK_WAIT_TIMEOUT +// : HA_ERR_LOCK_DEADLOCK; +// goto err; +// } +// } +// mysql_rwlock_wrlock(&keyinfo->root_lock); +//#ifndef MARIA_CANNOT_ROLLBACK +// keyinfo->version++; +//#endif +// } +// } +// +// /* The above changed info->lastkey2. Inform maria_rnext_same(). */ +// info->update&= ~HA_STATE_RNEXT_SAME; +// +// if (local_lock_tree) +// mysql_rwlock_unlock(&keyinfo->root_lock); +// } +// } if (share->calc_write_checksum) info->cur_row.checksum= (*share->calc_write_checksum)(info,record); if (filepos != HA_OFFSET_ERROR) @@ -407,12 +417,12 @@ int maria_write(MARIA_HA *info, uchar *record) info->update= (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); my_errno=save_errno; err2: - save_errno=my_errno; - DBUG_ASSERT(save_errno); - if (!save_errno) - save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */ - DBUG_PRINT("error", ("got error: %d", save_errno)); - _ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); + save_errno=my_errno=141; +// DBUG_ASSERT(save_errno); +// if (!save_errno) +// save_errno= HA_ERR_INTERNAL_ERROR; /* Should never happen */ +// DBUG_PRINT("error", ("got error: %d", save_errno)); +// _ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE); DBUG_RETURN(my_errno=save_errno); } /* maria_write */ @@ -471,7 +481,7 @@ static my_bool _ma_ck_write_btree(MARIA_HA *info, MARIA_KEY *key) */ static my_bool _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key, - my_off_t *root, uint32 comp_flag) + my_off_t *root, uint32 comp_flag)//work { MARIA_SHARE *share= info->s; LSN lsn= LSN_IMPOSSIBLE; @@ -518,7 +528,7 @@ static my_bool _ma_ck_write_btree_with_log(MARIA_HA *info, MARIA_KEY *key, */ my_bool _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEY *key, my_off_t *root, - uint32 comp_flag) + uint32 comp_flag)//work { int error; DBUG_ENTER("_ma_ck_real_write_btree"); @@ -777,7 +787,7 @@ static int w_search(register MARIA_HA *info, uint32 comp_flag, MARIA_KEY *key, int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, MARIA_PAGE *anc_page, uchar *key_pos, uchar *key_buff, MARIA_PAGE *father_page, uchar *father_key_pos, - my_bool insert_last) + my_bool insert_last)//work { uint a_length, nod_flag, org_anc_length; int t_length; diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 60a34c6..710a3e4 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -763,7 +763,7 @@ uint _mi_get_static_key(register MI_KEYDEF *keyinfo, uint nod_flag, /* - get key witch is packed against previous key or key with a NULL column. + get key which is packed against previous key or key with a NULL column. SYNOPSIS _mi_get_pack_key() diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index ff96ee8..77549b0 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -122,7 +122,7 @@ int mi_write(MI_INFO *info, uchar *record) } else { - if (share->keyinfo[i].ck_insert(info,i,buff, + if (share->keyinfo[i].ck_insert(info,i,buff, //work _mi_make_key(info,i,buff,record,filepos))) { if (local_lock_tree) @@ -258,7 +258,7 @@ int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length) **********************************************************************/ int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key, - uint key_length) + uint key_length)//work { int error; uint comp_flag; @@ -335,7 +335,7 @@ int _mi_enlarge_root(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *key, 0 = ok 1 = key should be stored in higher tree */ - +//work static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, uint comp_flag, uchar *key, uint key_length, my_off_t page, uchar *father_buff, uchar *father_keypos,