- while (1)
- {
- while ( (p->offset == p->size) && !descending )
- { /* end of this block - climb higher */
- assert (p->offset <= p->size);
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward climbing from l=%d",
- pp->level);
-#endif
- if (pp->level == 0)
- {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward returning 0 at root");
-#endif
- return 0; /* at end of the root, nothing left */
- }
- 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_forward climbed to node %d off=%d",
- p->pos, p->offset);
-#endif
- assert(!p->leaf);
- assert(p->offset <= p->size);
- /* skip the child we have handled */
- if (p->offset != p->size)
- {
- src = p->bytes + p->offset;
- decode_ptr(&src, &item_len);
-#if ISAMB_DEBUG
- (*pp->isamb->method->codec.log_item)(LOG_DEBUG, src,
- " isamb_pp_forward "
- "climb skipping old key");
-#endif
- src += item_len;
- decode_ptr(&src,&pos);
- p->offset = src - (char*) p->bytes;
- break; /* even if this puts us at the end of the block, we
- need to descend to the last pos. UGLY coding,
- clean up some day */
- }
- }
- if (!p->leaf)
- {
- src = p->bytes + p->offset;
- if (p->offset == p->size)
- cmp=-2 ; /* descend to the last node, as we have
- no value to cmp */
- else
- {
- decode_ptr(&src, &item_len);
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward (B) on a high node. "
- "ofs=%d sz=%d nxtpos=%d ",
- p->offset,p->size,pos);
- (*pp->isamb->method->codec.log_item)(LOG_DEBUG, src, "");
-#endif
- if (untilbuf)
- cmp=(*pp->isamb->method->compare_item)(untilbuf,src);
- else
- cmp=-2;
- src += item_len;
- decode_ptr(&src,&nxtpos);
- }
- if (cmp<2)
- {
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isambb_pp_forward descending l=%d p=%d ",
- pp->level, pos);
-#endif
- descending=1; /* prevent climbing for a while */
- ++(pp->level);
- p = open_block(pp->isamb,pos);
- pp->block[pp->level] = p ;
- pp->total_size += p->size;
- (pp->accessed_nodes[pp->maxlevel - pp->level])++;
- pp->no_blocks++;
- if ( !p->leaf)
- { /* block starts with a pos */
- src = p->bytes + p->offset;
- decode_ptr(&src,&pos);
- p->offset=src-(char*) p->bytes;
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward: block %d starts with %d",
- p->pos, pos);
-#endif
- }
- } /* descend to the node */
- else
- { /* skip the node */
- p->offset = src - (char*) p->bytes;
- pos=nxtpos;
- (pp->skipped_nodes[pp->maxlevel - pp->level -1])++;
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,
- "isamb_pp_forward: skipping block on level %d, noting "
- "on %d (%d)",
- pp->level, pp->maxlevel - pp->level-1 ,
- pp->skipped_nodes[pp->maxlevel - pp->level-1 ]);
-#endif
- /* 0 is always leafs, 1 is one level above leafs etc, no
- * matter how high tree */
- }
- } /* not on a leaf */
- else
- { /* on a leaf */
- if (p->offset == p->size) {
- descending = 0;
- }
- else
- {
- assert (p->offset < p->size);
- src = p->bytes + p->offset;
- dst=buf;
- (*pp->isamb->method->codec.decode)(p->decodeClientData,
- &dst, &src);
- p->offset = src - (char*) p->bytes;
- if (untilbuf)
- cmp=(*pp->isamb->method->compare_item)(untilbuf,buf);
- else
- cmp=-2;
-#if ISAMB_DEBUG
- logf(LOG_DEBUG,"isamb_pp_forward on a leaf. cmp=%d",
- cmp);
- (*pp->isamb->method->codec.log_item)(LOG_DEBUG, buf, "");
-#endif
- if (cmp <2)
- {