コード例 #1
0
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);
}
コード例 #2
0
ファイル: ft_update.c プロジェクト: isleon/Jaxer
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);
}
コード例 #3
0
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));
}
コード例 #4
0
ファイル: ft_update.c プロジェクト: Baoxiyi-Github/Mysql
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);
}
コード例 #5
0
ファイル: mi_write.c プロジェクト: NickeyWoo/mysql-3.23.49
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 */