New set types: sand/sor/snot - ranked versions of and/or/not in
[idzebra-moved-to-github.git] / rset / rssbool.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: rssbool.c,v $
7  * Revision 1.1  1995-12-11 09:15:27  adam
8  * New set types: sand/sor/snot - ranked versions of and/or/not in
9  * ranked/semi-ranked result sets.
10  * Note: the snot not finished yet.
11  * New rset member: flag.
12  * Bug fix: r_delete in rsrel.c did free bad memory block.
13  *
14  */
15
16 #include <stdio.h>
17 #include <assert.h>
18
19 #include <rsbool.h>
20 #include <alexutil.h>
21
22 static void *r_create_and(const struct rset_control *sel, void *parms,
23                          int *flags);
24 static void *r_create_or(const struct rset_control *sel, void *parms,
25                          int *flags);
26 static void *r_create_not(const struct rset_control *sel, void *parms,
27                          int *flags);
28 static RSFD r_open (RSET ct, int flag);
29 static void r_close (RSFD rfd);
30 static void r_delete (RSET ct);
31 static void r_rewind (RSFD rfd);
32 static int r_count (RSET ct);
33 static int r_read (RSFD rfd, void *buf);
34 static int r_write (RSFD rfd, const void *buf);
35 static int r_score (RSFD rfd, int *score);
36
37 static const rset_control control_sand = 
38 {
39     "sand",
40     r_create_and,
41     r_open,
42     r_close,
43     r_delete,
44     r_rewind,
45     r_count,
46     r_read,
47     r_write,
48     r_score
49 };
50
51 static const rset_control control_sor = 
52 {
53     "sor",
54     r_create_or,
55     r_open,
56     r_close,
57     r_delete,
58     r_rewind,
59     r_count,
60     r_read,
61     r_write,
62     r_score
63 };
64
65 static const rset_control control_snot = 
66 {
67     "snot",
68     r_create_not,
69     r_open,
70     r_close,
71     r_delete,
72     r_rewind,
73     r_count,
74     r_read,
75     r_write,
76     r_score
77 };
78
79
80 const rset_control *rset_kind_sand = &control_sand;
81 const rset_control *rset_kind_sor = &control_sor;
82 const rset_control *rset_kind_snot = &control_snot;
83
84 struct rset_bool_info {
85     int key_size;
86     RSET rset_l;
87     RSET rset_r;
88     char *key_buf;
89     int *score_buf;
90     int key_no;
91     int key_max;
92     int (*cmp)(const void *p1, const void *p2);
93     struct rset_bool_rfd *rfd_list;
94 };
95
96 struct rset_bool_rfd {
97     struct rset_bool_rfd *next;
98     struct rset_bool_info *info;
99     int position;
100     int last_pos;
101     int open_flag;
102 };    
103
104 static void *r_create_common (const struct rset_control *sel, 
105                               rset_bool_parms *bool_parms, int *flags);
106             
107 static void key_add (struct rset_bool_info *info,
108                      char *buf, int score)
109 {
110     if (info->key_no == info->key_max)
111         return;
112     memcpy (info->key_buf + info->key_size * info->key_no,
113             buf, info->key_size);
114     info->score_buf[info->key_no] = score;
115     (info->key_no)++;
116 }
117
118 static void *r_create_and (const struct rset_control *sel, void *parms,
119                            int *flags)
120 {
121     int more_l, more_r;
122     RSFD fd_l, fd_r;
123     char *buf_l, *buf_r;
124
125     struct rset_bool_info *info;
126     info = r_create_common (sel, parms, flags);
127
128     buf_l = xmalloc (info->key_size);
129     buf_r = xmalloc (info->key_size);
130     fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
131     fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
132
133     more_l = rset_read(info->rset_l, fd_l, buf_l);
134     more_r = rset_read(info->rset_r, fd_r, buf_r);
135
136     while (more_l || more_r)
137     {
138         int cmp;
139         int score, score_l, score_r;
140
141         if (more_l && more_r)
142             cmp = (*info->cmp)(buf_l, buf_r);
143         else if (more_r)
144             cmp = 2;
145         else 
146             cmp = -2;
147
148         if (cmp >= -1 && cmp <= 1)
149         {
150             rset_score (info->rset_l, fd_l, &score_l);
151             rset_score (info->rset_r, fd_r, &score_r);
152             if (score_l == -1)
153                 score = score_r;
154             else if (score_r == -1)
155                 score = score_l;
156             else
157                 score = score_l > score_r ? score_r : score_l;
158             key_add (info, buf_l, score);
159     
160             more_l = rset_read (info->rset_l, fd_l, buf_l);
161             more_r = rset_read (info->rset_r, fd_r, buf_r);
162         }
163         else if (cmp > 1)
164         {
165             rset_score (info->rset_r, fd_r, &score_r);
166             if (score_r != -1)
167                 key_add (info, buf_r, 1);
168             more_r = rset_read (info->rset_r, fd_r, buf_r);
169         }
170         else
171         {
172             rset_score (info->rset_l, fd_l, &score_l);
173             if (score_l != -1)
174                 key_add (info, buf_l, 1);
175             more_l = rset_read (info->rset_l, fd_l, buf_l);
176         }
177     }
178     rset_close (info->rset_l, fd_l);
179     rset_close (info->rset_r, fd_r);
180     rset_delete (info->rset_l);
181     rset_delete (info->rset_r);
182     xfree (buf_l);
183     xfree (buf_r);
184     return info;
185 }
186
187 static void *r_create_or (const struct rset_control *sel, void *parms,
188                           int *flags)
189 {
190     int more_l, more_r;
191     RSFD fd_l, fd_r;
192     char *buf_l, *buf_r;
193
194     struct rset_bool_info *info;
195     info = r_create_common (sel, parms, flags);
196
197     buf_l = xmalloc (info->key_size);
198     buf_r = xmalloc (info->key_size);
199     fd_l = rset_open (info->rset_l, RSETF_SORT_SYSNO|RSETF_READ);
200     fd_r = rset_open (info->rset_r, RSETF_SORT_SYSNO|RSETF_READ);
201
202     more_l = rset_read(info->rset_l, fd_l, buf_l);
203     more_r = rset_read(info->rset_r, fd_r, buf_r);
204
205     while (more_l || more_r)
206     {
207         int cmp;
208         int score, score_l, score_r;
209
210         if (more_l && more_r)
211             cmp = (*info->cmp)(buf_l, buf_r);
212         else if (more_r)
213             cmp = 2;
214         else 
215             cmp = -2;
216
217         if (cmp >= -1 && cmp <= 1)
218         {
219             rset_score (info->rset_l, fd_l, &score_l);
220             rset_score (info->rset_r, fd_r, &score_r);
221             if (score_l == -1)
222                 score = score_r;
223             else if (score_r == -1)
224                 score = score_l;
225             else
226                 score = score_r > score_l ? score_r : score_l;
227             key_add (info, buf_l, score);
228     
229             more_l = rset_read (info->rset_l, fd_l, buf_l);
230             more_r = rset_read (info->rset_r, fd_r, buf_r);
231         }
232         else if (cmp > 1)
233         {
234             rset_score (info->rset_r, fd_r, &score_r);
235             if (score_r != -1)
236                 key_add (info, buf_r, score_r / 2);
237             more_r = rset_read (info->rset_r, fd_r, buf_r);
238         }
239         else
240         {
241             rset_score (info->rset_l, fd_l, &score_l);
242             if (score_l != -1)
243                 key_add (info, buf_l, score_l / 2);
244             more_l = rset_read (info->rset_l, fd_l, buf_l);
245         }
246     }
247     rset_close (info->rset_l, fd_l);
248     rset_close (info->rset_r, fd_r);
249     rset_delete (info->rset_l);
250     rset_delete (info->rset_r);
251     xfree (buf_l);
252     xfree (buf_r);
253     return info;
254 }
255
256 static void *r_create_not (const struct rset_control *sel, void *parms,
257                            int *flags)
258 {
259     char *buf_l, *buf_r;
260
261     struct rset_bool_info *info;
262     info = r_create_common (sel, parms, flags);
263
264     buf_l = xmalloc (info->key_size);
265     buf_r = xmalloc (info->key_size);
266     rset_delete (info->rset_l);
267     rset_delete (info->rset_r);
268     xfree (buf_l);
269     xfree (buf_r);
270     return info;
271 }
272
273 static void *r_create_common (const struct rset_control *sel, 
274                               rset_bool_parms *bool_parms, int *flags)
275 {
276     struct rset_bool_info *info;
277
278     info = xmalloc (sizeof(*info));
279     info->key_size = bool_parms->key_size;
280     info->rset_l = bool_parms->rset_l;
281     info->rset_r = bool_parms->rset_r;
282     info->cmp = bool_parms->cmp;
283     info->rfd_list = NULL;
284     
285     if (rset_is_ranked(info->rset_l) || rset_is_ranked(info->rset_r))
286         *flags |= RSET_FLAG_RANKED;
287
288     info->key_max = rset_count(bool_parms->rset_l)
289                    +rset_count(bool_parms->rset_r);
290     if (!info->key_max)
291         info->key_max = 1;
292     if (info->key_max > 1000)
293         info->key_max = 1000;
294     info->key_buf = xmalloc (info->key_size * info->key_max);
295     info->score_buf = xmalloc (info->key_max * sizeof(*info->score_buf));
296     info->key_no = 0;
297
298     return info;
299 }
300
301 static RSFD r_open (RSET ct, int flag)
302 {
303     struct rset_bool_info *info = ct->buf;
304     struct rset_bool_rfd *rfd;
305
306     if (flag & RSETF_WRITE)
307     {
308         logf (LOG_FATAL, "sbool set type is read-only");
309         return NULL;
310     }
311     rfd = xmalloc (sizeof(*rfd));
312     rfd->next = info->rfd_list;
313     info->rfd_list = rfd;
314     rfd->info = info;
315
316     rfd->position = 0;
317     rfd->last_pos = 0;
318     rfd->open_flag = flag;
319
320     return rfd;
321 }
322
323 static void r_close (RSFD rfd)
324 {
325     struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
326     struct rset_bool_rfd **rfdp;
327     
328     for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
329         if (*rfdp == rfd)
330         {
331             *rfdp = (*rfdp)->next;
332             xfree (rfd);
333             return;
334         }
335     logf (LOG_FATAL, "r_close but no rfd match!");
336     assert (0);
337 }
338
339 static void r_delete (RSET ct)
340 {
341     struct rset_bool_info *info = ct->buf;
342
343     assert (info->rfd_list == NULL);
344     xfree (info->score_buf);
345     xfree (info->key_buf);
346     xfree (info);
347 }
348
349 static void r_rewind (RSFD rfd)
350 {
351     struct rset_bool_rfd *p = rfd;
352
353     logf (LOG_DEBUG, "rsbool_rewind");
354     p->position = p->last_pos = 0;
355 }
356
357 static int r_count (RSET ct)
358 {
359     struct rset_bool_info *info = ct->buf;
360
361     return info->key_no;
362 }
363
364 static int r_read (RSFD rfd, void *buf)
365 {
366     struct rset_bool_rfd *p = rfd;
367     struct rset_bool_info *info = p->info;
368
369     if (p->position >= info->key_no)
370         return 0;
371     p->last_pos = (p->position)++;
372     memcpy (buf, info->key_buf + info->key_size * p->last_pos,
373             info->key_size);
374     return 1;
375 }
376
377 static int r_write (RSFD rfd, const void *buf)
378 {
379     logf (LOG_FATAL, "sbool set type is read-only");
380     return -1;
381 }
382
383 static int r_score (RSFD rfd, int *score)
384 {
385     struct rset_bool_rfd *p = rfd;
386     struct rset_bool_info *info = p->info;
387
388     *score = info->score_buf[p->last_pos];
389     return 1;
390 }
391