-/* $Id: rsmultiandor.c,v 1.2 2004-09-28 16:12:42 heikki Exp $
+/* $Id: rsmultiandor.c,v 1.5 2004-09-30 09:53:05 heikki Exp $
Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
Index Data Aps
static RSFD r_open_or (RSET ct, int flag);
static void r_close (RSFD rfd);
static void r_delete (RSET ct);
-static void r_rewind (RSFD rfd);
static int r_read_and (RSFD rfd, void *buf);
static int r_read_or (RSFD rfd, void *buf);
static int r_write (RSFD rfd, const void *buf);
r_delete,
r_open_or,
r_close,
- r_rewind,
r_forward_or,
r_pos,
r_read_or,
r_delete,
r_open_and,
r_close,
- r_rewind,
r_forward_and,
r_pos,
r_read_and,
if (flag & RSETF_WRITE)
{
- logf (LOG_FATAL, "multior set type is read-only");
+ logf (LOG_FATAL, "multiandor set type is read-only");
return NULL;
}
rfd=rfd_create_base(ct);
static int r_forward_or(RSFD rfd, void *buf, const void *untilbuf)
+{ /* while heap head behind untilbuf, forward it and rebalance heap */
+ struct rset_multiandor_rfd *p=rfd->priv;
+ const struct key_control *kctrl=rfd->rset->keycontrol;
+ if (heap_empty(p->h))
+ return 0;
+ while ( (*kctrl->cmp)(p->h->heap[1]->buf,untilbuf) < -rfd->rset->scope )
+ {
+ if ( rset_forward(p->h->heap[1]->fd, p->h->heap[1]->buf, untilbuf) )
+ heap_balance(p->h);
+ else
+ {
+ heap_delete(p->h);
+ if (heap_empty(p->h))
+ return 0;
+ }
+
+ }
+ return r_read_or(rfd,buf);
+}
+
+
+static int r_read_or (RSFD rfd, void *buf)
{
struct rset_multiandor_rfd *mrfd=rfd->priv;
const struct key_control *kctrl=rfd->rset->keycontrol;
- struct heap_item it;
+ struct heap_item *it;
int rdres;
if (heap_empty(mrfd->h))
return 0;
- it = *(mrfd->h->heap[1]);
- memcpy(buf,it.buf, kctrl->key_size);
- /* FIXME - This is not right ! */
- /* If called with an untilbuf, we need to compare to that, and */
- /* forward until we are somewhere! */
+ it = mrfd->h->heap[1];
+ memcpy(buf,it->buf, kctrl->key_size);
(mrfd->hits)++;
- if (untilbuf)
- rdres=rset_forward(it.fd, it.buf, untilbuf);
- else
- rdres=rset_read(it.fd, it.buf);
+ rdres=rset_read(it->fd, it->buf);
if ( rdres )
heap_balance(mrfd->h);
else
}
-static int r_read_or (RSFD rfd, void *buf)
-{
- return r_forward_or(rfd, buf,0);
-}
-
static int r_read_and (RSFD rfd, void *buf)
{ /* Has to return all hits where each item points to the */
/* same sysno (scope), in order. Keep an extra key (hitkey) */
static int r_forward_and(RSFD rfd, void *buf, const void *untilbuf)
-{
- return 0;
+{
+ struct rset_multiandor_rfd *p=rfd->priv;
+ const struct key_control *kctrl=rfd->rset->keycontrol;
+ struct rset_multiandor_info *info=rfd->rset->priv;
+ int i;
+ int cmp;
+ int killtail=0;
+
+ for (i=0; i<info->no_rsets;i++)
+ {
+ cmp=(*kctrl->cmp)(p->items[i].buf,untilbuf);
+ if ( cmp <= -rfd->rset->scope )
+ {
+ killtail=1; /* we are moving to a different hit */
+ if (!rset_forward(p->items[i].fd, p->items[i].buf,
+ untilbuf))
+ {
+ p->eof=1; /* game over */
+ p->tailcount=0;
+ return 0;
+ }
+ }
+ }
+ if (killtail)
+ {
+ for (i=0; i<info->no_rsets;i++)
+ p->tailbits[i]=0;
+ p->tailcount=0;
+ }
+ return r_read_and(rfd,buf);
}
static void r_pos (RSFD rfd, double *current, double *total)
}
-static void r_rewind (RSFD rfd)
-{
- assert(!"rewind not implemented yet");
- /* FIXME - rewind all parts, rebalance heap, clear hits */
-}
static int r_write (RSFD rfd, const void *buf)
{