static int _mi_ft_erase(MI_INFO *info, uint keynr, uchar *keybuf, FT_WORD *wlist, my_off_t filepos) { uint key_length, err=0; DBUG_ENTER("_mi_ft_erase"); for (; wlist->pos; wlist++) { key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)) err=1; } DBUG_RETURN(err); }
int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, const byte *oldrec, const byte *newrec, my_off_t pos) { int error= -1; FT_WORD *oldlist,*newlist, *old_word, *new_word; CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; uint key_length; int cmp, cmp2; DBUG_ENTER("_mi_ft_update"); if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, oldrec))) goto err0; if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, newrec))) goto err1; error=0; while(old_word->pos && new_word->pos) { cmp= mi_compare_text(cs, (uchar*) old_word->pos,old_word->len, (uchar*) new_word->pos,new_word->len,0,0); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); if (cmp < 0 || cmp2) { key_length=_ft_make_key(info,keynr,keybuf,old_word,pos); if ((error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))) goto err2; } if (cmp > 0 || cmp2) { key_length=_ft_make_key(info,keynr,keybuf,new_word,pos); if ((error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))) goto err2; } if (cmp<=0) old_word++; if (cmp>=0) new_word++; } if (old_word->pos) error=_mi_ft_erase(info,keynr,keybuf,old_word,pos); else if (new_word->pos) error=_mi_ft_store(info,keynr,keybuf,new_word,pos); err2: my_free((char*) newlist,MYF(0)); err1: my_free((char*) oldlist,MYF(0)); err0: DBUG_RETURN(error); }
uint _mi_ft_convert_to_ft2(MI_INFO *info, uint keynr, uchar *key) { my_off_t root; DYNAMIC_ARRAY *da=info->ft1_to_ft2; MI_KEYDEF *keyinfo=&info->s->ft2_keyinfo; uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end; uint length, key_length; DBUG_ENTER("_mi_ft_convert_to_ft2"); /* we'll generate one pageful at once, and insert the rest one-by-one */ /* calculating the length of this page ...*/ length=(keyinfo->block_length-2) / keyinfo->keylength; set_if_smaller(length, da->elements); length=length * keyinfo->keylength; get_key_full_length_rdonly(key_length, key); while (_mi_ck_delete(info, keynr, key, key_length) == 0) { /* nothing to do here. _mi_ck_delete() will populate info->ft1_to_ft2 with deleted keys */ } /* creating pageful of keys */ mi_putint(info->buff,length+2,0); memcpy(info->buff+2, key_ptr, length); info->buff_used=info->page_changed=1; /* info->buff is used */ if ((root= _mi_new(info,keyinfo,DFLT_INIT_HITS)) == HA_OFFSET_ERROR || _mi_write_keypage(info,keyinfo,root,DFLT_INIT_HITS,info->buff)) DBUG_RETURN(-1); /* inserting the rest of key values */ end= (uchar*) dynamic_array_ptr(da, da->elements); for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength) if(_mi_ck_real_write_btree(info, keyinfo, key_ptr, 0, &root, SEARCH_SAME)) DBUG_RETURN(-1); /* now, writing the word key entry */ ft_intXstore(key+key_length, - (int) da->elements); _mi_dpointer(info, key+key_length+HA_FT_WLEN, root); DBUG_RETURN(_mi_ck_real_write_btree(info, info->s->keyinfo+keynr, key, 0, &info->s->state.key_root[keynr], SEARCH_SAME)); }
int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf, const uchar *oldrec, const uchar *newrec, my_off_t pos) { int error= -1; FT_WORD *oldlist,*newlist, *old_word, *new_word; const CHARSET_INFO *cs= info->s->keyinfo[keynr].seg->charset; uint key_length; int cmp, cmp2; DBUG_ENTER("_mi_ft_update"); if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, oldrec, &info->ft_memroot)) || !(new_word=newlist=_mi_ft_parserecord(info, keynr, newrec, &info->ft_memroot))) goto err; error=0; while(old_word->pos && new_word->pos) { cmp= ha_compare_text(cs, (uchar*) old_word->pos,old_word->len, (uchar*) new_word->pos,new_word->len,0,0); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); if (cmp < 0 || cmp2) { key_length=_ft_make_key(info,keynr,keybuf,old_word,pos); if ((error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length))) goto err; } if (cmp > 0 || cmp2) { key_length=_ft_make_key(info,keynr,keybuf,new_word,pos); if ((error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length))) goto err; } if (cmp<=0) old_word++; if (cmp>=0) new_word++; } if (old_word->pos) error=_mi_ft_erase(info,keynr,keybuf,old_word,pos); else if (new_word->pos) error=_mi_ft_store(info,keynr,keybuf,new_word,pos); err: free_root(&info->ft_memroot, MYF(MY_MARK_BLOCKS_FREE)); DBUG_RETURN(error); }
int mi_write(MI_INFO * info, byte * record) { uint i; int save_errno; my_off_t filepos; uchar *buff; MYISAM_SHARE *share = info->s; DBUG_ENTER("mi_write"); DBUG_PRINT("enter", ("isam: %d data: %d", info->s->kfile, info->dfile)); if (share->options & HA_OPTION_READ_ONLY_DATA) { DBUG_RETURN(my_errno = EACCES); } if (_mi_readinfo(info, F_WRLCK, 1)) DBUG_RETURN(my_errno); dont_break(); /* Dont allow SIGHUP or SIGINT */ #if !defined(NO_LOCKING) && defined(USE_RECORD_LOCK) if (!info->locked && my_lock(info->dfile, F_WRLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE) | info->lock_wait)) goto err; #endif filepos = ((share->state.dellink != HA_OFFSET_ERROR) ? share->state.dellink : info->state->data_file_length); if (share->base.reloc == (ha_rows) 1 && share->base.records == (ha_rows) 1 && info->state->records == (ha_rows) 1) { /* System file */ my_errno = HA_ERR_RECORD_FILE_FULL; goto err2; } if (info->state->key_file_length >= share->base.margin_key_file_length) { my_errno = HA_ERR_INDEX_FILE_FULL; goto err2; } if (_mi_mark_file_changed(info)) goto err2; /* Calculate and check all unique constraints */ for (i = 0; i < share->state.header.uniques; i++) { if (mi_check_unique(info, share->uniqueinfo + i, record, mi_unique_hash(share->uniqueinfo + i, record), HA_OFFSET_ERROR)) goto err2; } /* Write all keys to indextree */ buff = info->lastkey2; for (i = 0; i < share->base.keys; i++) { if (((ulonglong) 1 << i) & share->state.key_map) { if (share->concurrent_insert) { rw_wrlock(&share->key_root_lock[i]); share->keyinfo[i].version++; } if (share->keyinfo[i].flag & HA_FULLTEXT) { /* SerG *//* SerG */ if (_mi_ft_add(info, i, (char *)buff, record, filepos)) { /* SerG *//* SerG */ if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); DBUG_PRINT("error", ("Got error: %d on write", my_errno)); /* SerG */ goto err; /* SerG */ } /* SerG */ } /* SerG */ else { /* SerG */ uint key_length = _mi_make_key(info, i, buff, record, filepos); if (_mi_ck_write(info, i, buff, key_length)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); DBUG_PRINT("error", ("Got error: %d on write", my_errno)); goto err; } } if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); } } if (share->calc_checksum) info->checksum = (*share->calc_checksum) (info, record); if (!(info->opt_flag & OPT_NO_ROWS)) { if ((*share->write_record) (info, record)) goto err; share->state.checksum += info->checksum; } if (share->base.auto_key) update_auto_increment(info, record); info->update = (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); info->state->records++; info->lastpos = filepos; myisam_log_record(MI_LOG_WRITE, info, record, filepos, 0); VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(0); err: save_errno = my_errno; if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL) { info->errkey = (int)i; while (i-- > 0) { if (((ulonglong) 1 << i) & share->state.key_map) { if (share->concurrent_insert) rw_wrlock(&share->key_root_lock[i]); /* * The following code block is for text * searching by SerG */ if (share->keyinfo[i].flag & HA_FULLTEXT) { if (_mi_ft_del(info, i, (char *)buff, record, filepos)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); break; } } else { uint key_length = _mi_make_key(info, i, buff, record, filepos); if (_mi_ck_delete(info, i, buff, key_length)) { if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); break; } } if (share->concurrent_insert) rw_unlock(&share->key_root_lock[i]); } } } else mi_mark_crashed(info); info->update = (HA_STATE_CHANGED | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); my_errno = save_errno; err2: save_errno = my_errno; myisam_log_record(MI_LOG_WRITE, info, record, filepos, my_errno); VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); allow_break(); /* Allow SIGHUP & SIGINT */ DBUG_RETURN(my_errno = save_errno); } /* mi_write */