1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; either version 2 of the License, or
6
(at your option) any later version.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
21
/* search with boolean queries */
23
typedef struct st_all_in_one {
31
uint total_yes, total_no;
34
typedef struct st_ft_superdoc {
44
static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
46
if (p1->doc.dpos < p2->doc.dpos)
48
if (p1->doc.dpos == p2->doc.dpos)
53
static int walk_and_copy(FT_SUPERDOC *from,
54
uint32 count __attribute__((unused)), FT_DOC **to)
56
if (from->yes == from->aio->total_yes && !from->no)
58
(*to)->dpos=from->doc.dpos;
59
(*to)->weight=from->doc.weight;
65
static double _wghts[11]={
77
static double *wghts=_wghts+5; // wghts[i] = 1.5**i
79
static double _nwghts[11]={
91
static double *nwghts=_nwghts+5; // nwghts[i] = -0.5*1.5**i
93
int do_boolean(ALL_IN_ONE *aio, uint nested,
94
int yesno, int plusminus, bool pmsign)
98
FT_SUPERDOC sdoc, *sptr;
105
#endif /* EVAL_RUN */
109
for(wno=1; res=ft_get_word(&aio->start,aio->end,&w,¶m); wno++)
111
r=plusminus+param.plusminus;
112
if (param.pmsign^pmsign)
113
w.weight=nwghts[(r>5)?5:((r<-5)?-5:r)];
115
w.weight=wghts[(r>5)?5:((r<-5)?-5:r)];
117
if (param.yesno>0) aio->total_yes++;
118
if (param.yesno<0) aio->total_no++;
122
//if (do_boolean(aio,nested+1,my_yesno,plusminus+my_plusminus))
127
keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,&w,0);
130
r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
131
SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
136
r=_mi_compare_text(default_charset_info,
137
aio->info->lastkey+1,keylen-1,
138
aio->keybuff+1,keylen-1,0);
140
r=_mi_compare_text(default_charset_info,
141
aio->info->lastkey,keylen,
142
aio->keybuff,keylen,0);
145
sdoc.doc.dpos=aio->info->lastpos;
147
/* saving document matched into dtree */
148
if (!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
150
sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
152
if (selem->count==1) /* document's first match */
154
sptr->yes=sptr->no=sptr->doc.weight=0;
158
if (sptr->wno != wno)
160
if (param.yesno>0) sptr->yes++;
161
if (param.yesno<0) sptr->no++;
164
sptr->doc.weight+=w.weight;
166
if (_mi_test_if_changed(aio->info) == 0)
167
r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
168
aio->info->lastkey_length, SEARCH_BIGGER,
171
r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
172
aio->info->lastkey_length, SEARCH_BIGGER,
183
FT_DOCLIST *ft_boolean_search(MI_INFO *info, uint keynr, byte *query,
188
FT_DOCLIST *dlist=NULL;
192
aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
193
aio.keyinfo=aio.info->s->keyinfo+keynr;
194
aio.key_root=aio.info->s->state.key_root[keynr];
196
aio.end=query+query_len;
197
aio.total_yes=aio.total_no=0;
199
init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
202
if (do_boolean(&aio,0,0,0,0))
205
dlist=(FT_DOCLIST *)my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),MYF(0));
209
dlist->ndocs=aio.dtree.elements_in_tree;
211
dlist->info=aio.info;
214
tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr, left_root_right);
216
dlist->ndocs=dptr - dlist->doc;
219
delete_tree(&aio.dtree);