-/* $Id: rsbetween.c,v 1.23 2004-08-31 10:43:36 heikki Exp $
+/* $Id: rsbetween.c,v 1.27 2004-10-15 10:07:34 heikki Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
Index Data Aps
#include <assert.h>
#include <zebrautl.h>
-#include <rsbetween.h>
+#include <rset.h>
#define RSBETWEEN_DEBUG 0
static RSFD r_open_between (RSET ct, int flag);
static void r_close_between (RSFD rfd);
static void r_delete_between (RSET ct);
-static void r_rewind_between (RSFD rfd);
static int r_forward_between(RSFD rfd, void *buf,
- int (*cmpfunc)(const void *p1, const void *p2),
- const void *untilbuf);
-static int r_read_between (RSFD rfd, void *buf);
+ TERMID *term, const void *untilbuf);
+static int r_read_between (RSFD rfd, void *buf, TERMID *term );
static int r_write_between (RSFD rfd, const void *buf);
static void r_pos_between (RSFD rfd, double *current, double *total);
r_delete_between,
r_open_between,
r_close_between,
- r_rewind_between,
- r_forward_between, /* rset_default_forward, */
+ r_forward_between,
r_pos_between,
r_read_between,
r_write_between,
const struct rset_control *rset_kind_between = &control;
struct rset_between_info {
- int key_size;
- RSET rset_l;
- RSET rset_m;
- RSET rset_r;
- RSET rset_attr;
- int (*cmp)(const void *p1, const void *p2);
- char *(*printer)(const void *p1, char *buf);
+ RSET rset_l; /* left arg, start tag */
+ RSET rset_m; /* the thing itself */
+ RSET rset_r; /* right arg, end tag */
+ RSET rset_attr; /* attributes , optional */
};
struct rset_between_rfd {
void *buf_m;
void *buf_r;
void *buf_attr;
- int level;
- struct rset_between_rfd *next;
- struct rset_between_info *info;
+ TERMID term_m; /* we only return terms for the mid argument */
+ int level; /* counting start/end tags */
zint hits;
};
}
#endif
-RSET rsbetween_create( NMEM nmem, int key_size,
- int (*cmp)(const void *p1, const void *p2),
- RSET rset_l, RSET rset_m, RSET rset_r, RSET rset_attr,
- char *(*printer)(const void *p1, char *buf) )
+RSET rsbetween_create( NMEM nmem, const struct key_control *kcontrol,
+ int scope,
+ RSET rset_l, RSET rset_m, RSET rset_r, RSET rset_attr)
{
- RSET rnew=rset_create_base(&control, nmem);
- struct rset_between_info *info;
- info = (struct rset_between_info *) nmem_malloc(rnew->nmem,sizeof(*info));
- info->key_size = key_size;
+ RSET rnew=rset_create_base(&control, nmem, kcontrol, scope,0);
+ struct rset_between_info *info=
+ (struct rset_between_info *) nmem_malloc(rnew->nmem,sizeof(*info));
info->rset_l = rset_l;
info->rset_m = rset_m;
info->rset_r = rset_r;
info->rset_attr = rset_attr;
- info->cmp = cmp;
- info->printer = printer;
-
rnew->priv=info;
return rnew;
}
else {
p = (struct rset_between_rfd *) nmem_malloc(ct->nmem, (sizeof(*p)));
rfd->priv=p;
- p->buf_l = nmem_malloc(ct->nmem, (info->key_size));
- p->buf_m = nmem_malloc(ct->nmem, (info->key_size));
- p->buf_r = nmem_malloc(ct->nmem, (info->key_size));
- p->buf_attr = nmem_malloc(ct->nmem, (info->key_size));
+ p->buf_l = nmem_malloc(ct->nmem, (ct->keycontrol->key_size));
+ p->buf_m = nmem_malloc(ct->nmem, (ct->keycontrol->key_size));
+ p->buf_r = nmem_malloc(ct->nmem, (ct->keycontrol->key_size));
+ p->buf_attr = nmem_malloc(ct->nmem, (ct->keycontrol->key_size));
}
p->rfd_l = rset_open (info->rset_l, RSETF_READ);
p->rfd_m = rset_open (info->rset_m, RSETF_READ);
p->rfd_r = rset_open (info->rset_r, RSETF_READ);
- p->more_l = rset_read (p->rfd_l, p->buf_l);
- p->more_m = rset_read (p->rfd_m, p->buf_m);
- p->more_r = rset_read (p->rfd_r, p->buf_r);
+ p->more_l = rset_read (p->rfd_l, p->buf_l,NULL);
+ p->more_m = rset_read (p->rfd_m, p->buf_m, &p->term_m);
+ p->more_r = rset_read (p->rfd_r, p->buf_r,NULL);
if (info->rset_attr)
{
p->rfd_attr = rset_open (info->rset_attr, RSETF_READ);
- p->more_attr = rset_read (p->rfd_attr, p->buf_attr);
+ p->more_attr = rset_read (p->rfd_attr, p->buf_attr, NULL);
}
p->level=0;
p->hits=0;
rfd_delete_base(rfd);
}
-static void r_rewind_between (RSFD rfd)
-{
- struct rset_between_info *info =(struct rset_between_info *)rfd->rset->priv;
- struct rset_between_rfd *p=(struct rset_between_rfd *)rfd->priv;
-
-#if RSBETWEEN_DEBUG
- logf (LOG_DEBUG, "rsbetween_rewind");
-#endif
- rset_rewind (p->rfd_l);
- rset_rewind (p->rfd_m);
- rset_rewind (p->rfd_r);
- p->more_l = rset_read (p->rfd_l, p->buf_l);
- p->more_m = rset_read (p->rfd_m, p->buf_m);
- p->more_r = rset_read (p->rfd_r, p->buf_r);
- if (info->rset_attr)
- {
- rset_rewind (p->rfd_attr);
- p->more_attr = rset_read (p->rfd_attr, p->buf_attr);
- }
- p->level=0;
- p->hits=0;
-}
-
-static int r_forward_between(RSFD rfd, void *buf,
- int (*cmpfunc)(const void *p1, const void *p2),
- const void *untilbuf)
+static int r_forward_between(RSFD rfd, void *buf,
+ TERMID *term, const void *untilbuf)
{
- struct rset_between_info *info =(struct rset_between_info *)rfd->rset->priv;
struct rset_between_rfd *p=(struct rset_between_rfd *)rfd->priv;
int rc;
#if RSBETWEEN_DEBUG
/* It is enough to forward the m pointer here, the read will */
/* naturally forward the l, m, and attr pointers */
if (p->more_m)
- p->more_m=rset_forward(p->rfd_m, p->buf_m,
- info->cmp,untilbuf);
+ p->more_m=rset_forward(p->rfd_m, p->buf_m, term, untilbuf);
#if RSBETWEEN_DEBUG
log2( p, "fwd: after forward M", 0,0);
#endif
- rc = r_read_between(rfd, buf);
+ rc = r_read_between(rfd, buf, term);
#if RSBETWEEN_DEBUG
log2( p, "fwd: after forward", 0,0);
#endif
-static int r_read_between (RSFD rfd, void *buf)
+static int r_read_between (RSFD rfd, void *buf, TERMID *term)
{
struct rset_between_info *info =(struct rset_between_info *)rfd->rset->priv;
struct rset_between_rfd *p=(struct rset_between_rfd *)rfd->priv;
+ const struct key_control *kctrl=rfd->rset->keycontrol;
int cmp_l=0;
int cmp_r=0;
int attr_match = 0;
/* forward L until past m, count levels, note rec boundaries */
if (p->more_l)
- cmp_l= (*info->cmp)(p->buf_l, p->buf_m);
+ cmp_l= (*kctrl->cmp)(p->buf_l, p->buf_m);
else
{
p->level = 0;
- cmp_l=2; /* past this record */
+ cmp_l=rfd->rset->scope; /* past this record */
}
#if RSBETWEEN_DEBUG
log2( p, "after first L", cmp_l, cmp_r);
while (cmp_l < 0) /* l before m */
{
- if (cmp_l == -2)
+ if (cmp_l <= - rfd->rset->scope) /* ==-2 */
p->level=0; /* earlier record */
- if (cmp_l == -1)
+ if (cmp_l > - rfd->rset->scope) /* == -1 */
{
p->level++; /* relevant start tag */
attr_match = 0;
while (p->more_attr)
{
- cmp_attr = (*info->cmp)(p->buf_attr, p->buf_l);
+ cmp_attr = (*kctrl->cmp)(p->buf_attr, p->buf_l);
if (cmp_attr == 0)
{
attr_match = 1;
}
else if (cmp_attr > 0)
break;
- else if (cmp_attr==-1)
- p->more_attr = rset_read (p->rfd_attr, p->buf_attr);
+ else if (cmp_attr > - rfd->rset->scope) /* == -1 */
+ p->more_attr = rset_read (p->rfd_attr,
+ p->buf_attr,NULL);
/* if we had a forward that went all the way to
* the seqno, we could use that. But fwd only goes
* to the sysno */
- else if (cmp_attr==-2)
+ else if (cmp_attr <= - rfd->rset->scope) /* ==-2 */
{
p->more_attr = rset_forward( p->rfd_attr,
- p->buf_attr, info->cmp, p->buf_l);
+ p->buf_attr, NULL, p->buf_l);
#if RSBETWEEN_DEBUG
- logf(LOG_DEBUG, "btw: after frowarding attr m=%d",p->more_attr);
+ logf(LOG_DEBUG, "btw: after frowarding attr m=%d",
+ p->more_attr);
#endif
}
} /* while more_attr */
}
#define NEWCODE 1
#if NEWCODE
- if (cmp_l==-2)
+ if (cmp_l <= - rfd->rset->scope )/* ==-2 */
{
if (p->more_l)
{
- p->more_l=rset_forward(p->rfd_l,
- p->buf_l, info->cmp, p->buf_m);
+ p->more_l=rset_forward(p->rfd_l, p->buf_l, NULL, p->buf_m);
if (p->more_l)
- cmp_l= (*info->cmp)(p->buf_l, p->buf_m);
+ cmp_l= (*kctrl->cmp)(p->buf_l, p->buf_m);
else
- cmp_l=2;
+ cmp_l=rfd->rset->scope; /*2*/
#if RSBETWEEN_DEBUG
log2( p, "after forwarding L", cmp_l, cmp_r);
#endif
}
} else
{
- p->more_l = rset_read (p->rfd_l, p->buf_l);
+ p->more_l = rset_read (p->rfd_l, p->buf_l, NULL);
}
#else
- p->more_l = rset_read (p->rfd_l, p->buf_l);
+ p->more_l = rset_read (p->rfd_l, p->buf_l, NULL);
#endif
if (p->more_l)
{
- cmp_l= (*info->cmp)(p->buf_l, p->buf_m);
+ cmp_l= (*kctrl->cmp)(p->buf_l, p->buf_m);
}
else
- cmp_l=2;
+ cmp_l=rfd->rset->scope; /*2*/
#if RSBETWEEN_DEBUG
log2( p, "end of L loop", cmp_l, cmp_r);
#endif
log2( p, "Before moving R", cmp_l, cmp_r);
#endif
if (p->more_r)
- cmp_r= (*info->cmp)(p->buf_r, p->buf_m);
+ cmp_r= (*kctrl->cmp)(p->buf_r, p->buf_m);
else
- cmp_r=2;
+ cmp_r=rfd->rset->scope; /*2*/
#if RSBETWEEN_DEBUG
log2( p, "after first R", cmp_l, cmp_r);
#endif
while (cmp_r < 0) /* r before m */
{
/* -2, earlier record, don't count level */
- if (cmp_r == -1)
+ if (cmp_r > -rfd->rset->scope) /* == -1 */
p->level--; /* relevant end tag */
if (p->more_r)
{
#if NEWCODE
- if (cmp_r==-2)
+ if (cmp_r <= - rfd->rset->scope) /* == -2 */
{
- p->more_r=rset_forward(p->rfd_r,
- p->buf_r, info->cmp, p->buf_m);
+ p->more_r=rset_forward(p->rfd_r, p->buf_r, NULL, p->buf_m);
} else
{
- p->more_r = rset_read (p->rfd_r, p->buf_r);
+ p->more_r = rset_read (p->rfd_r, p->buf_r, NULL);
}
if (p->more_r)
- cmp_r= (*info->cmp)(p->buf_r, p->buf_m);
+ cmp_r= (*kctrl->cmp)(p->buf_r, p->buf_m);
#else
- p->more_r = rset_read (p->rfd_r, p->buf_r);
- cmp_r= (*info->cmp)(p->buf_r, p->buf_m);
+ p->more_r = rset_read (p->rfd_r, p->buf_r, NULL);
+ cmp_r= (*kctrl->cmp)(p->buf_r, p->buf_m);
#endif
}
else
- cmp_r=2;
+ cmp_r=rfd->rset->scope; /*2*/
#if RSBETWEEN_DEBUG
log2( p, "End of R loop", cmp_l, cmp_r);
#endif
if ( attr_match && p->level > 0) /* within a tag pair (or deeper) */
{
- memcpy (buf, p->buf_m, info->key_size);
+ memcpy (buf, p->buf_m, kctrl->key_size);
+ if (term)
+ *term=p->term_m;
#if RSBETWEEN_DEBUG
log2( p, "Returning a hit (and forwarding m)", cmp_l, cmp_r);
#endif
- p->more_m = rset_read (p->rfd_m, p->buf_m);
- if (cmp_l == 2)
+ p->more_m = rset_read (p->rfd_m, p->buf_m, NULL);
+ if (cmp_l >= rfd->rset->scope) /* == 2 */
p->level = 0;
p->hits++;
return 1;
return 0; /* ergo, nothing can be found. stop scanning */
}
#if NEWCODE
- if (cmp_l == 2)
+ if (cmp_l >= rfd->rset->scope) /* == 2 */
{
p->level = 0;
- p->more_m=rset_forward(p->rfd_m,
- p->buf_m, info->cmp, p->buf_l);
+ p->more_m=rset_forward(p->rfd_m, p->buf_m, &p->term_m, p->buf_l);
} else
{
- p->more_m = rset_read (p->rfd_m, p->buf_m);
+ p->more_m = rset_read (p->rfd_m, p->buf_m, &p->term_m);
}
#else
- if (cmp_l == 2)
+ if (cmp_l >= rfd->rset->scope ) /* == 2 */
p->level = 0;
p->more_m = rset_read (p->rfd_m, p->buf_m);
#endif