1 /* This file is part of the Zebra server.
2 Copyright (C) Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <idzebra/util.h>
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_not(RSFD rfd, void *buf, TERMID *term);
41 static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm);
43 static const struct rset_control control_not =
74 static RSET rsbool_create_base(const struct rset_control *ctrl,
76 struct rset_key_control *kcontrol,
77 int scope, RSET rset_l, RSET rset_r)
79 RSET children[2], rnew;
80 struct rset_private *info;
84 rnew = rset_create_base(ctrl, nmem, kcontrol, scope, 0, 2, children);
85 info = (struct rset_private *) nmem_malloc(rnew->nmem, sizeof(*info));
86 info->rset_l = rset_l;
87 info->rset_r = rset_r;
92 RSET rset_create_not(NMEM nmem, struct rset_key_control *kcontrol,
93 int scope, RSET rset_l, RSET rset_r)
95 return rsbool_create_base(&control_not, nmem, kcontrol,
96 scope, rset_l, rset_r);
99 static void r_delete(RSET ct)
103 static RSFD r_open(RSET ct, int flag)
105 struct rset_private *info = (struct rset_private *) ct->priv;
107 struct rfd_private *p;
109 if (flag & RSETF_WRITE)
111 yaz_log(YLOG_FATAL, "bool set type is read-only");
114 rfd = rfd_create_base(ct);
116 p = (struct rfd_private *)rfd->priv;
118 p = nmem_malloc(ct->nmem,sizeof(*p));
120 p->buf_l = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
121 p->buf_r = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
124 yaz_log(YLOG_DEBUG,"rsbool (%s) open [%p]", ct->control->desc, rfd);
127 p->rfd_l = rset_open (info->rset_l, RSETF_READ);
128 p->rfd_r = rset_open (info->rset_r, RSETF_READ);
129 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
130 p->more_r = rset_read(p->rfd_r, p->buf_r, &p->term_r);
135 static void r_close (RSFD rfd)
137 struct rfd_private *prfd=(struct rfd_private *)rfd->priv;
139 rset_close (prfd->rfd_l);
140 rset_close (prfd->rfd_r);
143 static int r_forward(RSFD rfd, void *buf, TERMID *term,
144 const void *untilbuf)
146 struct rfd_private *p = (struct rfd_private *)rfd->priv;
147 const struct rset_key_control *kctrl=rfd->rset->keycontrol;
149 if ( p->more_l && ((kctrl->cmp)(untilbuf,p->buf_l)>=rfd->rset->scope) )
150 p->more_l = rset_forward(p->rfd_l, p->buf_l, &p->term_l, untilbuf);
151 if ( p->more_r && ((kctrl->cmp)(untilbuf,p->buf_r)>=rfd->rset->scope))
152 p->more_r = rset_forward(p->rfd_r, p->buf_r, &p->term_r, untilbuf);
154 return rset_read(rfd,buf,term);
173 static int r_read_not(RSFD rfd, void *buf, TERMID *term)
175 struct rfd_private *p = (struct rfd_private *)rfd->priv;
176 const struct rset_key_control *kctrl = rfd->rset->keycontrol;
183 cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
185 cmp = -rfd->rset->scope;
187 if (cmp <= -rfd->rset->scope)
189 memcpy (buf, p->buf_l, kctrl->key_size);
192 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
196 else if (cmp >= rfd->rset->scope) /* cmp >1 */
198 p->more_r = rset_forward( p->rfd_r, p->buf_r,
199 &p->term_r, p->buf_l);
202 { /* cmp== -1, 0, or 1 */
203 memcpy (buf, p->buf_l, kctrl->key_size);
208 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
211 cmp = (*kctrl->cmp)(p->buf_l, buf);
212 } while (abs(cmp)<rfd->rset->scope);
213 /* (cmp >= -1 && cmp <= 1) */
216 p->more_r = rset_read(p->rfd_r, p->buf_r, &p->term_r);
219 cmp = (*kctrl->cmp)(p->buf_r, buf);
220 } while (abs(cmp)<rfd->rset->scope);
221 /* (cmp >= -1 && cmp <= 1) */
227 static void r_pos(RSFD rfd, double *current, double *total)
229 struct rfd_private *p = (struct rfd_private *)rfd->priv;
235 rset_pos(p->rfd_l, &lcur, <ot);
236 rset_pos(p->rfd_r, &rcur, &rtot);
237 if ( (rtot<0) && (ltot<0)) { /*no position */
238 *current = rcur; /* return same as you got */
239 *total = rtot; /* probably -1 for not available */
242 rtot = rcur = 0; /* if only one useful, use it */
247 *current = *total = 0;
250 r = 1.0*(lcur+rcur)/(ltot+rtot); /* weighed average of l and r */
251 *current = (double) (p->hits);
252 *total = *current/r ;
254 yaz_log(YLOG_DEBUG,"bool_pos: (%s/%s) %0.1f/%0.1f= %0.4f ",
255 info->rset_l->control->desc, info->rset_r->control->desc,
256 *current, *total, r);
260 static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm)
262 struct rset_private *info = (struct rset_private *) ct->priv;
263 rset_getterms(info->rset_l, terms, maxterms, curterm);
264 rset_getterms(info->rset_r, terms, maxterms, curterm);
270 * c-file-style: "Stroustrup"
271 * indent-tabs-mode: nil
273 * vim: shiftwidth=4 tabstop=8 expandtab