2 * Copyright (C) 1994-1996, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.6 1997-12-18 10:54:25 adam
8 * New method result set method rs_hits that returns the number of
9 * hits in result-set (if known). The ranked result set returns real
10 * number of hits but only when not combined with other operands.
12 * Revision 1.5 1997/09/09 13:38:16 adam
13 * Partial port to WIN95/NT.
15 * Revision 1.4 1996/10/29 13:55:27 adam
16 * Include of zebrautl.h instead of alexutil.h.
18 * Revision 1.3 1996/10/08 13:00:41 adam
19 * Bug fix: result sets with ranked operands in boolean operations weren't
22 * Revision 1.2 1996/05/15 18:35:17 adam
23 * Implemented snot operation.
25 * Revision 1.1 1995/12/11 09:15:27 adam
26 * New set types: sand/sor/snot - ranked versions of and/or/not in
27 * ranked/semi-ranked result sets.
28 * Note: the snot not finished yet.
29 * New rset member: flag.
30 * Bug fix: r_delete in rsrel.c did free bad memory block.
41 static void *r_create_and(const struct rset_control *sel, void *parms,
43 static void *r_create_or(const struct rset_control *sel, void *parms,
45 static void *r_create_not(const struct rset_control *sel, void *parms,
47 static RSFD r_open (RSET ct, int flag);
48 static void r_close (RSFD rfd);
49 static void r_delete (RSET ct);
50 static void r_rewind (RSFD rfd);
51 static int r_count (RSET ct);
52 static int r_hits (RSET ct, void *oi);
53 static int r_read (RSFD rfd, void *buf);
54 static int r_write (RSFD rfd, const void *buf);
55 static int r_score (RSFD rfd, int *score);
57 static const rset_control control_sand =
72 static const rset_control control_sor =
87 static const rset_control control_snot =
103 const rset_control *rset_kind_sand = &control_sand;
104 const rset_control *rset_kind_sor = &control_sor;
105 const rset_control *rset_kind_snot = &control_snot;
107 struct rset_bool_info {
116 int (*cmp)(const void *p1, const void *p2);
117 struct rset_bool_rfd *rfd_list;
120 struct rset_bool_rfd {
121 struct rset_bool_rfd *next;
122 struct rset_bool_info *info;
128 static void *r_create_common (const struct rset_control *sel,
129 rset_bool_parms *bool_parms, int *flags);
131 static struct rset_bool_info *qsort_info;
133 static int qcomp (const void *p1, const void *p2)
137 return qsort_info->score_buf[i2] - qsort_info->score_buf[i1];
140 static void key_add (struct rset_bool_info *info,
141 char *buf, int score)
143 if (info->key_no == info->key_max)
145 memcpy (info->key_buf + info->key_size * info->key_no,
146 buf, info->key_size);
147 info->score_buf[info->key_no] = score;
148 info->score_idx[info->key_no] = info->key_no;
152 static void *r_create_and (const struct rset_control *sel, void *parms,
159 struct rset_bool_info *info;
160 info = r_create_common (sel, parms, flags);
162 buf_l = xmalloc (info->key_size);
163 buf_r = xmalloc (info->key_size);
164 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
165 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
167 more_l = rset_read(info->rset_l, fd_l, buf_l);
168 more_r = rset_read(info->rset_r, fd_r, buf_r);
170 while (more_l || more_r)
173 int score, score_l, score_r;
175 if (more_l && more_r)
176 cmp = (*info->cmp)(buf_l, buf_r);
182 if (cmp >= -1 && cmp <= 1)
184 rset_score (info->rset_l, fd_l, &score_l);
185 rset_score (info->rset_r, fd_r, &score_r);
188 else if (score_r == -1)
191 score = score_l > score_r ? score_r : score_l;
192 key_add (info, buf_l, score);
194 more_l = rset_read (info->rset_l, fd_l, buf_l);
195 more_r = rset_read (info->rset_r, fd_r, buf_r);
198 more_r = rset_read (info->rset_r, fd_r, buf_r);
200 more_l = rset_read (info->rset_l, fd_l, buf_l);
202 rset_close (info->rset_l, fd_l);
203 rset_close (info->rset_r, fd_r);
204 rset_delete (info->rset_l);
205 rset_delete (info->rset_r);
209 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
213 static void *r_create_or (const struct rset_control *sel, void *parms,
220 struct rset_bool_info *info;
221 info = r_create_common (sel, parms, flags);
223 buf_l = xmalloc (info->key_size);
224 buf_r = xmalloc (info->key_size);
225 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
226 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
228 more_l = rset_read(info->rset_l, fd_l, buf_l);
229 more_r = rset_read(info->rset_r, fd_r, buf_r);
231 while (more_l || more_r)
234 int score, score_l, score_r;
236 if (more_l && more_r)
237 cmp = (*info->cmp)(buf_l, buf_r);
243 if (cmp >= -1 && cmp <= 1)
245 rset_score (info->rset_l, fd_l, &score_l);
246 rset_score (info->rset_r, fd_r, &score_r);
249 else if (score_r == -1)
252 score = score_r > score_l ? score_r : score_l;
253 key_add (info, buf_l, score);
255 more_l = rset_read (info->rset_l, fd_l, buf_l);
256 more_r = rset_read (info->rset_r, fd_r, buf_r);
260 rset_score (info->rset_r, fd_r, &score_r);
262 key_add (info, buf_r, score_r / 2);
263 more_r = rset_read (info->rset_r, fd_r, buf_r);
267 rset_score (info->rset_l, fd_l, &score_l);
269 key_add (info, buf_l, score_l / 2);
270 more_l = rset_read (info->rset_l, fd_l, buf_l);
273 rset_close (info->rset_l, fd_l);
274 rset_close (info->rset_r, fd_r);
275 rset_delete (info->rset_l);
276 rset_delete (info->rset_r);
280 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
284 static void *r_create_not (const struct rset_control *sel, void *parms,
291 struct rset_bool_info *info;
292 info = r_create_common (sel, parms, flags);
294 buf_l = xmalloc (info->key_size);
295 buf_r = xmalloc (info->key_size);
297 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
298 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
300 more_l = rset_read(info->rset_l, fd_l, buf_l);
301 more_r = rset_read(info->rset_r, fd_r, buf_r);
303 while (more_l || more_r)
308 if (more_l && more_r)
309 cmp = (*info->cmp)(buf_l, buf_r);
315 if (cmp >= -1 && cmp <= 1)
316 more_l = rset_read (info->rset_l, fd_l, buf_l);
319 more_r = rset_read (info->rset_r, fd_r, buf_r);
323 rset_score (info->rset_l, fd_l, &score);
324 key_add (info, buf_l, score == -1 ? 1 : score);
325 more_l = rset_read (info->rset_l, fd_l, buf_l);
328 rset_close (info->rset_l, fd_l);
329 rset_close (info->rset_r, fd_r);
331 rset_delete (info->rset_l);
332 rset_delete (info->rset_r);
336 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
340 static void *r_create_common (const struct rset_control *sel,
341 rset_bool_parms *bool_parms, int *flags)
343 struct rset_bool_info *info;
345 info = xmalloc (sizeof(*info));
346 info->key_size = bool_parms->key_size;
347 info->rset_l = bool_parms->rset_l;
348 info->rset_r = bool_parms->rset_r;
349 info->cmp = bool_parms->cmp;
350 info->rfd_list = NULL;
352 if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r))
353 *flags |= RSET_FLAG_RANKED;
355 info->key_max = rset_count(bool_parms->rset_l)
356 +rset_count(bool_parms->rset_r);
359 if (info->key_max > 1000)
360 info->key_max = 1000;
361 info->key_buf = xmalloc (info->key_size * info->key_max);
362 info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf));
363 info->score_idx = xmalloc (info->key_max * sizeof(*info->score_idx));
369 static RSFD r_open (RSET ct, int flag)
371 struct rset_bool_info *info = ct->buf;
372 struct rset_bool_rfd *rfd;
374 if (flag & RSETF_WRITE)
376 logf (LOG_FATAL, "sbool set type is read-only");
379 rfd = xmalloc (sizeof(*rfd));
380 rfd->next = info->rfd_list;
381 info->rfd_list = rfd;
391 static void r_close (RSFD rfd)
393 struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
394 struct rset_bool_rfd **rfdp;
396 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
399 *rfdp = (*rfdp)->next;
403 logf (LOG_FATAL, "r_close but no rfd match!");
407 static void r_delete (RSET ct)
409 struct rset_bool_info *info = ct->buf;
411 assert (info->rfd_list == NULL);
412 xfree (info->score_buf);
413 xfree (info->score_idx);
414 xfree (info->key_buf);
418 static void r_rewind (RSFD rfd)
420 struct rset_bool_rfd *p = rfd;
422 logf (LOG_DEBUG, "rsbool_rewind");
423 p->position = p->last_pos = 0;
426 static int r_count (RSET ct)
428 struct rset_bool_info *info = ct->buf;
433 static int r_hits (RSET ct, void *oi)
438 static int r_read (RSFD rfd, void *buf)
440 struct rset_bool_rfd *p = rfd;
441 struct rset_bool_info *info = p->info;
443 if (p->position >= info->key_no)
445 if (p->flag & RSETF_SORT_RANK)
446 p->last_pos = info->score_idx[(p->position)++];
448 p->last_pos = (p->position)++;
449 memcpy (buf, info->key_buf + info->key_size * p->last_pos,
454 static int r_write (RSFD rfd, const void *buf)
456 logf (LOG_FATAL, "sbool set type is read-only");
460 static int r_score (RSFD rfd, int *score)
462 struct rset_bool_rfd *p = rfd;
463 struct rset_bool_info *info = p->info;
465 *score = info->score_buf[p->last_pos];