2 * Copyright (C) 1994-1996, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.5 1997-09-09 13:38:16 adam
8 * Partial port to WIN95/NT.
10 * Revision 1.4 1996/10/29 13:55:27 adam
11 * Include of zebrautl.h instead of alexutil.h.
13 * Revision 1.3 1996/10/08 13:00:41 adam
14 * Bug fix: result sets with ranked operands in boolean operations weren't
17 * Revision 1.2 1996/05/15 18:35:17 adam
18 * Implemented snot operation.
20 * Revision 1.1 1995/12/11 09:15:27 adam
21 * New set types: sand/sor/snot - ranked versions of and/or/not in
22 * ranked/semi-ranked result sets.
23 * Note: the snot not finished yet.
24 * New rset member: flag.
25 * Bug fix: r_delete in rsrel.c did free bad memory block.
36 static void *r_create_and(const struct rset_control *sel, void *parms,
38 static void *r_create_or(const struct rset_control *sel, void *parms,
40 static void *r_create_not(const struct rset_control *sel, void *parms,
42 static RSFD r_open (RSET ct, int flag);
43 static void r_close (RSFD rfd);
44 static void r_delete (RSET ct);
45 static void r_rewind (RSFD rfd);
46 static int r_count (RSET ct);
47 static int r_read (RSFD rfd, void *buf);
48 static int r_write (RSFD rfd, const void *buf);
49 static int r_score (RSFD rfd, int *score);
51 static const rset_control control_sand =
65 static const rset_control control_sor =
79 static const rset_control control_snot =
94 const rset_control *rset_kind_sand = &control_sand;
95 const rset_control *rset_kind_sor = &control_sor;
96 const rset_control *rset_kind_snot = &control_snot;
98 struct rset_bool_info {
107 int (*cmp)(const void *p1, const void *p2);
108 struct rset_bool_rfd *rfd_list;
111 struct rset_bool_rfd {
112 struct rset_bool_rfd *next;
113 struct rset_bool_info *info;
119 static void *r_create_common (const struct rset_control *sel,
120 rset_bool_parms *bool_parms, int *flags);
122 static struct rset_bool_info *qsort_info;
124 static int qcomp (const void *p1, const void *p2)
128 return qsort_info->score_buf[i2] - qsort_info->score_buf[i1];
131 static void key_add (struct rset_bool_info *info,
132 char *buf, int score)
134 if (info->key_no == info->key_max)
136 memcpy (info->key_buf + info->key_size * info->key_no,
137 buf, info->key_size);
138 info->score_buf[info->key_no] = score;
139 info->score_idx[info->key_no] = info->key_no;
143 static void *r_create_and (const struct rset_control *sel, void *parms,
150 struct rset_bool_info *info;
151 info = r_create_common (sel, parms, flags);
153 buf_l = xmalloc (info->key_size);
154 buf_r = xmalloc (info->key_size);
155 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
156 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
158 more_l = rset_read(info->rset_l, fd_l, buf_l);
159 more_r = rset_read(info->rset_r, fd_r, buf_r);
161 while (more_l || more_r)
164 int score, score_l, score_r;
166 if (more_l && more_r)
167 cmp = (*info->cmp)(buf_l, buf_r);
173 if (cmp >= -1 && cmp <= 1)
175 rset_score (info->rset_l, fd_l, &score_l);
176 rset_score (info->rset_r, fd_r, &score_r);
179 else if (score_r == -1)
182 score = score_l > score_r ? score_r : score_l;
183 key_add (info, buf_l, score);
185 more_l = rset_read (info->rset_l, fd_l, buf_l);
186 more_r = rset_read (info->rset_r, fd_r, buf_r);
189 more_r = rset_read (info->rset_r, fd_r, buf_r);
191 more_l = rset_read (info->rset_l, fd_l, buf_l);
193 rset_close (info->rset_l, fd_l);
194 rset_close (info->rset_r, fd_r);
195 rset_delete (info->rset_l);
196 rset_delete (info->rset_r);
200 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
204 static void *r_create_or (const struct rset_control *sel, void *parms,
211 struct rset_bool_info *info;
212 info = r_create_common (sel, parms, flags);
214 buf_l = xmalloc (info->key_size);
215 buf_r = xmalloc (info->key_size);
216 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
217 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
219 more_l = rset_read(info->rset_l, fd_l, buf_l);
220 more_r = rset_read(info->rset_r, fd_r, buf_r);
222 while (more_l || more_r)
225 int score, score_l, score_r;
227 if (more_l && more_r)
228 cmp = (*info->cmp)(buf_l, buf_r);
234 if (cmp >= -1 && cmp <= 1)
236 rset_score (info->rset_l, fd_l, &score_l);
237 rset_score (info->rset_r, fd_r, &score_r);
240 else if (score_r == -1)
243 score = score_r > score_l ? score_r : score_l;
244 key_add (info, buf_l, score);
246 more_l = rset_read (info->rset_l, fd_l, buf_l);
247 more_r = rset_read (info->rset_r, fd_r, buf_r);
251 rset_score (info->rset_r, fd_r, &score_r);
253 key_add (info, buf_r, score_r / 2);
254 more_r = rset_read (info->rset_r, fd_r, buf_r);
258 rset_score (info->rset_l, fd_l, &score_l);
260 key_add (info, buf_l, score_l / 2);
261 more_l = rset_read (info->rset_l, fd_l, buf_l);
264 rset_close (info->rset_l, fd_l);
265 rset_close (info->rset_r, fd_r);
266 rset_delete (info->rset_l);
267 rset_delete (info->rset_r);
271 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
275 static void *r_create_not (const struct rset_control *sel, void *parms,
282 struct rset_bool_info *info;
283 info = r_create_common (sel, parms, flags);
285 buf_l = xmalloc (info->key_size);
286 buf_r = xmalloc (info->key_size);
288 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
289 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
291 more_l = rset_read(info->rset_l, fd_l, buf_l);
292 more_r = rset_read(info->rset_r, fd_r, buf_r);
294 while (more_l || more_r)
299 if (more_l && more_r)
300 cmp = (*info->cmp)(buf_l, buf_r);
306 if (cmp >= -1 && cmp <= 1)
307 more_l = rset_read (info->rset_l, fd_l, buf_l);
310 more_r = rset_read (info->rset_r, fd_r, buf_r);
314 rset_score (info->rset_l, fd_l, &score);
315 key_add (info, buf_l, score == -1 ? 1 : score);
316 more_l = rset_read (info->rset_l, fd_l, buf_l);
319 rset_close (info->rset_l, fd_l);
320 rset_close (info->rset_r, fd_r);
322 rset_delete (info->rset_l);
323 rset_delete (info->rset_r);
327 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
331 static void *r_create_common (const struct rset_control *sel,
332 rset_bool_parms *bool_parms, int *flags)
334 struct rset_bool_info *info;
336 info = xmalloc (sizeof(*info));
337 info->key_size = bool_parms->key_size;
338 info->rset_l = bool_parms->rset_l;
339 info->rset_r = bool_parms->rset_r;
340 info->cmp = bool_parms->cmp;
341 info->rfd_list = NULL;
343 if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r))
344 *flags |= RSET_FLAG_RANKED;
346 info->key_max = rset_count(bool_parms->rset_l)
347 +rset_count(bool_parms->rset_r);
350 if (info->key_max > 1000)
351 info->key_max = 1000;
352 info->key_buf = xmalloc (info->key_size * info->key_max);
353 info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf));
354 info->score_idx = xmalloc (info->key_max * sizeof(*info->score_idx));
360 static RSFD r_open (RSET ct, int flag)
362 struct rset_bool_info *info = ct->buf;
363 struct rset_bool_rfd *rfd;
365 if (flag & RSETF_WRITE)
367 logf (LOG_FATAL, "sbool set type is read-only");
370 rfd = xmalloc (sizeof(*rfd));
371 rfd->next = info->rfd_list;
372 info->rfd_list = rfd;
382 static void r_close (RSFD rfd)
384 struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
385 struct rset_bool_rfd **rfdp;
387 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
390 *rfdp = (*rfdp)->next;
394 logf (LOG_FATAL, "r_close but no rfd match!");
398 static void r_delete (RSET ct)
400 struct rset_bool_info *info = ct->buf;
402 assert (info->rfd_list == NULL);
403 xfree (info->score_buf);
404 xfree (info->score_idx);
405 xfree (info->key_buf);
409 static void r_rewind (RSFD rfd)
411 struct rset_bool_rfd *p = rfd;
413 logf (LOG_DEBUG, "rsbool_rewind");
414 p->position = p->last_pos = 0;
417 static int r_count (RSET ct)
419 struct rset_bool_info *info = ct->buf;
424 static int r_read (RSFD rfd, void *buf)
426 struct rset_bool_rfd *p = rfd;
427 struct rset_bool_info *info = p->info;
429 if (p->position >= info->key_no)
431 if (p->flag & RSETF_SORT_RANK)
432 p->last_pos = info->score_idx[(p->position)++];
434 p->last_pos = (p->position)++;
435 memcpy (buf, info->key_buf + info->key_size * p->last_pos,
440 static int r_write (RSFD rfd, const void *buf)
442 logf (LOG_FATAL, "sbool set type is read-only");
446 static int r_score (RSFD rfd, int *score)
448 struct rset_bool_rfd *p = rfd;
449 struct rset_bool_info *info = p->info;
451 *score = info->score_buf[p->last_pos];