2 * Copyright (C) 1994-1998, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.6 1998-03-05 08:36:28 adam
8 * New result set model.
10 * Revision 1.5 1997/12/18 10:54:25 adam
11 * New method result set method rs_hits that returns the number of
12 * hits in result-set (if known). The ranked result set returns real
13 * number of hits but only when not combined with other operands.
15 * Revision 1.4 1997/10/31 12:37:55 adam
16 * Code calls xfree() instead of free().
18 * Revision 1.3 1997/09/09 13:38:16 adam
19 * Partial port to WIN95/NT.
21 * Revision 1.2 1996/12/23 15:30:49 adam
24 * Revision 1.1 1996/12/20 11:07:21 adam
25 * Implemented Multi-or result set.
39 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
40 static RSFD r_open (RSET ct, int flag);
41 static void r_close (RSFD rfd);
42 static void r_delete (RSET ct);
43 static void r_rewind (RSFD rfd);
44 static int r_count (RSET ct);
45 static int r_read (RSFD rfd, void *buf, int *term_index);
46 static int r_write (RSFD rfd, const void *buf);
48 static const struct rset_control control =
61 const struct rset_control *rset_kind_m_or = &control;
63 struct rset_mor_info {
66 int (*cmp)(const void *p1, const void *p2);
68 ISAM_P *isam_positions;
70 int no_isam_positions;
71 int no_save_positions;
72 struct rset_mor_rfd *rfd_list;
80 int (*cmp)(const void *p1, const void *p2);
92 struct rset_mor_rfd *next;
93 struct rset_mor_info *info;
94 struct trunc_info *ti;
97 static void heap_swap (struct trunc_info *ti, int i1, int i2)
102 ti->ptr[i1] = ti->ptr[i2];
106 static void heap_delete (struct trunc_info *ti)
108 int cur = 1, child = 2;
110 heap_swap (ti, 1, ti->heapnum--);
111 while (child <= ti->heapnum) {
112 if (child < ti->heapnum &&
113 (*ti->cmp)(ti->heap[ti->ptr[child]],
114 ti->heap[ti->ptr[1+child]]) > 0)
116 if ((*ti->cmp)(ti->heap[ti->ptr[cur]],
117 ti->heap[ti->ptr[child]]) > 0)
119 heap_swap (ti, cur, child);
128 static void heap_insert (struct trunc_info *ti, const char *buf, int indx)
132 cur = ++(ti->heapnum);
133 memcpy (ti->heap[ti->ptr[cur]], buf, ti->keysize);
134 ti->indx[ti->ptr[cur]] = indx;
136 while (parent && (*ti->cmp)(ti->heap[ti->ptr[parent]],
137 ti->heap[ti->ptr[cur]]) > 0)
139 heap_swap (ti, cur, parent);
146 struct trunc_info *heap_init (int size, int key_size,
147 int (*cmp)(const void *p1, const void *p2))
149 struct trunc_info *ti = xmalloc (sizeof(*ti));
154 ti->keysize = key_size;
156 ti->indx = xmalloc (size * sizeof(*ti->indx));
157 ti->heap = xmalloc (size * sizeof(*ti->heap));
158 ti->ptr = xmalloc (size * sizeof(*ti->ptr));
159 ti->swapbuf = xmalloc (ti->keysize);
160 ti->tmpbuf = xmalloc (ti->keysize);
161 ti->buf = xmalloc (size * ti->keysize);
162 for (i = size; --i >= 0; )
165 ti->heap[i] = ti->buf + ti->keysize * i;
170 static void heap_close (struct trunc_info *ti)
180 static void *r_create (RSET ct, const struct rset_control *sel, void *parms)
182 rset_m_or_parms *r_parms = parms;
183 struct rset_mor_info *info;
185 ct->flags |= RSET_FLAG_VOLATILE;
186 info = xmalloc (sizeof(*info));
187 info->key_size = r_parms->key_size;
188 assert (info->key_size > 1);
189 info->cmp = r_parms->cmp;
191 info->no_save_positions = r_parms->no_save_positions;
193 info->isc = r_parms->isc;
194 info->no_isam_positions = r_parms->no_isam_positions;
195 info->isam_positions = xmalloc (sizeof(*info->isam_positions) *
196 info->no_isam_positions);
197 memcpy (info->isam_positions, r_parms->isam_positions,
198 sizeof(*info->isam_positions) * info->no_isam_positions);
199 info->rfd_list = NULL;
201 ct->no_rset_terms = 1;
202 ct->rset_terms = xmalloc (sizeof(*ct->rset_terms));
203 ct->rset_terms[0] = rset_term_dup (r_parms->rset_term);
207 static RSFD r_open (RSET ct, int flag)
209 struct rset_mor_rfd *rfd;
210 struct rset_mor_info *info = ct->buf;
213 if (flag & RSETF_WRITE)
215 logf (LOG_FATAL, "m_or set type is read-only");
218 rfd = xmalloc (sizeof(*rfd));
220 rfd->next = info->rfd_list;
222 info->rfd_list = rfd;
224 rfd->ispt = xmalloc (sizeof(*rfd->ispt) * info->no_isam_positions);
226 rfd->ti = heap_init (info->no_isam_positions, info->key_size, info->cmp);
228 ct->rset_terms[0]->nn = 0;
229 for (i = 0; i<info->no_isam_positions; i++)
231 rfd->ispt[i] = isc_pp_open (info->isc, info->isam_positions[i]);
233 ct->rset_terms[0]->nn += isc_pp_num (rfd->ispt[i]);
235 if (isc_pp_read (rfd->ispt[i], rfd->ti->tmpbuf))
236 heap_insert (rfd->ti, rfd->ti->tmpbuf, i);
239 isc_pp_close (rfd->ispt[i]);
243 rfd->position = info->no_save_positions;
248 static void r_close (RSFD rfd)
250 struct rset_mor_info *info = ((struct rset_mor_rfd*)rfd)->info;
251 struct rset_mor_rfd **rfdp;
254 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
257 *rfdp = (*rfdp)->next;
259 heap_close (((struct rset_mor_rfd *) rfd)->ti);
260 for (i = 0; i<info->no_isam_positions; i++)
261 if (((struct rset_mor_rfd *) rfd)->ispt[i])
262 isc_pp_close (((struct rset_mor_rfd *) rfd)->ispt[i]);
263 xfree (((struct rset_mor_rfd *)rfd)->ispt);
267 logf (LOG_FATAL, "r_close but no rfd match!");
271 static void r_delete (RSET ct)
273 struct rset_mor_info *info = ct->buf;
276 assert (info->rfd_list == NULL);
277 xfree (info->isam_positions);
279 for (i = 0; i<ct->no_rset_terms; i++)
280 rset_term_destroy (ct->rset_terms[i]);
281 xfree (ct->rset_terms);
286 static void r_rewind (RSFD rfd)
290 static int r_count (RSET ct)
295 static int r_read (RSFD rfd, void *buf, int *term_index)
297 struct trunc_info *ti = ((struct rset_mor_rfd *) rfd)->ti;
298 int n = ti->indx[ti->ptr[1]];
303 memcpy (buf, ti->heap[ti->ptr[1]], ti->keysize);
304 if (((struct rset_mor_rfd *) rfd)->position)
306 if (isc_pp_read (((struct rset_mor_rfd *) rfd)->ispt[n], ti->tmpbuf))
309 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
310 ((struct rset_mor_rfd *) rfd)->position--;
311 heap_insert (ti, ti->tmpbuf, n);
319 if (!isc_pp_read (((struct rset_mor_rfd *) rfd)->ispt[n], ti->tmpbuf))
324 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
327 heap_insert (ti, ti->tmpbuf, n);
334 static int r_write (RSFD rfd, const void *buf)
336 logf (LOG_FATAL, "mor set type is read-only");