1 /* $Id: rsbool.c,v 1.49 2004-10-15 10:07:34 heikki Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
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 int r_forward(RSFD rfd, void *buf, TERMID *term, const void *untilbuf);
39 static void r_pos (RSFD rfd, double *current, double *total);
40 static int r_read_and (RSFD rfd, void *buf, TERMID *term);
41 static int r_read_or (RSFD rfd, void *buf, TERMID *term);
42 static int r_read_not (RSFD rfd, void *buf, TERMID *term);
43 static int r_write (RSFD rfd, const void *buf);
45 static const struct rset_control control_and =
57 static const struct rset_control control_or =
69 static const struct rset_control control_not =
82 const struct rset_control *rset_kind_and = &control_and;
83 const struct rset_control *rset_kind_or = &control_or;
84 const struct rset_control *rset_kind_not = &control_not;
86 struct rset_bool_info {
91 struct rset_bool_rfd {
104 static RSET rsbool_create_base( const struct rset_control *ctrl,
105 NMEM nmem, const struct key_control *kcontrol,
107 RSET rset_l, RSET rset_r)
109 RSET rnew=rset_create_base(ctrl, nmem, kcontrol, scope,0);
110 struct rset_bool_info *info;
111 info = (struct rset_bool_info *) nmem_malloc(rnew->nmem,sizeof(*info));
112 info->rset_l = rset_l;
113 info->rset_r = rset_r;
119 RSET rsbool_create_and( NMEM nmem, const struct key_control *kcontrol,
121 RSET rset_l, RSET rset_r)
123 return rsbool_create_base(rset_kind_and, nmem, kcontrol,
128 RSET rsbool_create_or( NMEM nmem, const struct key_control *kcontrol,
130 RSET rset_l, RSET rset_r)
132 return rsbool_create_base(rset_kind_or, nmem, kcontrol,
137 RSET rsbool_create_not( NMEM nmem, const struct key_control *kcontrol,
139 RSET rset_l, RSET rset_r)
141 return rsbool_create_base(rset_kind_not, nmem, kcontrol,
146 static void r_delete (RSET ct)
148 struct rset_bool_info *info = (struct rset_bool_info *) ct->priv;
149 rset_delete (info->rset_l);
150 rset_delete (info->rset_r);
154 static RSFD r_open (RSET ct, int flag)
156 struct rset_bool_info *info = (struct rset_bool_info *) ct->priv;
158 struct rset_bool_rfd *p;
161 if (flag & RSETF_WRITE)
163 logf (LOG_FATAL, "bool set type is read-only");
166 rfd = rfd_create_base(ct);
168 p=(struct rset_bool_rfd *)rfd->priv;
170 p=nmem_malloc(ct->nmem,sizeof(*p));
172 p->buf_l = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
173 p->buf_r = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
176 logf(LOG_DEBUG,"rsbool (%s) open [%p]", ct->control->desc, rfd);
179 p->rfd_l = rset_open (info->rset_l, RSETF_READ);
180 p->rfd_r = rset_open (info->rset_r, RSETF_READ);
181 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
182 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
187 static void r_close (RSFD rfd)
189 /* struct rset_bool_info *info = (struct rset_bool_info*)(rfd->rset->priv); */
190 struct rset_bool_rfd *prfd=(struct rset_bool_rfd *)rfd->priv;
192 rset_close (prfd->rfd_l);
193 rset_close (prfd->rfd_r);
194 rfd_delete_base(rfd);
199 static int r_forward (RSFD rfd, void *buf, TERMID *term,
200 const void *untilbuf)
202 struct rset_bool_rfd *p=(struct rset_bool_rfd *)rfd->priv;
203 const struct key_control *kctrl=rfd->rset->keycontrol;
205 if ( p->more_l && ((kctrl->cmp)(untilbuf,p->buf_l)>=rfd->rset->scope) )
206 p->more_l = rset_forward(p->rfd_l, p->buf_l, &p->term_l, untilbuf);
207 if ( p->more_r && ((kctrl->cmp)(untilbuf,p->buf_r)>=rfd->rset->scope))
208 p->more_r = rset_forward(p->rfd_r, p->buf_r, &p->term_r, untilbuf);
210 return rset_read(rfd,buf,term);
229 static int r_read_and (RSFD rfd, void *buf, TERMID *term)
231 struct rset_bool_rfd *p=(struct rset_bool_rfd *)rfd->priv;
232 const struct key_control *kctrl=rfd->rset->keycontrol;
234 while (p->more_l || p->more_r)
238 if (p->more_l && p->more_r)
239 cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
241 cmp = -rfd->rset->scope;
243 cmp = rfd->rset->scope;
245 logf (LOG_DEBUG, "r_read_and [%p] looping: m=%d/%d c=%d t=%d",
246 rfd, p->more_l, p->more_r, cmp, p->tail);
247 (*kctrl->log_item)(LOG_DEBUG, p->buf_l, "left ");
248 (*kctrl->log_item)(LOG_DEBUG, p->buf_r, "right ");
252 memcpy (buf, p->buf_l, kctrl->key_size);
255 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
258 else if ( (cmp>0) && (cmp<rfd->rset->scope))
259 { /* typically cmp == 1 */
260 memcpy (buf, p->buf_r, kctrl->key_size);
263 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
266 logf (LOG_DEBUG, "r_read_and [%p] returning R m=%d/%d c=%d",
267 rfd, p->more_l, p->more_r, cmp);
268 key_logdump(LOG_DEBUG,buf);
269 (*kctrl->log_item)(LOG_DEBUG, buf, "");
274 else if ( (cmp<0) && (-cmp<rfd->rset->scope))
276 memcpy (buf, p->buf_l, kctrl->key_size);
279 p->more_l = rset_read (p->rfd_l, p->buf_l,&p->term_l);
282 logf (LOG_DEBUG, "r_read_and [%p] returning L m=%d/%d c=%d",
283 rfd, p->more_l, p->more_r, cmp);
284 (*kctrl->log_item)(LOG_DEBUG, buf, "");
289 else if (cmp >= rfd->rset->scope )
293 memcpy (buf, p->buf_r, kctrl->key_size);
296 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
297 if (!p->more_r || (*kctrl->cmp)(p->buf_r, buf) > 1)
300 logf (LOG_DEBUG, "r_read_and [%p] returning R tail m=%d/%d c=%d",
301 rfd, p->more_l, p->more_r, cmp);
302 (*kctrl->log_item)(LOG_DEBUG, buf, "");
310 logf (LOG_DEBUG, "r_read_and [%p] about to forward R "
312 rfd, p->more_l, p->more_r, cmp);
314 if (p->more_r && p->more_l)
315 p->more_r = rset_forward( p->rfd_r, p->buf_r,
316 &p->term_r, p->buf_l);
318 return 0; /* no point in reading further */
325 memcpy (buf, p->buf_l, kctrl->key_size);
328 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
329 if (!p->more_l || (*kctrl->cmp)(p->buf_l, buf) > 1)
332 logf (LOG_DEBUG, "r_read_and [%p] returning L tail m=%d/%d c=%d",
333 rfd, p->more_l, p->more_r, cmp);
334 (*kctrl->log_item)(LOG_DEBUG, buf, "");
342 logf (LOG_DEBUG, "r_read_and [%p] about to forward L "
344 rfd, p->more_l, p->more_r, cmp);
346 if (p->more_r && p->more_l)
347 p->more_l = rset_forward(p->rfd_l, p->buf_l,
348 &p->term_l, p->buf_r);
350 return 0; /* no point in reading further */
355 logf (LOG_DEBUG, "r_read_and [%p] reached its end",rfd);
360 static int r_read_or (RSFD rfd, void *buf, TERMID *term)
362 struct rset_bool_rfd *p=(struct rset_bool_rfd *)rfd->priv;
363 const struct key_control *kctrl=rfd->rset->keycontrol;
365 while (p->more_l || p->more_r)
369 if (p->more_l && p->more_r)
370 cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
372 cmp = rfd->rset->scope;
374 cmp = -rfd->rset->scope;
377 memcpy (buf, p->buf_l, kctrl->key_size);
380 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
381 /* FIXME - is this right, should we not leave _r as it is */
382 /* and return that in the next read, so that ranking etc */
383 /* get to see both? */
384 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
386 logf (LOG_DEBUG, "r_read_or returning A m=%d/%d c=%d",
387 p->more_l, p->more_r, cmp);
388 (*kctrl->log_item)(LOG_DEBUG, buf, "");
395 memcpy (buf, p->buf_r, kctrl->key_size);
398 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
400 logf (LOG_DEBUG, "r_read_or returning B m=%d/%d c=%d",
401 p->more_l, p->more_r, cmp);
402 (*kctrl->log_item)(LOG_DEBUG, buf, "");
409 memcpy (buf, p->buf_l, kctrl->key_size);
412 p->more_l = rset_read ( p->rfd_l, p->buf_l, &p->term_l);
414 logf (LOG_DEBUG, "r_read_or returning C m=%d/%d c=%d",
415 p->more_l, p->more_r, cmp);
416 (*kctrl->log_item)(LOG_DEBUG, buf, "");
425 static int r_read_not (RSFD rfd, void *buf, TERMID *term)
427 struct rset_bool_rfd *p=(struct rset_bool_rfd *)rfd->priv;
428 const struct key_control *kctrl=rfd->rset->keycontrol;
430 while (p->more_l || p->more_r)
434 if (p->more_l && p->more_r)
435 cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
437 cmp = rfd->rset->scope;
439 cmp = -rfd->rset->scope;
441 if (cmp <= -rfd->rset->scope)
443 memcpy (buf, p->buf_l, kctrl->key_size);
446 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
450 else if (cmp >= rfd->rset->scope) /* cmp >1 */
451 p->more_r = rset_forward( p->rfd_r, p->buf_r,
452 &p->term_r, p->buf_l);
454 { /* cmp== -1, 0, or 1 */
455 memcpy (buf, p->buf_l, kctrl->key_size);
460 p->more_l = rset_read (p->rfd_l, p->buf_l, &p->term_l);
463 cmp = (*kctrl->cmp)(p->buf_l, buf);
464 } while (abs(cmp)<rfd->rset->scope);
465 /* (cmp >= -1 && cmp <= 1) */
468 p->more_r = rset_read (p->rfd_r, p->buf_r, &p->term_r);
471 cmp = (*kctrl->cmp)(p->buf_r, buf);
472 } while (abs(cmp)<rfd->rset->scope);
473 /* (cmp >= -1 && cmp <= 1) */
480 static int r_write (RSFD rfd, const void *buf)
482 logf (LOG_FATAL, "bool set type is read-only");
486 static void r_pos (RSFD rfd, double *current, double *total)
488 struct rset_bool_rfd *p=(struct rset_bool_rfd *)rfd->priv;
493 rset_pos(p->rfd_l, &lcur, <ot);
494 rset_pos(p->rfd_r, &rcur, &rtot);
495 if ( (rtot<0) && (ltot<0)) { /*no position */
496 *current=rcur; /* return same as you got */
497 *total=rtot; /* probably -1 for not available */
499 if ( rtot<0) { rtot=0; rcur=0;} /* if only one useful, use it */
500 if ( ltot<0) { ltot=0; lcur=0;}
501 if ( rtot+ltot < 1 ) { /* empty rset */
506 r=1.0*(lcur+rcur)/(ltot+rtot); /* weighed average of l and r */
507 *current=(double) (p->hits);
510 yaz_log(LOG_DEBUG,"bool_pos: (%s/%s) %0.1f/%0.1f= %0.4f ",
511 info->rset_l->control->desc, info->rset_r->control->desc,
512 *current, *total, r);