New parameter: result-set file descriptor (RSFD) to support multiple
[idzebra-moved-to-github.git] / rset / rsbool.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: rsbool.c,v $
7  * Revision 1.3  1995-09-07 13:58:43  adam
8  * New parameter: result-set file descriptor (RSFD) to support multiple
9  * positions within the same result-set.
10  * Boolean operators: and, or, not implemented.
11  *
12  * Revision 1.2  1995/09/06  16:11:55  adam
13  * More work on boolean sets.
14  *
15  * Revision 1.1  1995/09/06  13:27:15  adam
16  * New set type: bool. Not finished yet.
17  *
18  */
19
20 #include <stdio.h>
21 #include <assert.h>
22
23 #include <rsbool.h>
24 #include <alexutil.h>
25
26 static rset_control *r_create(const struct rset_control *sel, void *parms);
27 static RSFD r_open (rset_control *ct, int wflag);
28 static void r_close (RSFD rfd);
29 static void r_delete (rset_control *ct);
30 static void r_rewind (RSFD rfd);
31 static int r_count (rset_control *ct);
32 static int r_read_and (RSFD rfd, void *buf);
33 static int r_read_or (RSFD rfd, void *buf);
34 static int r_read_not (RSFD rfd, void *buf);
35 static int r_write (RSFD rfd, const void *buf);
36
37 static const rset_control control_and = 
38 {
39     "AND set type",
40     0,
41     r_create,
42     r_open,
43     r_close,
44     r_delete,
45     r_rewind,
46     r_count,
47     r_read_and,
48     r_write
49 };
50
51 static const rset_control control_or = 
52 {
53     "OR set type",
54     0,
55     r_create,
56     r_open,
57     r_close,
58     r_delete,
59     r_rewind,
60     r_count,
61     r_read_or,
62     r_write
63 };
64
65 static const rset_control control_not = 
66 {
67     "NOT set type",
68     0,
69     r_create,
70     r_open,
71     r_close,
72     r_delete,
73     r_rewind,
74     r_count,
75     r_read_not,
76     r_write
77 };
78
79
80 const rset_control *rset_kind_and = &control_and;
81 const rset_control *rset_kind_or = &control_or;
82 const rset_control *rset_kind_not = &control_not;
83
84 struct rset_bool_info {
85     int key_size;
86     RSET rset_l;
87     RSET rset_r;
88     int (*cmp)(const void *p1, const void *p2);
89     struct rset_bool_rfd *rfd_list;
90 };
91
92 struct rset_bool_rfd {
93     RSFD rfd_l;
94     RSFD rfd_r;
95     int  more_l;
96     int  more_r;
97     void *buf_l;
98     void *buf_r;
99     struct rset_bool_rfd *next;
100     struct rset_bool_info *info;
101 };    
102
103 static rset_control *r_create (const struct rset_control *sel, void *parms)
104 {
105     rset_control *newct;
106     rset_bool_parms *bool_parms = parms;
107     struct rset_bool_info *info;
108
109     logf (LOG_DEBUG, "rsbool_create(%s)", sel->desc);
110     newct = xmalloc(sizeof(*newct));
111     memcpy (newct, sel, sizeof(*sel));
112     newct->buf = xmalloc (sizeof(struct rset_bool_info));
113     info = (struct rset_bool_info*) newct->buf;
114     info->key_size = bool_parms->key_size;
115     info->rset_l = bool_parms->rset_l;
116     info->rset_r = bool_parms->rset_r;
117     info->cmp = bool_parms->cmp;
118     info->rfd_list = NULL;
119     return newct;
120 }
121
122 static RSFD r_open (rset_control *ct, int wflag)
123 {
124     struct rset_bool_info *info = ct->buf;
125     struct rset_bool_rfd *rfd;
126
127     if (wflag)
128     {
129         logf (LOG_FATAL, "bool set type is read-only");
130         return NULL;
131     }
132     rfd = xmalloc (sizeof(*rfd));
133     rfd->next = info->rfd_list;
134     info->rfd_list = rfd;
135
136     rfd->buf_l = xmalloc (info->key_size);
137     rfd->buf_r = xmalloc (info->key_size);
138     rfd->rfd_l = rset_open (info->rset_l, wflag);
139     rfd->rfd_r = rset_open (info->rset_r, wflag);
140     rfd->more_l = rset_read (info->rset_l, rfd->rfd_l, rfd->buf_l);
141     rfd->more_r = rset_read (info->rset_r, rfd->rfd_r, rfd->buf_r);
142     rfd->info = info;
143     return rfd;
144 }
145
146 static void r_close (RSFD rfd)
147 {
148     struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
149     struct rset_bool_rfd **rfdp;
150     
151     for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
152         if (*rfdp == rfd)
153         {
154             xfree ((*rfdp)->buf_l);
155             xfree ((*rfdp)->buf_r);
156             rset_close (info->rset_l, (*rfdp)->rfd_l);
157             rset_close (info->rset_r, (*rfdp)->rfd_r);
158             *rfdp = (*rfdp)->next;
159             free (rfd);
160             return;
161         }
162     logf (LOG_FATAL, "r_close but no rfd match!");
163     assert (0);
164 }
165
166 static void r_delete (rset_control *ct)
167 {
168     struct rset_bool_info *info = ct->buf;
169
170     assert (info->rfd_list == NULL);
171     xfree (info);
172     xfree (ct);
173 }
174
175 static void r_rewind (RSFD rfd)
176 {
177     struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
178     struct rset_bool_rfd *p = rfd;
179
180     logf (LOG_DEBUG, "rsbool_rewind");
181     rset_rewind (info->rset_l, p->rfd_l);
182     rset_rewind (info->rset_r, p->rfd_r);
183     p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
184     p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
185 }
186
187 static int r_count (rset_control *ct)
188 {
189     return 0;
190 }
191
192 static int r_read_and (RSFD rfd, void *buf)
193 {
194     struct rset_bool_rfd *p = rfd;
195     struct rset_bool_info *info = p->info;
196
197     while (p->more_l || p->more_r)
198     {
199         int cmp;
200
201         if (p->more_l && p->more_r)
202             cmp = (*info->cmp)(p->buf_l, p->buf_r);
203         else if (p->more_r)
204             cmp = 2;
205         else
206             cmp = -2;
207         if (!cmp)
208         {
209             memcpy (buf, p->buf_l, info->key_size);
210             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
211             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
212             return 1;
213         }
214         else if (cmp == 1)
215         {
216             memcpy (buf, p->buf_r, info->key_size);
217             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
218             return 1;
219         }
220         else if (cmp == -1)
221         {
222             memcpy (buf, p->buf_l, info->key_size);
223             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
224             return 1;
225         }
226         else if (cmp > 1)
227             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
228         else
229             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
230     }
231     return 0;
232 }
233
234 static int r_read_or (RSFD rfd, void *buf)
235 {
236     struct rset_bool_rfd *p = rfd;
237     struct rset_bool_info *info = p->info;
238
239     while (p->more_l || p->more_r)
240     {
241         int cmp;
242
243         if (p->more_l && p->more_r)
244             cmp = (*info->cmp)(p->buf_l, p->buf_r);
245         else if (p->more_r)
246             cmp = 2;
247         else
248             cmp = -2;
249         if (!cmp)
250         {
251             memcpy (buf, p->buf_l, info->key_size);
252             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
253             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
254             return 1;
255         }
256         else if (cmp > 0)
257         {
258             memcpy (buf, p->buf_r, info->key_size);
259             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
260             return 1;
261         }
262         else
263         {
264             memcpy (buf, p->buf_l, info->key_size);
265             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
266             return 1;
267         }
268     }
269     return 0;
270 }
271
272 static int r_read_not (RSFD rfd, void *buf)
273 {
274     struct rset_bool_rfd *p = rfd;
275     struct rset_bool_info *info = p->info;
276
277     while (p->more_l || p->more_r)
278     {
279         int cmp;
280
281         if (p->more_l && p->more_r)
282             cmp = (*info->cmp)(p->buf_l, p->buf_r);
283         else if (p->more_r)
284             cmp = 2;
285         else
286             cmp = -2;
287         if (cmp < -1)
288         {
289             memcpy (buf, p->buf_l, info->key_size);
290             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
291             return 1;
292         }
293         else if (cmp > 1)
294             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
295         else
296         {
297             memcpy (buf, p->buf_l, info->key_size);
298             do
299             {
300                 p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l);
301                 if (!p->more_l)
302                     break;
303                 cmp = (*info->cmp)(p->buf_l, buf);
304             } while (cmp >= -1 && cmp <= 1);
305             do
306             {
307                 p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r);
308                 if (!p->more_r)
309                     break;
310                 cmp = (*info->cmp)(p->buf_r, buf);
311             } while (cmp >= -1 && cmp <= 1);
312         }
313     }
314     return 0;
315 }
316
317
318 static int r_write (RSFD rfd, const void *buf)
319 {
320     logf (LOG_FATAL, "bool set type is read-only");
321     return -1;
322 }