~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to myisam/ft_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:
18
18
 
19
19
#include "ftdefs.h"
20
20
 
21
 
/* queries isam and returns list of documents matched */
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
 
} ALL_IN_ONE;
31
 
 
32
 
typedef struct st_ft_superdoc {
33
 
    FT_DOC   doc;
34
 
    FT_WORD *word_ptr;
35
 
    double   tmp_weight;
36
 
} FT_SUPERDOC;
37
 
 
38
 
static int FT_SUPERDOC_cmp(FT_SUPERDOC *p1, FT_SUPERDOC *p2)
39
 
{
40
 
  if (p1->doc.dpos < p2->doc.dpos)
41
 
    return -1;
42
 
  if (p1->doc.dpos == p2->doc.dpos)
43
 
    return 0;
44
 
  return 1;
45
 
}
46
 
 
47
 
static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
48
 
{
49
 
  uint         keylen, r, doc_cnt;
50
 
#ifdef EVAL_RUN
51
 
  uint         cnt;
52
 
  double       sum, sum2, suml;
53
 
#endif /* EVAL_RUN */
54
 
  FT_SUPERDOC  sdoc, *sptr;
55
 
  TREE_ELEMENT *selem;
56
 
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
57
 
  float tmp_weight;
58
 
#else
59
 
#error
60
 
#endif
61
 
 
62
 
  word->weight=LWS_FOR_QUERY;
63
 
 
64
 
  keylen=_ft_make_key(aio->info,aio->keynr,(char*) aio->keybuff,word,0);
65
 
#ifdef EVAL_RUN
66
 
  keylen-=1+HA_FT_WLEN;
67
 
#else /* EVAL_RUN */
68
 
  keylen-=HA_FT_WLEN;
69
 
#endif /* EVAL_RUN */
70
 
 
71
 
#ifdef EVAL_RUN
72
 
  sum=sum2=suml=
73
 
#endif /* EVAL_RUN */
74
 
  doc_cnt=0;
75
 
 
76
 
  r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
77
 
               SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
78
 
 
79
 
  while(!r)
80
 
  {
81
 
    if (_mi_compare_text(default_charset_info,
82
 
                         aio->info->lastkey,keylen,
83
 
                         aio->keybuff,keylen,0)) break;
84
 
 
85
 
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
86
 
#ifdef EVAL_RUN
87
 
    mi_float4get(tmp_weight,aio->info->lastkey+keylen+1);
88
 
#else /* EVAL_RUN */
89
 
    mi_float4get(tmp_weight,aio->info->lastkey+keylen);
90
 
#endif /* EVAL_RUN */
91
 
#else
92
 
#error
93
 
#endif
94
 
    if(tmp_weight==0) return doc_cnt; /* stopword, doc_cnt should be 0 */
95
 
 
96
 
#ifdef EVAL_RUN
97
 
    cnt=*(byte *)(aio->info->lastkey+keylen);
98
 
#endif /* EVAL_RUN */
99
 
 
100
 
    sdoc.doc.dpos=aio->info->lastpos;
101
 
 
102
 
    /* saving document matched into dtree */
103
 
    if(!(selem=tree_insert(&aio->dtree, &sdoc, 0))) return 1;
104
 
 
105
 
    sptr=(FT_SUPERDOC *)ELEMENT_KEY((&aio->dtree), selem);
106
 
 
107
 
    if(selem->count==1) /* document's first match */
108
 
      sptr->doc.weight=0;
109
 
    else
110
 
      sptr->doc.weight+=sptr->tmp_weight*sptr->word_ptr->weight;
111
 
 
112
 
    sptr->word_ptr=word;
113
 
    sptr->tmp_weight=tmp_weight;
114
 
 
115
 
    doc_cnt++;
116
 
#ifdef EVAL_RUN
117
 
    sum +=cnt;
118
 
    sum2+=cnt*cnt;
119
 
    suml+=cnt*log(cnt);
120
 
#endif /* EVAL_RUN */
121
 
 
122
 
    if (_mi_test_if_changed(aio->info) == 0)
123
 
        r=_mi_search_next(aio->info, aio->keyinfo, aio->info->lastkey,
124
 
                          aio->info->lastkey_length, SEARCH_BIGGER,
125
 
                          aio->key_root);
126
 
    else
127
 
        r=_mi_search(aio->info, aio->keyinfo, aio->info->lastkey,
128
 
                     aio->info->lastkey_length, SEARCH_BIGGER,
129
 
                     aio->key_root);
130
 
  }
131
 
  if(doc_cnt) {
132
 
    word->weight*=GWS_IN_USE;
133
 
    if(word->weight < 0) word->weight=0;
134
 
  }
135
 
 
136
 
  return 0;
137
 
}
138
 
 
139
 
static int walk_and_copy(FT_SUPERDOC *from,
140
 
                         uint32 count __attribute__((unused)), FT_DOC **to)
141
 
{
142
 
    from->doc.weight+=from->tmp_weight*from->word_ptr->weight;
143
 
    (*to)->dpos=from->doc.dpos;
144
 
    (*to)->weight=from->doc.weight;
145
 
    (*to)++;
146
 
    return 0;
147
 
}
 
21
/* queries myisam and returns list of documents matched */
148
22
 
149
23
static int FT_DOC_cmp(FT_DOC *a, FT_DOC *b)
150
24
{
151
25
    return sgn(b->weight - a->weight);
152
26
}
153
27
 
154
 
FT_DOCLIST * ft_init_search(void *info, uint keynr, byte *key,
155
 
                            uint key_len, my_bool presort)
 
28
FT_DOCLIST *ft_init_search(void *info, uint keynr, byte *query,
 
29
                            uint query_len, my_bool presort)
156
30
{
157
 
  TREE       *wtree;
158
 
  ALL_IN_ONE aio;
159
31
  FT_DOCLIST *dlist;
160
 
  FT_DOC     *dptr;
161
32
  my_off_t saved_lastpos=((MI_INFO *)info)->lastpos;
162
33
 
163
34
/* black magic ON */
167
38
    return NULL;
168
39
/* black magic OFF */
169
40
 
170
 
  dlist=NULL;
171
 
  aio.info=(MI_INFO *)info;
172
 
  aio.keynr=keynr;
173
 
  aio.keybuff=aio.info->lastkey+aio.info->s->base.max_key_length;
174
 
  aio.keyinfo=aio.info->s->keyinfo+keynr;
175
 
  aio.key_root=aio.info->s->state.key_root[keynr];
176
 
 
177
 
  if (!(wtree=ft_parse(NULL,key,key_len))) return NULL;
178
 
 
179
 
  init_tree(&aio.dtree,0,sizeof(FT_SUPERDOC),(qsort_cmp)&FT_SUPERDOC_cmp,0,
180
 
            NULL);
181
 
 
182
 
  if (tree_walk(wtree, (tree_walk_action)&walk_and_match, &aio,
183
 
                left_root_right))
184
 
    goto err;
185
 
 
186
 
  dlist=(FT_DOCLIST *) my_malloc(sizeof(FT_DOCLIST)+sizeof(FT_DOC)*
187
 
                                 (aio.dtree.elements_in_tree-1),MYF(0));
188
 
  if (!dlist)
189
 
    goto err;
190
 
 
191
 
  dlist->ndocs=aio.dtree.elements_in_tree;
192
 
  dlist->curdoc=-1;
193
 
  dlist->info=aio.info;
194
 
  dptr=dlist->doc;
195
 
 
196
 
  tree_walk(&aio.dtree, (tree_walk_action)&walk_and_copy, &dptr,
197
 
            left_root_right);
198
 
 
199
 
  if (presort)
 
41
  if (is_boolean(query, query_len))
 
42
    dlist=ft_boolean_search(info,keynr,query,query_len);
 
43
  else
 
44
    dlist=ft_nlq_search(info,keynr,query,query_len);
 
45
 
 
46
  if(dlist && presort)
200
47
  {
201
48
    qsort(dlist->doc, dlist->ndocs, sizeof(FT_DOC), (qsort_cmp)&FT_DOC_cmp);
202
49
  }
203
50
 
204
 
err:
205
 
  delete_tree(&aio.dtree);
206
 
  delete_tree(wtree);
207
 
  my_free((char*) wtree,MYF(0));
208
51
  ((MI_INFO *)info)->lastpos=saved_lastpos;
209
52
  return dlist;
210
53
}