1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2011 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
25 #include <idzebra/util.h>
32 static RSFD r_open(RSET ct, int flag);
33 static void r_close(RSFD rfd);
34 static void r_delete(RSET ct);
35 static int r_forward(RSFD rfd, void *buf, TERMID *term, const void *untilbuf);
36 static void r_pos(RSFD rfd, double *current, double *total);
37 static int r_read_not(RSFD rfd, void *buf, TERMID *term);
38 static int r_write(RSFD rfd, const void *buf);
39 static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm);
41 static const struct rset_control control_not =
72 static RSET rsbool_create_base(const struct rset_control *ctrl,
74 struct rset_key_control *kcontrol,
75 int scope, RSET rset_l, RSET rset_r)
77 RSET children[2], rnew;
78 struct rset_private *info;
82 rnew = rset_create_base(ctrl, nmem, kcontrol, scope, 0, 2, children);
83 info = (struct rset_private *) nmem_malloc(rnew->nmem, sizeof(*info));
84 info->rset_l = rset_l;
85 info->rset_r = rset_r;
90 RSET rset_create_not(NMEM nmem, struct rset_key_control *kcontrol,
91 int scope, RSET rset_l, RSET rset_r)
93 return rsbool_create_base(&control_not, nmem, kcontrol,
94 scope, rset_l, rset_r);
97 static void r_delete(RSET ct)
101 static RSFD r_open(RSET ct, int flag)
103 struct rset_private *info = (struct rset_private *) ct->priv;
105 struct rfd_private *p;
107 if (flag & RSETF_WRITE)
109 yaz_log(YLOG_FATAL, "bool set type is read-only");
112 rfd = rfd_create_base(ct);
114 p = (struct rfd_private *)rfd->priv;
116 p = nmem_malloc(ct->nmem,sizeof(*p));
118 p->buf_l = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
119 p->buf_r = nmem_malloc(ct->nmem, ct->keycontrol->key_size);
122 yaz_log(YLOG_DEBUG,"rsbool (%s) open [%p]", ct->control->desc, rfd);
125 p->rfd_l = rset_open (info->rset_l, RSETF_READ);
126 p->rfd_r = rset_open (info->rset_r, RSETF_READ);
127 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
128 p->more_r = rset_read(p->rfd_r, p->buf_r, &p->term_r);
133 static void r_close (RSFD rfd)
135 struct rfd_private *prfd=(struct rfd_private *)rfd->priv;
137 rset_close (prfd->rfd_l);
138 rset_close (prfd->rfd_r);
141 static int r_forward(RSFD rfd, void *buf, TERMID *term,
142 const void *untilbuf)
144 struct rfd_private *p = (struct rfd_private *)rfd->priv;
145 const struct rset_key_control *kctrl=rfd->rset->keycontrol;
147 if ( p->more_l && ((kctrl->cmp)(untilbuf,p->buf_l)>=rfd->rset->scope) )
148 p->more_l = rset_forward(p->rfd_l, p->buf_l, &p->term_l, untilbuf);
149 if ( p->more_r && ((kctrl->cmp)(untilbuf,p->buf_r)>=rfd->rset->scope))
150 p->more_r = rset_forward(p->rfd_r, p->buf_r, &p->term_r, untilbuf);
152 return rset_read(rfd,buf,term);
171 static int r_read_not(RSFD rfd, void *buf, TERMID *term)
173 struct rfd_private *p = (struct rfd_private *)rfd->priv;
174 const struct rset_key_control *kctrl = rfd->rset->keycontrol;
181 cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
183 cmp = -rfd->rset->scope;
185 if (cmp <= -rfd->rset->scope)
187 memcpy (buf, p->buf_l, kctrl->key_size);
190 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
194 else if (cmp >= rfd->rset->scope) /* cmp >1 */
196 p->more_r = rset_forward( p->rfd_r, p->buf_r,
197 &p->term_r, p->buf_l);
200 { /* cmp== -1, 0, or 1 */
201 memcpy (buf, p->buf_l, kctrl->key_size);
206 p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
209 cmp = (*kctrl->cmp)(p->buf_l, buf);
210 } while (abs(cmp)<rfd->rset->scope);
211 /* (cmp >= -1 && cmp <= 1) */
214 p->more_r = rset_read(p->rfd_r, p->buf_r, &p->term_r);
217 cmp = (*kctrl->cmp)(p->buf_r, buf);
218 } while (abs(cmp)<rfd->rset->scope);
219 /* (cmp >= -1 && cmp <= 1) */
226 static int r_write(RSFD rfd, const void *buf)
228 yaz_log(YLOG_FATAL, "bool set type is read-only");
232 static void r_pos(RSFD rfd, double *current, double *total)
234 struct rfd_private *p = (struct rfd_private *)rfd->priv;
240 rset_pos(p->rfd_l, &lcur, <ot);
241 rset_pos(p->rfd_r, &rcur, &rtot);
242 if ( (rtot<0) && (ltot<0)) { /*no position */
243 *current = rcur; /* return same as you got */
244 *total = rtot; /* probably -1 for not available */
247 rtot = rcur = 0; /* if only one useful, use it */
252 *current = *total = 0;
255 r = 1.0*(lcur+rcur)/(ltot+rtot); /* weighed average of l and r */
256 *current = (double) (p->hits);
257 *total = *current/r ;
259 yaz_log(YLOG_DEBUG,"bool_pos: (%s/%s) %0.1f/%0.1f= %0.4f ",
260 info->rset_l->control->desc, info->rset_r->control->desc,
261 *current, *total, r);
265 static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm)
267 struct rset_private *info = (struct rset_private *) ct->priv;
268 rset_getterms(info->rset_l, terms, maxterms, curterm);
269 rset_getterms(info->rset_r, terms, maxterms, curterm);
275 * c-file-style: "Stroustrup"
276 * indent-tabs-mode: nil
278 * vim: shiftwidth=4 tabstop=8 expandtab