diff options
Diffstat (limited to 'myisam/ft_boolean_search.c')
-rw-r--r-- | myisam/ft_boolean_search.c | 240 |
1 files changed, 137 insertions, 103 deletions
diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 79fecccaaf6..32d8e7941bb 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -16,6 +16,7 @@ /* Written by Sergei A. Golubchik, who has a shared copyright to this code */ +#define FT_CORE #include "ftdefs.h" #include <queues.h> @@ -73,8 +74,9 @@ typedef struct { byte word[1]; } FTB_WORD; -typedef struct st_ftb_handler { - MI_INFO *info; +typedef struct st_ft_info { + struct _ft_vft *please; + MI_INFO *info; uint keynr; int ok; FTB_EXPR *root; @@ -85,10 +87,10 @@ typedef struct st_ftb_handler { int FTB_WORD_cmp(void *v, byte *a, byte *b) { /* ORDER BY docid, ndepth DESC */ - int i=((FTB_WORD *)a)->docid-((FTB_WORD *)b)->docid; + int i=comp(((FTB_WORD *)a)->docid, ((FTB_WORD *)b)->docid); if (!i) - i=((FTB_WORD *)b)->ndepth-((FTB_WORD *)a)->ndepth; - return sgn(i); + i=comp(((FTB_WORD *)b)->ndepth,((FTB_WORD *)a)->ndepth); + return i; } void _ftb_parse_query(FTB *ftb, byte **start, byte *end, @@ -108,70 +110,71 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end, if (! ftb->ok) return; - while (res=ftb_get_word(&start,end,&w,¶m)) + param.prev=' '; + while (res=ft_get_word(start,end,&w,¶m)) { byte r=param.plusminus; float weight=(param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)]; switch (res) { case FTB_LBR: - ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)); - ftbe->yesno=param.yesno; - ftbe->weight=weight; - ftbe->up=up; - ftbe->ythresh=0; - ftbe->docid=HA_POS_ERROR; - if (ftbw->yesno > 0) up->ythresh++; + ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)); + ftbe->yesno=param.yesno; + ftbe->weight=weight; + ftbe->up=up; + ftbe->ythresh=0; + ftbe->docid=HA_POS_ERROR; + if (ftbw->yesno > 0) up->ythresh++; _ftb_parse_query(ftb, start, end, ftbe, depth+1, - (param.yesno<0 ? depth+1 : ndepth)); + (param.yesno<0 ? depth+1 : ndepth)); break; case FTB_RBR: return; case 1: - ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root, + ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root, sizeof(FTB_WORD) + (param.trunc ? MI_MAX_KEY_BUFF : w.len+extra)); ftbw->len=w.len + !param.trunc; - ftbw->yesno=param.yesno; - ftbw->trunc=param.trunc; /* 0 or 1 */ - ftbw->weight=weight; - ftbw->up=up; - ftbw->docid=HA_POS_ERROR; - ftbw->ndepth= param.yesno<0 ? depth : ndepth; + ftbw->yesno=param.yesno; + ftbw->trunc=param.trunc; /* 0 or 1 */ + ftbw->weight=weight; + ftbw->up=up; + ftbw->docid=HA_POS_ERROR; + ftbw->ndepth= param.yesno<0 ? depth : ndepth; memcpy(ftbw->word+1, w.pos, w.len); ftbw->word[0]=w.len; - if (ftbw->yesno > 0) up->ythresh++; - /*****************************************/ - r=_mi_search(info, keyinfo, ftbw->word, ftbw->len, - SEARCH_FIND | SEARCH_PREFIX, keyroot); - if (!r) - { - r=_mi_compare_text(default_charset_info, - info->lastkey+ftbw->trunc,ftbw->len, - ftbw->word+ftbw->trunc,ftbw->len,0); - } - if (r) /* not found */ - { - if (ftbw->yesno>0 && ftbw->up->up==0) - { /* this word MUST BE present in every document returned, - so we can abort the search right now */ - ftb->ok=0; - return; - } - } - else - { - memcpy(ftbw->word, info->lastkey, info->lastkey_length); - ftbw->docid=info->lastpos; - queue_insert(& ftb->queue, (byte *)ftbw); - } - /*****************************************/ + if (ftbw->yesno > 0) up->ythresh++; + /*****************************************/ + r=_mi_search(info, keyinfo, ftbw->word, ftbw->len, + SEARCH_FIND | SEARCH_PREFIX, keyroot); + if (!r) + { + r=_mi_compare_text(default_charset_info, + info->lastkey+ftbw->trunc,ftbw->len, + ftbw->word+ftbw->trunc,ftbw->len,0); + } + if (r) /* not found */ + { + if (ftbw->yesno>0 && ftbw->up->up==0) + { /* this word MUST BE present in every document returned, + so we can abort the search right now */ + ftb->ok=0; + return; + } + } + else + { + memcpy(ftbw->word, info->lastkey, info->lastkey_length); + ftbw->docid=info->lastpos; + queue_insert(& ftb->queue, (byte *)ftbw); + } + /*****************************************/ break; } } return; } -FTB * ft_boolean_search_init(MI_INFO *info, uint keynr, byte *query, - uint query_len) +FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, + uint query_len, my_bool presort __attribute__((unused))) { FTB *ftb; FTB_EXPR *ftbe; @@ -179,11 +182,12 @@ FTB * ft_boolean_search_init(MI_INFO *info, uint keynr, byte *query, if (!(ftb=(FTB *)my_malloc(sizeof(FTB), MYF(MY_WME)))) return 0; + ftb->please=& _ft_vft_boolean; ftb->ok=1; ftb->info=info; ftb->keynr=keynr; - init_alloc_root(&ftb->mem_root, query_len,0); + init_alloc_root(&ftb->mem_root, 1024, 1024); /* hack: instead of init_queue, we'll use reinit queue to be able * to alloc queue with alloc_root() @@ -201,7 +205,7 @@ FTB * ft_boolean_search_init(MI_INFO *info, uint keynr, byte *query, return ftb; } -int ft_boolean_search_next(FTB *ftb, char *record) +int ft_boolean_read_next(FT_INFO *ftb, char *record) { FTB_EXPR *ftbe, *up; FTB_WORD *ftbw; @@ -218,61 +222,64 @@ int ft_boolean_search_next(FTB *ftb, char *record) return my_errno; /* black magic OFF */ - while(ftb->ok && ftb->queue.elements) - { - curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid; + if (!ftb->queue.elements) + return my_errno=HA_ERR_END_OF_FILE; + while(ftb->ok && + (curdoc=((FTB_WORD *)queue_top(& ftb->queue))->docid) != HA_POS_ERROR) + { while (curdoc==(ftbw=(FTB_WORD *)queue_top(& ftb->queue))->docid) { float weight=ftbw->weight; - uint yn=ftbw->yesno; + int yn=ftbw->yesno; for (ftbe=ftbw->up; ftbe; ftbe=ftbe->up) { - if (ftbe->docid != curdoc) - { - ftbe->cur_weight=ftbe->yesses=ftbe->nos=0; - ftbe->docid=curdoc; - } - if (yn>0) - { - ftbe->cur_weight+=weight; - if (++ftbe->yesses >= ftbe->ythresh && !ftbe->nos) - { + if (ftbe->docid != curdoc) + { + ftbe->cur_weight=ftbe->yesses=ftbe->nos=0; + ftbe->docid=curdoc; + } + if (yn>0) + { + ftbe->cur_weight+=weight; + if (++ftbe->yesses >= ftbe->ythresh && !ftbe->nos) + { yn=ftbe->yesno; - weight=ftbe->cur_weight*ftbe->weight; - } - else - break; - } - else - if (yn<0) - { - /* NOTE: special sort function of queue assures that all yn<0 - * events for every particular subexpression will happen - * BEFORE all yn>=0 events. So no already matched expression - * can become not-matched again. - */ - ++ftbe->nos; - break; - } - else + weight=ftbe->cur_weight*ftbe->weight; + } + else + break; + } + else + if (yn<0) + { + /* NOTE: special sort function of queue assures that all yn<0 + * events for every particular subexpression will + * "auto-magically" happen BEFORE all yn>=0 events. So no + * already matched expression can become not-matched again. + */ + ++ftbe->nos; + break; + } + else /* if (yn==0) */ - { - if (ftbe->yesses >= ftbe->ythresh && !ftbe->nos) - { + { + if (ftbe->yesses >= ftbe->ythresh && !ftbe->nos) + { yn=ftbe->yesno; - weight*=ftbe->weight; - } - else - { - ftbe->cur_weight+=weight; - break; - } - } + ftbe->cur_weight=weight; + weight*=ftbe->weight; + } + else + { + ftbe->cur_weight+=weight; + break; + } + } } /* update queue */ r=_mi_search(info, keyinfo, ftbw->word, ftbw->len, - SEARCH_FIND | SEARCH_PREFIX, keyroot); + SEARCH_BIGGER , keyroot); if (!r) { r=_mi_compare_text(default_charset_info, @@ -281,19 +288,19 @@ int ft_boolean_search_next(FTB *ftb, char *record) } if (r) /* not found */ { - queue_remove(& ftb->queue, 0); - if (ftbw->yesno>0 && ftbw->up->up==0) - { /* this word MUST BE present in every document returned, - so we can stop the search right now */ - ftb->ok=0; - } + ftbw->docid=HA_POS_ERROR; + if (ftbw->yesno>0 && ftbw->up->up==0) + { /* this word MUST BE present in every document returned, + so we can stop the search right now */ + ftb->ok=0; + } } else { memcpy(ftbw->word, info->lastkey, info->lastkey_length); ftbw->docid=info->lastpos; - queue_replaced(& ftb->queue); } + queue_replaced(& ftb->queue); } ftbe=ftb->root; @@ -305,8 +312,8 @@ int ft_boolean_search_next(FTB *ftb, char *record) /* info->lastpos=curdoc; */ /* do I need this ? */ if (!(*info->read_record)(info,curdoc,record)) { - info->update|= HA_STATE_AKTIV; /* Record is read */ - return 0; + info->update|= HA_STATE_AKTIV; /* Record is read */ + return 0; } return my_errno; } @@ -314,3 +321,30 @@ int ft_boolean_search_next(FTB *ftb, char *record) return my_errno=HA_ERR_END_OF_FILE; } +float ft_boolean_find_relevance(FT_INFO *ftb, my_off_t docid) +{ + fprintf(stderr, "ft_boolean_find_relevance called!\n"); + return -1.0; /* to be done via str scan */ +} + +void ft_boolean_close_search(FT_INFO *ftb) +{ + free_root(& ftb->mem_root, MYF(0)); + my_free((gptr)ftb,MYF(0)); +} + +float ft_boolean_get_relevance(FT_INFO *ftb) +{ + return ftb->root->cur_weight; +} + +my_off_t ft_boolean_get_docid(FT_INFO *ftb) +{ + return HA_POS_ERROR; +} + +void ft_boolean_reinit_search(FT_INFO *ftb) +{ + fprintf(stderr, "ft_boolean_reinit_search called!\n"); +} + |