~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to myisam/ft_boolean_search.c

  • Committer: sasha at sashanet
  • Date: 2001-04-12 01:09:00 UTC
  • mfrom: (669.1.1)
  • Revision ID: sp1r-sasha@mysql.sashanet.com-20010412010900-14282
Ugly merge of 3.23 changes into 4.0 - fix up needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
 
2
 
 
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.
 
7
 
 
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.
 
12
 
 
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 */
 
16
 
 
17
/* Written by Sergei A. Golubchik, who has a shared copyright to this code */
 
18
 
 
19
#include "ftdefs.h"
 
20
 
 
21
/* search with boolean queries */
 
22
 
 
23
typedef struct st_all_in_one {
 
24
  MI_INFO    *info;
 
25
  uint        keynr;
 
26
  uchar      *keybuff;
 
27
  MI_KEYDEF  *keyinfo;
 
28
  my_off_t    key_root;
 
29
  TREE        dtree;
 
30
  byte       *start, *end;
 
31
  uint        total_yes, total_no;
 
32
} ALL_IN_ONE;
 
33
 
 
34
typedef struct st_ft_superdoc {
 
35
    FT_DOC   doc;
 
36
    //FT_WORD *word_ptr;
 
37
    //double   tmp_weight;
 
38
    uint     yes;
 
39
    uint     no;
 
40
    uint     wno;
 
41
    ALL_IN_ONE *aio;
 
42
} FT_SUPERDOC;
 
43
 
 
44
static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
 
45
{
 
46
  if (p1->doc.dpos < p2->doc.dpos)
 
47
    return -1;
 
48
  if (p1->doc.dpos == p2->doc.dpos)
 
49
    return 0;
 
50
  return 1;
 
51
}
 
52
 
 
53
static int walk_and_copy(FT_SUPERDOC *from,
 
54
                         uint32 count __attribute__((unused)), FT_DOC **to)
 
55
{
 
56
    if (from->yes == from->aio->total_yes && !from->no)
 
57
    {
 
58
      (*to)->dpos=from->doc.dpos;
 
59
      (*to)->weight=from->doc.weight;
 
60
      (*to)++;
 
61
    }
 
62
    return 0;
 
63
}
 
64
 
 
65
static double _wghts[11]={
 
66
  0.131687242798354,
 
67
  0.197530864197531,
 
68
  0.296296296296296,
 
69
  0.444444444444444,
 
70
  0.666666666666667,
 
71
  1.000000000000000,
 
72
  1.500000000000000,
 
73
  2.250000000000000,
 
74
  3.375000000000000,
 
75
  5.062500000000000,
 
76
  7.593750000000000};
 
77
static double *wghts=_wghts+5; // wghts[i] = 1.5**i
 
78
 
 
79
static double _nwghts[11]={
 
80
 -0.065843621399177,
 
81
 -0.098765432098766,
 
82
 -0.148148148148148,
 
83
 -0.222222222222222,
 
84
 -0.333333333333334,
 
85
 -0.500000000000000,
 
86
 -0.750000000000000,
 
87
 -1.125000000000000,
 
88
 -1.687500000000000,
 
89
 -2.531250000000000,
 
90
 -3.796875000000000};
 
91
static double *nwghts=_nwghts+5; // nwghts[i] = -0.5*1.5**i
 
92
 
 
93
int do_boolean(ALL_IN_ONE *aio, uint nested,
 
94
                int yesno, int plusminus, bool pmsign)
 
95
{
 
96
  int r, res;
 
97
  uint keylen, wno;
 
98
  FT_SUPERDOC  sdoc, *sptr;
 
99
  TREE_ELEMENT *selem;
 
100
  FT_WORD w;
 
101
  FTB_PARAM param;
 
102
 
 
103
#ifdef EVAL_RUN
 
104
  return 1;
 
105
#endif /* EVAL_RUN */
 
106
 
 
107
  param.prev=' ';
 
108
 
 
109
  for(wno=1; res=ft_get_word(&aio->start,aio->end,&w,&param); wno++)
 
110
  {
 
111
    r=plusminus+param.plusminus;
 
112
    if (param.pmsign^pmsign)
 
113
      w.weight=nwghts[(r>5)?5:((r<-5)?-5:r)];
 
114
    else
 
115
      w.weight=wghts[(r>5)?5:((r<-5)?-5:r)];
 
116
 
 
117
    if (param.yesno>0) aio->total_yes++;
 
118
    if (param.yesno<0) aio->total_no++;
 
119
 
 
120
    switch (res) {
 
121
    case FTB_LBR:    // (
 
122
      //if (do_boolean(aio,nested+1,my_yesno,plusminus+my_plusminus))
 
123
      //  return 1;
 
124
      // ???
 
125
      break;
 
126
    case 1:          // word
 
127
      keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,&w,0);
 
128
      keylen-=HA_FT_WLEN;
 
129
 
 
130
      r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
 
131
                   SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
 
132
 
 
133
      while (!r)
 
134
      {
 
135
        if (param.trunc)
 
136
           r=_mi_compare_text(default_charset_info,
 
137
                              aio->info->lastkey+1,keylen-1,
 
138
                              aio->keybuff+1,keylen-1,0);
 
139
        else
 
140
           r=_mi_compare_text(default_charset_info,
 
141
                              aio->info->lastkey,keylen,
 
142
                              aio->keybuff,keylen,0);
 
143
        if (r) break;
 
144
 
 
145
        sdoc.doc.dpos=aio->info->lastpos;
 
146
 
 
147
        /* saving document matched into dtree */
 
148
        if (!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
 
149
 
 
150
        sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
 
151
 
 
152
        if (selem->count==1) /* document's first match */
 
153
        {
 
154
          sptr->yes=sptr->no=sptr->doc.weight=0;
 
155
          sptr->aio=aio;
 
156
          sptr->wno=0;
 
157
        }
 
158
        if (sptr->wno != wno)
 
159
        {
 
160
          if (param.yesno>0) sptr->yes++;
 
161
          if (param.yesno<0) sptr->no++;
 
162
          sptr->wno=wno;
 
163
        }
 
164
        sptr->doc.weight+=w.weight;
 
165
 
 
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,
 
169
                            aio->key_root);
 
170
        else
 
171
          r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
 
172
                       aio->info->lastkey_length, SEARCH_BIGGER,
 
173
                       aio->key_root);
 
174
      }
 
175
      break;
 
176
    case FTB_RBR:    // )
 
177
      break;
 
178
    }
 
179
  }
 
180
  return 0;
 
181
}
 
182
 
 
183
FT_DOCLIST *ft_boolean_search(MI_INFO *info, uint keynr, byte *query,
 
184
                              uint query_len)
 
185
{
 
186
  ALL_IN_ONE aio;
 
187
  FT_DOC     *dptr;
 
188
  FT_DOCLIST *dlist=NULL;
 
189
 
 
190
  aio.info=info;
 
191
  aio.keynr=keynr;
 
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];
 
195
  aio.start=query;
 
196
  aio.end=query+query_len;
 
197
  aio.total_yes=aio.total_no=0;
 
198
 
 
199
  init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
 
200
            NULL);
 
201
 
 
202
  if (do_boolean(&aio,0,0,0,0))
 
203
    goto err;
 
204
 
 
205
  dlist=(FT_DOCLIST *)my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*(aio.dtree.elements_in_tree-1),MYF(0));
 
206
  if(!dlist)
 
207
    goto err;
 
208
 
 
209
  dlist->ndocs=aio.dtree.elements_in_tree;
 
210
  dlist->curdoc=-1;
 
211
  dlist->info=aio.info;
 
212
  dptr=dlist->doc;
 
213
 
 
214
  tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr, left_root_right);
 
215
 
 
216
  dlist->ndocs=dptr - dlist->doc;
 
217
 
 
218
err:
 
219
  delete_tree(&aio.dtree);
 
220
  return dlist;
 
221
}
 
222