Zebra not returning Valid XML.
[idzebra-moved-to-github.git] / rset / rsmultiandor.c
index 7b6b69a..fceb772 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rsmultiandor.c,v 1.3 2004-09-28 16:39:46 heikki Exp $
+/* $Id: rsmultiandor.c,v 1.6 2004-10-15 10:07:34 heikki Exp $
    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
    Index Data Aps
 
@@ -47,13 +47,12 @@ static RSFD r_open_and (RSET ct, int flag);
 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_read_and (RSFD rfd, void *buf, TERMID *term);
+static int r_read_or (RSFD rfd, void *buf, TERMID *term);
 static int r_write (RSFD rfd, const void *buf);
-static int r_forward_and(RSFD rfd, void *buf,
+static int r_forward_and(RSFD rfd, void *buf, TERMID *term,
                      const void *untilbuf);
-static int r_forward_or(RSFD rfd, void *buf,
+static int r_forward_or(RSFD rfd, void *buf, TERMID *term,
                      const void *untilbuf);
 static void r_pos (RSFD rfd, double *current, double *total);
 
@@ -63,7 +62,6 @@ static const struct rset_control control_or =
     r_delete,
     r_open_or,
     r_close,
-    r_rewind,
     r_forward_or,
     r_pos,
     r_read_or,
@@ -75,7 +73,6 @@ static const struct rset_control control_and =
     r_delete,
     r_open_and,
     r_close,
-    r_rewind,
     r_forward_and,
     r_pos,
     r_read_and,
@@ -97,6 +94,7 @@ struct heap_item {
     RSFD fd;
     void *buf;
     RSET rset;
+    TERMID term;
 };
 
 struct heap {
@@ -261,7 +259,7 @@ static RSET rsmulti_andor_create( NMEM nmem, const struct key_control *kcontrol,
                            int scope, int no_rsets, RSET* rsets, 
                            const struct rset_control *ctrl)
 {
-    RSET rnew=rset_create_base(ctrl, nmem,kcontrol, scope);
+    RSET rnew=rset_create_base(ctrl, nmem,kcontrol, scope,0);
     struct rset_multiandor_info *info;
     info = (struct rset_multiandor_info *) nmem_malloc(rnew->nmem,sizeof(*info));
     info->no_rsets=no_rsets;
@@ -306,7 +304,7 @@ static RSFD r_open_andor (RSET ct, int flag, int is_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);
@@ -341,7 +339,7 @@ static RSFD r_open_andor (RSET ct, int flag, int is_and)
     { /* read the array and sort it */
         for (i=0; i<info->no_rsets; i++){
             p->items[i].fd=rset_open(info->rsets[i],RSETF_READ);
-            if ( !rset_read(p->items[i].fd, p->items[i].buf) )
+            if (!rset_read(p->items[i].fd, p->items[i].buf, &p->items[i].term))
                 p->eof=1;
             p->tailbits[i]=0;
         }
@@ -350,7 +348,7 @@ static RSFD r_open_andor (RSET ct, int flag, int is_and)
     { /* fill the heap for ORing */
         for (i=0; i<info->no_rsets; i++){
             p->items[i].fd=rset_open(info->rsets[i],RSETF_READ);
-            if ( rset_read(p->items[i].fd, p->items[i].buf) )
+            if ( rset_read(p->items[i].fd, p->items[i].buf, &p->items[i].term))
                 heap_insert(p->h, &(p->items[i]));
         }
     }
@@ -385,24 +383,44 @@ static void r_close (RSFD rfd)
 
 
 
-static int r_forward_or(RSFD rfd, void *buf, const void *untilbuf)
+static int r_forward_or(RSFD rfd, void *buf, 
+                        TERMID *term,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,
+                         &p->h->heap[1]->term, untilbuf))
+            heap_balance(p->h);
+        else 
+        {
+            heap_delete(p->h);
+            if (heap_empty(p->h))
+                return 0;
+        }
+
+    }
+    return r_read_or(rfd,buf,term);
+}
+
+
+static int r_read_or (RSFD rfd, void *buf, TERMID *term)
 {
     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); 
+    if (term)
+        *term=it->term;
     (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, &it->term);
     if ( rdres )
         heap_balance(mrfd->h);
     else
@@ -411,12 +429,7 @@ static int r_forward_or(RSFD rfd, void *buf, const void *untilbuf)
 
 }
 
-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)
+static int r_read_and (RSFD rfd, void *buf, TERMID *term)
 { /* Has to return all hits where each item points to the */
   /* same sysno (scope), in order. Keep an extra key (hitkey) */
   /* as long as all records do not point to hitkey, forward */
@@ -448,7 +461,10 @@ static int r_read_and (RSFD rfd, void *buf)
             }
             /* return the lowest tail */
             memcpy(buf, p->items[mintail].buf, kctrl->key_size); 
-            if (!rset_read(p->items[mintail].fd, p->items[mintail].buf))
+            if (term)
+                *term=p->items[mintail].term;
+            if (!rset_read(p->items[mintail].fd, p->items[mintail].buf,
+                           &p->items[mintail].term))
             {
                 p->eof=1; /* game over, once tails have been returned */
                 p->tailbits[mintail]=0; 
@@ -472,7 +488,7 @@ static int r_read_and (RSFD rfd, void *buf)
             cmp=(*kctrl->cmp)(p->items[0].buf,p->items[i].buf);
             if (cmp<=-rfd->rset->scope) { /* [0] was behind, forward it */
                 if (!rset_forward(p->items[0].fd, p->items[0].buf, 
-                                  p->items[i].buf))
+                                  &p->items[0].term, p->items[i].buf))
                 {
                     p->eof=1; /* game over */
                     return 0;
@@ -481,7 +497,7 @@ static int r_read_and (RSFD rfd, void *buf)
             } else if (cmp>=rfd->rset->scope)
             { /* [0] was ahead, forward i */
                 if (!rset_forward(p->items[i].fd, p->items[i].buf, 
-                                  p->items[0].buf))
+                                  &p->items[i].term, p->items[0].buf))
                 {
                     p->eof=1; /* game over */
                     return 0;
@@ -499,7 +515,8 @@ static int r_read_and (RSFD rfd, void *buf)
 }
 
 
-static int r_forward_and(RSFD rfd, void *buf, const void *untilbuf)
+static int r_forward_and(RSFD rfd, void *buf, TERMID *term, 
+                         const void *untilbuf)
 { 
     struct rset_multiandor_rfd *p=rfd->priv;
     const struct key_control *kctrl=rfd->rset->keycontrol;
@@ -515,7 +532,7 @@ static int r_forward_and(RSFD rfd, void *buf, const void *untilbuf)
         {
             killtail=1; /* we are moving to a different hit */
             if (!rset_forward(p->items[i].fd, p->items[i].buf, 
-                              untilbuf))
+                              &p->items[i].term, untilbuf))
             {
                 p->eof=1; /* game over */
                 p->tailcount=0;
@@ -529,7 +546,7 @@ static int r_forward_and(RSFD rfd, void *buf, const void *untilbuf)
             p->tailbits[i]=0;
         p->tailcount=0;
     }
-    return r_read_and(rfd,buf);
+    return r_read_and(rfd,buf,term);
 }
 
 static void r_pos (RSFD rfd, double *current, double *total)
@@ -556,11 +573,6 @@ 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)
 {