2 * Copyright (C) 1994-1996, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.4 1996-10-29 13:55:27 adam
8 * Include of zebrautl.h instead of alexutil.h.
10 * Revision 1.3 1996/10/08 13:00:41 adam
11 * Bug fix: result sets with ranked operands in boolean operations weren't
14 * Revision 1.2 1996/05/15 18:35:17 adam
15 * Implemented snot operation.
17 * Revision 1.1 1995/12/11 09:15:27 adam
18 * New set types: sand/sor/snot - ranked versions of and/or/not in
19 * ranked/semi-ranked result sets.
20 * Note: the snot not finished yet.
21 * New rset member: flag.
22 * Bug fix: r_delete in rsrel.c did free bad memory block.
32 static void *r_create_and(const struct rset_control *sel, void *parms,
34 static void *r_create_or(const struct rset_control *sel, void *parms,
36 static void *r_create_not(const struct rset_control *sel, void *parms,
38 static RSFD r_open (RSET ct, int flag);
39 static void r_close (RSFD rfd);
40 static void r_delete (RSET ct);
41 static void r_rewind (RSFD rfd);
42 static int r_count (RSET ct);
43 static int r_read (RSFD rfd, void *buf);
44 static int r_write (RSFD rfd, const void *buf);
45 static int r_score (RSFD rfd, int *score);
47 static const rset_control control_sand =
61 static const rset_control control_sor =
75 static const rset_control control_snot =
90 const rset_control *rset_kind_sand = &control_sand;
91 const rset_control *rset_kind_sor = &control_sor;
92 const rset_control *rset_kind_snot = &control_snot;
94 struct rset_bool_info {
103 int (*cmp)(const void *p1, const void *p2);
104 struct rset_bool_rfd *rfd_list;
107 struct rset_bool_rfd {
108 struct rset_bool_rfd *next;
109 struct rset_bool_info *info;
115 static void *r_create_common (const struct rset_control *sel,
116 rset_bool_parms *bool_parms, int *flags);
118 static struct rset_bool_info *qsort_info;
120 static int qcomp (const void *p1, const void *p2)
124 return qsort_info->score_buf[i2] - qsort_info->score_buf[i1];
127 static void key_add (struct rset_bool_info *info,
128 char *buf, int score)
130 if (info->key_no == info->key_max)
132 memcpy (info->key_buf + info->key_size * info->key_no,
133 buf, info->key_size);
134 info->score_buf[info->key_no] = score;
135 info->score_idx[info->key_no] = info->key_no;
139 static void *r_create_and (const struct rset_control *sel, void *parms,
146 struct rset_bool_info *info;
147 info = r_create_common (sel, parms, flags);
149 buf_l = xmalloc (info->key_size);
150 buf_r = xmalloc (info->key_size);
151 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
152 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
154 more_l = rset_read(info->rset_l, fd_l, buf_l);
155 more_r = rset_read(info->rset_r, fd_r, buf_r);
157 while (more_l || more_r)
160 int score, score_l, score_r;
162 if (more_l && more_r)
163 cmp = (*info->cmp)(buf_l, buf_r);
169 if (cmp >= -1 && cmp <= 1)
171 rset_score (info->rset_l, fd_l, &score_l);
172 rset_score (info->rset_r, fd_r, &score_r);
175 else if (score_r == -1)
178 score = score_l > score_r ? score_r : score_l;
179 key_add (info, buf_l, score);
181 more_l = rset_read (info->rset_l, fd_l, buf_l);
182 more_r = rset_read (info->rset_r, fd_r, buf_r);
185 more_r = rset_read (info->rset_r, fd_r, buf_r);
187 more_l = rset_read (info->rset_l, fd_l, buf_l);
189 rset_close (info->rset_l, fd_l);
190 rset_close (info->rset_r, fd_r);
191 rset_delete (info->rset_l);
192 rset_delete (info->rset_r);
196 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
200 static void *r_create_or (const struct rset_control *sel, void *parms,
207 struct rset_bool_info *info;
208 info = r_create_common (sel, parms, flags);
210 buf_l = xmalloc (info->key_size);
211 buf_r = xmalloc (info->key_size);
212 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
213 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
215 more_l = rset_read(info->rset_l, fd_l, buf_l);
216 more_r = rset_read(info->rset_r, fd_r, buf_r);
218 while (more_l || more_r)
221 int score, score_l, score_r;
223 if (more_l && more_r)
224 cmp = (*info->cmp)(buf_l, buf_r);
230 if (cmp >= -1 && cmp <= 1)
232 rset_score (info->rset_l, fd_l, &score_l);
233 rset_score (info->rset_r, fd_r, &score_r);
236 else if (score_r == -1)
239 score = score_r > score_l ? score_r : score_l;
240 key_add (info, buf_l, score);
242 more_l = rset_read (info->rset_l, fd_l, buf_l);
243 more_r = rset_read (info->rset_r, fd_r, buf_r);
247 rset_score (info->rset_r, fd_r, &score_r);
249 key_add (info, buf_r, score_r / 2);
250 more_r = rset_read (info->rset_r, fd_r, buf_r);
254 rset_score (info->rset_l, fd_l, &score_l);
256 key_add (info, buf_l, score_l / 2);
257 more_l = rset_read (info->rset_l, fd_l, buf_l);
260 rset_close (info->rset_l, fd_l);
261 rset_close (info->rset_r, fd_r);
262 rset_delete (info->rset_l);
263 rset_delete (info->rset_r);
267 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
271 static void *r_create_not (const struct rset_control *sel, void *parms,
278 struct rset_bool_info *info;
279 info = r_create_common (sel, parms, flags);
281 buf_l = xmalloc (info->key_size);
282 buf_r = xmalloc (info->key_size);
284 fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
285 fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
287 more_l = rset_read(info->rset_l, fd_l, buf_l);
288 more_r = rset_read(info->rset_r, fd_r, buf_r);
290 while (more_l || more_r)
295 if (more_l && more_r)
296 cmp = (*info->cmp)(buf_l, buf_r);
302 if (cmp >= -1 && cmp <= 1)
303 more_l = rset_read (info->rset_l, fd_l, buf_l);
306 more_r = rset_read (info->rset_r, fd_r, buf_r);
310 rset_score (info->rset_l, fd_l, &score);
311 key_add (info, buf_l, score == -1 ? 1 : score);
312 more_l = rset_read (info->rset_l, fd_l, buf_l);
315 rset_close (info->rset_l, fd_l);
316 rset_close (info->rset_r, fd_r);
318 rset_delete (info->rset_l);
319 rset_delete (info->rset_r);
323 qsort (info->score_idx, info->key_no, sizeof(*info->score_idx), qcomp);
327 static void *r_create_common (const struct rset_control *sel,
328 rset_bool_parms *bool_parms, int *flags)
330 struct rset_bool_info *info;
332 info = xmalloc (sizeof(*info));
333 info->key_size = bool_parms->key_size;
334 info->rset_l = bool_parms->rset_l;
335 info->rset_r = bool_parms->rset_r;
336 info->cmp = bool_parms->cmp;
337 info->rfd_list = NULL;
339 if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r))
340 *flags |= RSET_FLAG_RANKED;
342 info->key_max = rset_count(bool_parms->rset_l)
343 +rset_count(bool_parms->rset_r);
346 if (info->key_max > 1000)
347 info->key_max = 1000;
348 info->key_buf = xmalloc (info->key_size * info->key_max);
349 info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf));
350 info->score_idx = xmalloc (info->key_max * sizeof(*info->score_idx));
356 static RSFD r_open (RSET ct, int flag)
358 struct rset_bool_info *info = ct->buf;
359 struct rset_bool_rfd *rfd;
361 if (flag & RSETF_WRITE)
363 logf (LOG_FATAL, "sbool set type is read-only");
366 rfd = xmalloc (sizeof(*rfd));
367 rfd->next = info->rfd_list;
368 info->rfd_list = rfd;
378 static void r_close (RSFD rfd)
380 struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
381 struct rset_bool_rfd **rfdp;
383 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
386 *rfdp = (*rfdp)->next;
390 logf (LOG_FATAL, "r_close but no rfd match!");
394 static void r_delete (RSET ct)
396 struct rset_bool_info *info = ct->buf;
398 assert (info->rfd_list == NULL);
399 xfree (info->score_buf);
400 xfree (info->score_idx);
401 xfree (info->key_buf);
405 static void r_rewind (RSFD rfd)
407 struct rset_bool_rfd *p = rfd;
409 logf (LOG_DEBUG, "rsbool_rewind");
410 p->position = p->last_pos = 0;
413 static int r_count (RSET ct)
415 struct rset_bool_info *info = ct->buf;
420 static int r_read (RSFD rfd, void *buf)
422 struct rset_bool_rfd *p = rfd;
423 struct rset_bool_info *info = p->info;
425 if (p->position >= info->key_no)
427 if (p->flag & RSETF_SORT_RANK)
428 p->last_pos = info->score_idx[(p->position)++];
430 p->last_pos = (p->position)++;
431 memcpy (buf, info->key_buf + info->key_size * p->last_pos,
436 static int r_write (RSFD rfd, const void *buf)
438 logf (LOG_FATAL, "sbool set type is read-only");
442 static int r_score (RSFD rfd, int *score)
444 struct rset_bool_rfd *p = rfd;
445 struct rset_bool_info *info = p->info;
447 *score = info->score_buf[p->last_pos];