diff options
author | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-11-13 23:12:55 +0400 |
---|---|---|
committer | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-11-13 23:12:55 +0400 |
commit | 9248b402d8c5e437e0bbbd4e25841b2d54ff3f72 (patch) | |
tree | 5a97be6534619bc26b4e41b1de100ad88fbd8a98 /myisam | |
parent | 6c5a2e50c4d738c9df85102d3fcbbf6dd24cec38 (diff) | |
parent | cb927e2f453acc7b8e618ece81e0d963f48b09d8 (diff) | |
download | mariadb-git-9248b402d8c5e437e0bbbd4e25841b2d54ff3f72.tar.gz |
Merge bk@192.168.21.1:mysql-4.1-opt
into mysql.com:/home/hf/work/31305/my41-31305
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/mi_dynrec.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 260f461685e..ad76296a66e 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -145,6 +145,29 @@ static int write_dynamic_record(MI_INFO *info, const byte *record, DBUG_ENTER("write_dynamic_record"); flag=0; + + /* + Check if we have enough room for the new record. + First we do simplified check to make usual case faster. + Then we do more precise check for the space left. + Though it still is not absolutely precise, as + we always use MI_MAX_DYN_BLOCK_HEADER while it can be + less in the most of the cases. + */ + + if (unlikely(info->s->base.max_data_file_length - + info->state->data_file_length < + reclength + MI_MAX_DYN_BLOCK_HEADER)) + { + if (info->s->base.max_data_file_length - info->state->data_file_length + + info->state->empty - info->state->del * MI_MAX_DYN_BLOCK_HEADER < + reclength + MI_MAX_DYN_BLOCK_HEADER) + { + my_errno=HA_ERR_RECORD_FILE_FULL; + DBUG_RETURN(1); + } + } + do { if (_mi_find_writepos(info,reclength,&filepos,&length)) @@ -577,6 +600,51 @@ static int update_dynamic_record(MI_INFO *info, my_off_t filepos, byte *record, DBUG_ENTER("update_dynamic_record"); flag=block_info.second_read=0; + /* + Check if we have enough room for the record. + First we do simplified check to make usual case faster. + Then we do more precise check for the space left. + Though it still is not absolutely precise, as + we always use MI_MAX_DYN_BLOCK_HEADER while it can be + less in the most of the cases. + */ + + /* + compare with just the reclength as we're going + to get some space from the old replaced record + */ + if (unlikely(info->s->base.max_data_file_length - + info->state->data_file_length < reclength)) + { + /* + let's read the old record's block to find out the length of the + old record + */ + if ((error=_mi_get_block_info(&block_info,info->dfile,filepos)) + & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | BLOCK_FATAL_ERROR)) + { + DBUG_PRINT("error",("Got wrong block info")); + if (!(error & BLOCK_FATAL_ERROR)) + my_errno=HA_ERR_WRONG_IN_RECORD; + goto err; + } + + /* + if new record isn't longer, we can go on safely + */ + if (block_info.rec_len < reclength) + { + if (info->s->base.max_data_file_length - info->state->data_file_length + + info->state->empty - info->state->del * MI_MAX_DYN_BLOCK_HEADER < + reclength - block_info.rec_len + MI_MAX_DYN_BLOCK_HEADER) + { + my_errno=HA_ERR_RECORD_FILE_FULL; + goto err; + } + } + block_info.second_read=0; + } + while (reclength > 0) { if (filepos != info->s->state.dellink) |