+ while (1) {
+ if (p->tailcount)
+ { /* we are tailing, find lowest tail and return it */
+ int mintail = -1;
+ int cmp;
+
+ for (i = 0; i<ct->no_children; i++)
+ {
+ if (p->tailbits[i])
+ {
+ if (mintail >= 0)
+ cmp = (*kctrl->cmp)
+ (p->items[i].buf, p->items[mintail].buf);
+ else
+ cmp = -1;
+ if (cmp < 0)
+ mintail = i;
+
+ if (kctrl->get_segment)
+ { /* segments enabled */
+ zint segment = kctrl->get_segment(p->items[i].buf);
+ /* store segment if not stored already */
+ if (!p->segment && segment)
+ p->segment = segment;
+
+ /* skip rest entirely if segments don't match */
+ if (p->segment && segment && p->segment != segment)
+ p->skip = 1;
+ }
+ }
+ }
+ /* return the lowest tail */
+ memcpy(buf, p->items[mintail].buf, kctrl->key_size);
+ 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;
+ (p->tailcount)--;
+ }
+ else
+ {
+ /* still a tail? */
+ cmp = (*kctrl->cmp)(p->items[mintail].buf,buf);
+ if (cmp >= rfd->rset->scope)
+ {
+ p->tailbits[mintail] = 0;
+ (p->tailcount)--;
+ }
+ }
+ if (p->skip)
+ continue; /* skip again.. eventually tailcount will be 0 */
+ (p->hits)++;
+ return 1;
+ }
+ /* not tailing, forward until all records match, and set up */
+ /* as tails. the earlier 'if' will then return the hits */
+ if (p->eof)
+ return 0; /* nothing more to see */
+ i = 1; /* assume items[0] is highest up */
+ while (i < ct->no_children)
+ {
+ int 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[0].term, p->items[i].buf))
+ {
+ p->eof = 1; /* game over */
+ return 0;
+ }
+ i = 0; /* start forwarding from scratch */
+ }
+ else if (cmp>=rfd->rset->scope)
+ { /* [0] was ahead, forward i */
+ if (!rset_forward(p->items[i].fd, p->items[i].buf,
+ &p->items[i].term, p->items[0].buf))
+ {
+ p->eof = 1; /* game over */
+ return 0;
+ }
+ }
+ else
+ i++;
+ } /* while i */
+ /* if we get this far, all rsets are now within +- scope of [0] */
+ /* ergo, we have a hit. Mark them all as tailing, and let the */
+ /* upper 'if' return the hits in right order */
+ for (i = 0; i < ct->no_children; i++)
+ p->tailbits[i] = 1;
+ p->tailcount = ct->no_children;
+ p->segment = 0;
+ p->skip = 0;
+ } /* while 1 */