diff options
Diffstat (limited to 'myisam/ft_update.c')
-rw-r--r-- | myisam/ft_update.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/myisam/ft_update.c b/myisam/ft_update.c index 658ea9282f3..f8f1d7769aa 100644 --- a/myisam/ft_update.c +++ b/myisam/ft_update.c @@ -29,14 +29,16 @@ /* parses a document i.e. calls _mi_ft_parse for every keyseg */ -static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf, +FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf, const byte *record) { - TREE *parsed=NULL; + TREE *parsed, ptree; MI_KEYSEG *keyseg; byte *pos; uint i; + bzero(parsed=&ptree, sizeof(ptree)); + keyseg=info->s->keyinfo[keynr].seg; for (i=info->s->keyinfo[keynr].keysegs-FT_SEGS ; i-- ; ) { @@ -64,7 +66,7 @@ static FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, byte *keybuf, return NULL; } /* Handle the case where all columns are NULL */ - if (!parsed && !(parsed=ft_parse(0, (byte*) "", 0))) + if (!is_tree_inited(parsed) && !(parsed=ft_parse(parsed, (byte*) "", 0))) return NULL; return ft_linearize(info, keynr, keybuf, parsed); } @@ -151,6 +153,69 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL; } +/* update a document entry */ +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; + uint key_length; + uint cmp; + + if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, keybuf, oldrec))) + goto err0; + if (!(new_word=newlist=_mi_ft_parserecord(info, keynr, keybuf, newrec))) + goto err1; + + while(old_word->pos && new_word->pos) + { + cmp=_mi_compare_text(default_charset_info, + (uchar*) old_word->pos,old_word->len, + (uchar*) new_word->pos,new_word->len,0); + if (cmp==0) + { + double p=(old_word->weight-new_word->weight)/ + (old_word->weight+new_word->weight); + if (p<1e-5) + cmp=0; + else + cmp=sgn(p); + } + else + cmp=sgn(cmp); + + switch (cmp) { + case -1: + key_length=_ft_make_key(info,keynr,keybuf,old_word,pos); + if (error=_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)) + goto err2; + old_word++; + break; + case 0: + old_word++; + new_word++; + break; + case 1: + key_length=_ft_make_key(info,keynr,keybuf,new_word,pos); + if (error=_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)) + goto err2; + new_word++; + break; + } + } + 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: + return error; +} + /* adds a document to the collection */ int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, my_off_t pos) |