IDZEBRA  2.1.2
rsbool.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
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
7 version.
8 
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
12 for more details.
13 
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
17 
18 */
19 
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 
28 #include <idzebra/util.h>
29 #include <rset.h>
30 
31 #ifndef RSET_DEBUG
32 #define RSET_DEBUG 0
33 #endif
34 
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);
42 
43 static const struct rset_control control_not =
44 {
45  "not",
46  r_delete,
48  r_open,
49  r_close,
50  r_forward,
51  r_pos,
52  r_read_not,
54 };
55 
56 struct rset_private {
59 };
60 
61 struct rfd_private {
65  int more_l;
66  int more_r;
67  void *buf_l;
68  void *buf_r;
71  int tail;
72 };
73 
74 static RSET rsbool_create_base(const struct rset_control *ctrl,
75  NMEM nmem,
76  struct rset_key_control *kcontrol,
77  int scope, RSET rset_l, RSET rset_r)
78 {
79  RSET children[2], rnew;
80  struct rset_private *info;
81 
82  children[0] = rset_l;
83  children[1] = rset_r;
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;
88  rnew->priv = info;
89  return rnew;
90 }
91 
92 RSET rset_create_not(NMEM nmem, struct rset_key_control *kcontrol,
93  int scope, RSET rset_l, RSET rset_r)
94 {
95  return rsbool_create_base(&control_not, nmem, kcontrol,
96  scope, rset_l, rset_r);
97 }
98 
99 static void r_delete(RSET ct)
100 {
101 }
102 
103 static RSFD r_open(RSET ct, int flag)
104 {
105  struct rset_private *info = (struct rset_private *) ct->priv;
106  RSFD rfd;
107  struct rfd_private *p;
108 
109  if (flag & RSETF_WRITE)
110  {
111  yaz_log(YLOG_FATAL, "bool set type is read-only");
112  return NULL;
113  }
114  rfd = rfd_create_base(ct);
115  if (rfd->priv)
116  p = (struct rfd_private *)rfd->priv;
117  else {
118  p = nmem_malloc(ct->nmem,sizeof(*p));
119  rfd->priv = 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);
122  }
123 
124  yaz_log(YLOG_DEBUG,"rsbool (%s) open [%p]", ct->control->desc, rfd);
125  p->hits=0;
126 
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);
131  p->tail = 0;
132  return rfd;
133 }
134 
135 static void r_close (RSFD rfd)
136 {
137  struct rfd_private *prfd=(struct rfd_private *)rfd->priv;
138 
139  rset_close (prfd->rfd_l);
140  rset_close (prfd->rfd_r);
141 }
142 
143 static int r_forward(RSFD rfd, void *buf, TERMID *term,
144  const void *untilbuf)
145 {
146  struct rfd_private *p = (struct rfd_private *)rfd->priv;
147  const struct rset_key_control *kctrl=rfd->rset->keycontrol;
148 
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);
153  p->tail = 0;
154  return rset_read(rfd,buf,term);
155 }
156 
157 
158 /*
159  1,1 1,3
160  1,9 2,1
161  1,11 3,1
162  2,9
163 
164  1,1 1,1
165  1,3 1,3
166  1,9
167  1,11
168  2,1 2,1
169  2,9
170  3,1
171 */
172 
173 static int r_read_not(RSFD rfd, void *buf, TERMID *term)
174 {
175  struct rfd_private *p = (struct rfd_private *)rfd->priv;
176  const struct rset_key_control *kctrl = rfd->rset->keycontrol;
177 
178  while (p->more_l)
179  {
180  int cmp;
181 
182  if (p->more_r)
183  cmp = (*kctrl->cmp)(p->buf_l, p->buf_r);
184  else
185  cmp = -rfd->rset->scope;
186 
187  if (cmp <= -rfd->rset->scope)
188  { /* cmp == -2 */
189  memcpy (buf, p->buf_l, kctrl->key_size);
190  if (term)
191  *term=p->term_l;
192  p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
193  p->hits++;
194  return 1;
195  }
196  else if (cmp >= rfd->rset->scope) /* cmp >1 */
197  {
198  p->more_r = rset_forward( p->rfd_r, p->buf_r,
199  &p->term_r, p->buf_l);
200  }
201  else
202  { /* cmp== -1, 0, or 1 */
203  memcpy (buf, p->buf_l, kctrl->key_size);
204  if (term)
205  *term = p->term_l;
206  do
207  {
208  p->more_l = rset_read(p->rfd_l, p->buf_l, &p->term_l);
209  if (!p->more_l)
210  break;
211  cmp = (*kctrl->cmp)(p->buf_l, buf);
212  } while (abs(cmp)<rfd->rset->scope);
213  /* (cmp >= -1 && cmp <= 1) */
214  do
215  {
216  p->more_r = rset_read(p->rfd_r, p->buf_r, &p->term_r);
217  if (!p->more_r)
218  break;
219  cmp = (*kctrl->cmp)(p->buf_r, buf);
220  } while (abs(cmp)<rfd->rset->scope);
221  /* (cmp >= -1 && cmp <= 1) */
222  }
223  }
224  return 0;
225 }
226 
227 static void r_pos(RSFD rfd, double *current, double *total)
228 {
229  struct rfd_private *p = (struct rfd_private *)rfd->priv;
230  double lcur, ltot;
231  double rcur, rtot;
232  double r;
233  ltot = -1;
234  rtot = -1;
235  rset_pos(p->rfd_l, &lcur, &ltot);
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 */
240  }
241  if (rtot < 0)
242  rtot = rcur = 0; /* if only one useful, use it */
243  if (ltot < 0)
244  ltot = lcur = 0;
245  if (rtot+ltot < 1)
246  { /* empty rset */
247  *current = *total = 0;
248  return;
249  }
250  r = 1.0*(lcur+rcur)/(ltot+rtot); /* weighed average of l and r */
251  *current = (double) (p->hits);
252  *total = *current/r ;
253 #if RSET_DEBUG
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);
257 #endif
258 }
259 
260 static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm)
261 {
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);
265 }
266 
267 /*
268  * Local variables:
269  * c-basic-offset: 4
270  * c-file-style: "Stroustrup"
271  * indent-tabs-mode: nil
272  * End:
273  * vim: shiftwidth=4 tabstop=8 expandtab
274  */
275 
static void r_close(RSFD rfd)
Definition: rsbool.c:135
static void r_get_terms(RSET ct, TERMID *terms, int maxterms, int *curterm)
Definition: rsbool.c:260
int tail
Definition: rsbool.c:71
void * buf
Definition: rsisamb.c:65
#define rset_getterms(ct, terms, maxterms, curterm)
Definition: rset.h:209
struct rset_key_control * keycontrol
Definition: rset.h:153
static RSET rsbool_create_base(const struct rset_control *ctrl, NMEM nmem, struct rset_key_control *kcontrol, int scope, RSET rset_l, RSET rset_r)
Definition: rsbool.c:74
RSFD rfd_create_base(RSET rs)
Common constuctor for RFDs.
Definition: rset.c:43
RSFD rfd_l
Definition: rsbool.c:63
int scope
Definition: rset.h:159
#define RSETF_READ
Definition: rset.h:199
RSET rset_r
Definition: rsbool.c:58
int key_size
Definition: rset.h:128
#define rset_open(rs, wflag)
Definition: rset.h:202
int rset_no_write(RSFD rfd, const void *buf)
Definition: rset.c:431
RSET rset
Definition: rset.h:74
RSET rset_l
Definition: rsbool.c:57
const char * scope
Definition: tstlockscope.c:40
#define rset_read(rfd, buf, term)
Definition: rset.h:217
static void r_pos(RSFD rfd, double *current, double *total)
Definition: rsbool.c:227
void * priv
Definition: rset.h:155
static void r_delete(RSET ct)
Definition: rsbool.c:99
int more_r
Definition: rsbool.c:66
static int r_forward(RSFD rfd, void *buf, TERMID *term, const void *untilbuf)
Definition: rsbool.c:143
static int r_read_not(RSFD rfd, void *buf, TERMID *term)
Definition: rsbool.c:173
RSFD rfd_r
Definition: rsbool.c:64
RSET rset_create_not(NMEM nmem, struct rset_key_control *kcontrol, int scope, RSET rset_l, RSET rset_r)
Definition: rsbool.c:92
void * buf_r
Definition: rsbool.c:68
long zint
Zebra integer.
Definition: util.h:66
NMEM nmem
Definition: rset.h:156
TERMID term_l
Definition: rsbool.c:69
static RSFD r_open(RSET ct, int flag)
Definition: rsbool.c:103
Definition: rset.h:150
Definition: rset.h:73
void * buf_l
Definition: rsbool.c:67
TERMID term_r
Definition: rsbool.c:70
static const struct rset_control control_not
Definition: rsbool.c:43
void * priv
Definition: rset.h:75
zint hits
Definition: rsbool.c:62
void rset_close(RSFD rfd)
Closes a result set RFD handle.
Definition: rset.c:98
Definition: rset.h:50
#define rset_forward(rfd, buf, term, untilbuf)
Definition: rset.h:205
#define rset_pos(rfd, cur, tot)
Definition: rset.h:213
int more_l
Definition: rsbool.c:65
RSET rset_create_base(const struct rset_control *sel, NMEM nmem, struct rset_key_control *kcontrol, int scope, TERMID term, int no_children, RSET *children)
Common constuctor for RSETs.
Definition: rset.c:164
#define RSETF_WRITE
Definition: rset.h:200