2 * Copyright (C) 1994-1996, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.3 1996-10-08 13:00:41 adam
8 * Bug fix: result sets with ranked operands in boolean operations weren't
11 * Revision 1.2 1996/05/15 18:35:17 adam
12 * Implemented snot operation.
14 * Revision 1.1 1995/12/11 09:15:27 adam
15 * New set types: sand/sor/snot - ranked versions of and/or/not in
16 * ranked/semi-ranked result sets.
17 * Note: the snot not finished yet.
18 * New rset member: flag.
19 * Bug fix: r_delete in rsrel.c did free bad memory block.
29 static void *r_create_and(const struct rset_control *sel, void *parms,
31 static void *r_create_or(const struct rset_control *sel, void *parms,
33 static void *r_create_not(const struct rset_control *sel, void *parms,
35 static RSFD r_open (RSET ct, int flag);
36 static void r_close (RSFD rfd);
37 static void r_delete (RSET ct);
38 static void r_rewind (RSFD rfd);
39 static int r_count (RSET ct);
40 static int r_read (RSFD rfd, void *buf);
41 static int r_write (RSFD rfd, const void *buf);
42 static int r_score (RSFD rfd, int *score);
44 static const rset_control control_sand =
58 static const rset_control control_sor =
72 static const rset_control control_snot =
87 const rset_control *rset_kind_sand = &control_sand;
88 const rset_control *rset_kind_sor = &control_sor;
89 const rset_control *rset_kind_snot = &control_snot;
91 struct rset_bool_info {
100 int (*cmp)(const void *p1, const void *p2);
101 struct rset_bool_rfd *rfd_list;
104 struct rset_bool_rfd {
105 struct rset_bool_rfd *next;
106 struct rset_bool_info *info;
112 static void *r_create_common (const struct rset_control *sel,
113 rset_bool_parms *bool_parms, int *flags);
115 static struct rset_bool_info *qsort_info;
117 static int qcomp (const void *p1, const void *p2)
121 return qsort_info->score_buf[i2] - qsort_info->score_buf[i1];
124 static void key_add (struct rset_bool_info *info,
125 char *buf, int score)
127 if (info->key_no == info->key_max)
129 memcpy (info->key_buf + info->key_size * info->key_no,
130 buf, info->key_size);
131 info->score_buf[info->key_no] = score;
132 info->score_idx[info->key_no] = info->key_no;
136 static void *r_create_and (const struct rset_control *sel, void *parms,
143 struct rset_bool_info *info;
144 info = r_create_common (sel, parms, flags);
146 buf_l = xmalloc (info->key_size);
147 buf_r = xmalloc (info->key_size);
148 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
149 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
151 more_l = rset_read(info->rset_l, fd_l, buf_l);
152 more_r = rset_read(info->rset_r, fd_r, buf_r);
154 while (more_l || more_r)
157 int score, score_l, score_r;
159 if (more_l && more_r)
160 cmp = (*info->cmp)(buf_l, buf_r);
166 if (cmp >= -1 && cmp <= 1)
168 rset_score (info->rset_l, fd_l, &score_l);
169 rset_score (info->rset_r, fd_r, &score_r);
172 else if (score_r == -1)
175 score = score_l > score_r ? score_r : score_l;
176 key_add (info, buf_l, score);
178 more_l = rset_read (info->rset_l, fd_l, buf_l);
179 more_r = rset_read (info->rset_r, fd_r, buf_r);
182 more_r = rset_read (info->rset_r, fd_r, buf_r);
184 more_l = rset_read (info->rset_l, fd_l, buf_l);
186 rset_close (info->rset_l, fd_l);
187 rset_close (info->rset_r, fd_r);
188 rset_delete (info->rset_l);
189 rset_delete (info->rset_r);
193 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
197 static void *r_create_or (const struct rset_control *sel, void *parms,
204 struct rset_bool_info *info;
205 info = r_create_common (sel, parms, flags);
207 buf_l = xmalloc (info->key_size);
208 buf_r = xmalloc (info->key_size);
209 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
210 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
212 more_l = rset_read(info->rset_l, fd_l, buf_l);
213 more_r = rset_read(info->rset_r, fd_r, buf_r);
215 while (more_l || more_r)
218 int score, score_l, score_r;
220 if (more_l && more_r)
221 cmp = (*info->cmp)(buf_l, buf_r);
227 if (cmp >= -1 && cmp <= 1)
229 rset_score (info->rset_l, fd_l, &score_l);
230 rset_score (info->rset_r, fd_r, &score_r);
233 else if (score_r == -1)
236 score = score_r > score_l ? score_r : score_l;
237 key_add (info, buf_l, score);
239 more_l = rset_read (info->rset_l, fd_l, buf_l);
240 more_r = rset_read (info->rset_r, fd_r, buf_r);
244 rset_score (info->rset_r, fd_r, &score_r);
246 key_add (info, buf_r, score_r / 2);
247 more_r = rset_read (info->rset_r, fd_r, buf_r);
251 rset_score (info->rset_l, fd_l, &score_l);
253 key_add (info, buf_l, score_l / 2);
254 more_l = rset_read (info->rset_l, fd_l, buf_l);
257 rset_close (info->rset_l, fd_l);
258 rset_close (info->rset_r, fd_r);
259 rset_delete (info->rset_l);
260 rset_delete (info->rset_r);
264 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
268 static void *r_create_not (const struct rset_control *sel, void *parms,
275 struct rset_bool_info *info;
276 info = r_create_common (sel, parms, flags);
278 buf_l = xmalloc (info->key_size);
279 buf_r = xmalloc (info->key_size);
281 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
282 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
284 more_l = rset_read(info->rset_l, fd_l, buf_l);
285 more_r = rset_read(info->rset_r, fd_r, buf_r);
287 while (more_l || more_r)
292 if (more_l && more_r)
293 cmp = (*info->cmp)(buf_l, buf_r);
299 if (cmp >= -1 && cmp <= 1)
300 more_l = rset_read (info->rset_l, fd_l, buf_l);
303 more_r = rset_read (info->rset_r, fd_r, buf_r);
307 rset_score (info->rset_l, fd_l, &score);
308 key_add (info, buf_l, score == -1 ? 1 : score);
309 more_l = rset_read (info->rset_l, fd_l, buf_l);
312 rset_close (info->rset_l, fd_l);
313 rset_close (info->rset_r, fd_r);
315 rset_delete (info->rset_l);
316 rset_delete (info->rset_r);
320 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
324 static void *r_create_common (const struct rset_control *sel,
325 rset_bool_parms *bool_parms, int *flags)
327 struct rset_bool_info *info;
329 info = xmalloc (sizeof(*info));
330 info->key_size = bool_parms->key_size;
331 info->rset_l = bool_parms->rset_l;
332 info->rset_r = bool_parms->rset_r;
333 info->cmp = bool_parms->cmp;
334 info->rfd_list = NULL;
336 if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r))
337 *flags |= RSET_FLAG_RANKED;
339 info->key_max = rset_count(bool_parms->rset_l)
340 +rset_count(bool_parms->rset_r);
343 if (info->key_max > 1000)
344 info->key_max = 1000;
345 info->key_buf = xmalloc (info->key_size * info->key_max);
346 info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf));
347 info->score_idx = xmalloc (info->key_max * sizeof(*info->score_idx));
353 static RSFD r_open (RSET ct, int flag)
355 struct rset_bool_info *info = ct->buf;
356 struct rset_bool_rfd *rfd;
358 if (flag & RSETF_WRITE)
360 logf (LOG_FATAL, "sbool set type is read-only");
363 rfd = xmalloc (sizeof(*rfd));
364 rfd->next = info->rfd_list;
365 info->rfd_list = rfd;
375 static void r_close (RSFD rfd)
377 struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
378 struct rset_bool_rfd **rfdp;
380 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
383 *rfdp = (*rfdp)->next;
387 logf (LOG_FATAL, "r_close but no rfd match!");
391 static void r_delete (RSET ct)
393 struct rset_bool_info *info = ct->buf;
395 assert (info->rfd_list == NULL);
396 xfree (info->score_buf);
397 xfree (info->score_idx);
398 xfree (info->key_buf);
402 static void r_rewind (RSFD rfd)
404 struct rset_bool_rfd *p = rfd;
406 logf (LOG_DEBUG, "rsbool_rewind");
407 p->position = p->last_pos = 0;
410 static int r_count (RSET ct)
412 struct rset_bool_info *info = ct->buf;
417 static int r_read (RSFD rfd, void *buf)
419 struct rset_bool_rfd *p = rfd;
420 struct rset_bool_info *info = p->info;
422 if (p->position >= info->key_no)
424 if (p->flag & RSETF_SORT_RANK)
425 p->last_pos = info->score_idx[(p->position)++];
427 p->last_pos = (p->position)++;
428 memcpy (buf, info->key_buf + info->key_size * p->last_pos,
433 static int r_write (RSFD rfd, const void *buf)
435 logf (LOG_FATAL, "sbool set type is read-only");
439 static int r_score (RSFD rfd, int *score)
441 struct rset_bool_rfd *p = rfd;
442 struct rset_bool_info *info = p->info;
444 *score = info->score_buf[p->last_pos];