- return isamb_pp_forward(pp,buf,0);
-}
-#endif
-
-#define NEW_FORWARD 0
-
-#if NEW_FORWARD == 1
-
-/*
-#undef ISAMB_DEBUB
-#define ISAMB_DEBUG 1
-*/
-
-static int isamb_pp_read_on_leaf(ISAMB_PP pp, void *buf)
-{ /* reads the next item on the current leaf, returns 0 if end of leaf*/
- struct ISAMB_block *p = pp->block[pp->level];
- char *dst;
- char *src;
- if (p->offset == p->size) {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_read_on_leaf returning 0 on node %d",p->pos);
-#endif
- return 0; /* at end of leaf */
- }
- src=p->bytes + p->offset;
- dst=buf;
- (*pp->isamb->method->code_item)
- (ISAMC_DECODE, p->decodeClientData,&dst, &src);
- p->offset = src - (char*) p->bytes;
-#if ISAMB_DEBUG
- (*pp->isamb->method->log_item)(LOG_DEBUG, buf, "read_on_leaf returning 1");
-#endif
- return 1;
-} /* read_on_leaf */
-
-
-static int isamb_pp_climb_level(ISAMB_PP pp, int *pos)
-{ /* climbs higher in the tree, until finds a level with data left */
- /* returns the node to (consider to) descend to in *pos) */
- struct ISAMB_block *p = pp->block[pp->level];
- char *src;
- int item_len;
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_climb_level starting "
- "at level %d node %d ofs=%d sz=%d",
- pp->level, p->pos, p->offset, p->size);
-#endif
- assert(p->offset <= p->size);
- if (pp->level==0)
- {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_climb_level returning 0 at root");
- return 0;
-#endif
- }
- close_block(pp->isamb, pp->block[pp->level]);
- pp->block[pp->level]=0;
- (pp->level)--;
- p=pp->block[pp->level];
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_climb_level climbed to level %d node %d ofs=%d",
- pp->level, p->pos, p->offset);
-#endif
- assert (!p->leaf);
- assert (p->offset <= p->size);
- if (p->offset == p->size ) {
- /* we came from the last pointer, climb on */
- if (!isamb_pp_climb_level(pp,pos))
- return 0;
- p=pp->block[pp->level];
- }
- else
- {
- /* skip the child we just came from */
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isam_pp_climb_level: skipping lev=%d ofs=%d sz=%d",
- pp->level, p->offset, p->size);
-#endif
- assert (p->offset < p->size );
- src=p->bytes + p->offset;
- decode_ptr(&src, &item_len);
- src += item_len;
- decode_ptr(&src, pos);
- p->offset=src - (char *)p->bytes;
- }
- return 1;
-} /* climb_level */
-
-
-static int isamb_pp_forward_unode(ISAMB_PP pp, int pos, const void *untilbuf)
-{ /* scans a upper node until it finds a child <= untilbuf */
- /* pp points to the key value, as always. pos is the child read from */
- /* the buffer */
- /* if all values are too small, returns the last child in the node */
- /* FIXME - this can be detected, and avoided by looking at the */
- /* parent node, but that gets messy. Presumably the cost is */
- /* pretty low anyway */
- struct ISAMB_block *p = pp->block[pp->level];
- char *src=p->bytes + p->offset;
- int item_len;
- int cmp;
- int nxtpos;
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward_unode starting "
- "at level %d node %d ofs=%di sz=%d",
- pp->level, p->pos, p->offset, p->size);
-#endif
- assert(!p->leaf);
- assert(p->offset <= p->size);
- if (p->offset == p->size) {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward_unode returning at end "
- "at level %d node %d ofs=%di sz=%d",
- pp->level, p->pos, p->offset, p->size);
-#endif
- return pos; /* already at the end of it */
- }
- while(p->offset < p->size) {
- decode_ptr(&src,&item_len);
- cmp=(*pp->isamb->method->compare_item)(untilbuf,src);
- src+=item_len;
- decode_ptr(&src,&nxtpos);
- if (cmp<2)
- {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward_unode returning a hit "
- "at level %d node %d ofs=%di sz=%d",
- pp->level, p->pos, p->offset, p->size);
-#endif
- return pos;
- } /* found one */
- pos=nxtpos;
- p->offset=src-(char*)p->bytes;
- }
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward_unode returning at tail "
- "at level %d node %d ofs=%di sz=%d",
- pp->level, p->pos, p->offset, p->size);
-#endif
- return pos; /* that's the last one in the line */
-
-} /* forward_unode */
-
-static void isamb_pp_descend_to_leaf(ISAMB_PP pp, int pos, const void *untilbuf)
-{ /* climbs down the tree, from pos, to the leftmost leaf */
- struct ISAMB_block *p = pp->block[pp->level];
- char *src;
- assert(!p->leaf);
- ++(pp->level);
- p=open_block(pp->isamb, pos);
- pp->block[pp->level]=p;
- ++(pp->accessed_nodes[pp->maxlevel-pp->level]);
- ++(pp->no_blocks);
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_descend_to_leaf "
- "got lev %d node %d lf=%d",
- pp->level, p->pos, p->leaf);
-#endif
- if (p->leaf)
- return;
- assert (p->offset==0 );
- src=p->bytes + p->offset;
- decode_ptr(&src, &pos);
- p->offset=src-(char*)p->bytes;
- if (untilbuf)
- pos=isamb_pp_forward_unode(pp,pos,untilbuf);
- isamb_pp_descend_to_leaf(pp,pos,untilbuf);
-} /* descend_to_leaf */
-
-static int isamb_pp_find_next_leaf(ISAMB_PP pp)
-{ /* finds the next leaf by climbing up and down */
- int pos;
- if (!isamb_pp_climb_level(pp,&pos))
- return 0;
- isamb_pp_descend_to_leaf(pp, pos,0);
- return 1;