X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=isamb%2Fisamb.c;h=1bf6389d44f1da38210ecd445558e4332ae8baba;hb=39b9f004ecc7242730ef003f387a16c50dac33f0;hp=c732143457f9b8f1dc2eb9a1ecb3cb601cf7237e;hpb=05259bf944ff61befc9bee89b7377bf365b25099;p=idzebra-moved-to-github.git diff --git a/isamb/isamb.c b/isamb/isamb.c index c732143..1bf6389 100644 --- a/isamb/isamb.c +++ b/isamb/isamb.c @@ -1,4 +1,4 @@ -/* $Id: isamb.c,v 1.30 2004-06-01 12:56:38 adam Exp $ +/* $Id: isamb.c,v 1.36 2004-06-02 12:30:32 adam Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Index Data Aps @@ -26,6 +26,10 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include +#ifndef ISAMB_DEBUG +#define ISAMB_DEBUG 0 +#endif + struct ISAMB_head { int first_block; int last_block; @@ -204,6 +208,9 @@ ISAMB isamb_open (BFiles bfs, const char *name, int writeflag, ISAMC_M *method, assert(isamb->file[i].head.block_size == b_size); b_size = b_size * 4; } +#if ISAMB_DEBUG + logf(LOG_WARN, "isamb debug enabled. Things will be slower than usual"); +#endif return isamb; } @@ -319,8 +326,7 @@ void isamb_close (ISAMB isamb) xfree (isamb); } - -struct ISAMB_block *open_block (ISAMB b, ISAMC_P pos) +static struct ISAMB_block *open_block (ISAMB b, ISAMC_P pos) { int cat = pos&CAT_MASK; struct ISAMB_block *p; @@ -1001,6 +1007,63 @@ void isamb_pp_close (ISAMB_PP pp) isamb_pp_close_x (pp, 0, 0); } +/* simple recursive dumper .. */ +static void isamb_dump_r (ISAMB b, ISAMB_P pos, void (*pr)(const char *str), + int level) +{ + char buf[1024]; + char prefix_str[1024]; + if (pos) + { + struct ISAMB_block *p = open_block (b, pos); + sprintf(prefix_str, "%*s %d cat=%d size=%d max=%d", level*2, "", + pos, p->cat, p->size, b->file[p->cat].head.block_max); + (*pr)(prefix_str); + sprintf(prefix_str, "%*s %d", level*2, "", pos); + if (p->leaf) + { + while (p->offset < p->size) + { + char *src = p->bytes + p->offset; + char *dst = buf; + (*b->method->code_item)(ISAMC_DECODE, p->decodeClientData, + &dst, &src); + (*b->method->log_item)(LOG_DEBUG, buf, prefix_str); + p->offset = src - (char*) p->bytes; + } + assert(p->offset == p->size); + } + else + { + char *src = p->bytes + p->offset; + int sub; + int item_len; + + decode_ptr (&src, &sub); + p->offset = src - (char*) p->bytes; + + isamb_dump_r(b, sub, pr, level+1); + + while (p->offset < p->size) + { + decode_ptr (&src, &item_len); + (*b->method->log_item)(LOG_DEBUG, src, prefix_str); + src += item_len; + decode_ptr (&src, &sub); + + p->offset = src - (char*) p->bytes; + + isamb_dump_r(b, sub, pr, level+1); + } + } + close_block(b,p); + } +} + +void isamb_dump (ISAMB b, ISAMB_P pos, void (*pr)(const char *str)) +{ + return isamb_dump_r(b, pos, pr, 0); +} #if 0 /* Old isamb_pp_read that Adam wrote, kept as a reference in case we need to @@ -1061,7 +1124,7 @@ int isamb_pp_read (ISAMB_PP pp, void *buf) (*pp->isamb->method->code_item)(ISAMC_DECODE, p->decodeClientData, &dst, &src); p->offset = src - (char*) p->bytes; - key_logdump_txt(LOG_DEBUG,buf, "isamb_pp_read returning 1"); + /* key_logdump_txt(LOG_DEBUG,buf, "isamb_pp_read returning 1"); */ return 1; } @@ -1099,61 +1162,75 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) int item_len; int pos; int nxtpos; + int descending=0; /* used to prevent a border condition error */ if (!p) return 0; +#if ISAMB_DEBUG logf(LOG_DEBUG,"isamb_pp_forward starting [%p] p=%d",pp,p->pos); (*pp->isamb->method->log_item)(LOG_DEBUG, untilbuf, "until"); (*pp->isamb->method->log_item)(LOG_DEBUG, buf, "buf"); +#endif while (1) { - while ( p->offset == p->size) + 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->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 */ + 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 */ + cmp=-2 ; /* descend to the last node, as we have + no value to cmp */ else { decode_ptr(&src, &item_len); - logf(LOG_DEBUG,"isamb_pp_forward (B) on a high node. ofs=%d sz=%d nxtpos=%d ", +#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->log_item)(LOG_DEBUG, src, ""); +#endif if (untilbuf) cmp=(*pp->isamb->method->compare_item)(untilbuf,src); else @@ -1163,8 +1240,11 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) } 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 ; @@ -1176,8 +1256,10 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) 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 @@ -1185,46 +1267,59 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) 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)", + "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 */ - 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 (untilbuf) - cmp=(*pp->isamb->method->compare_item)(untilbuf,buf); - else - cmp=-2; - logf(LOG_DEBUG,"isamb_pp_forward on a leaf. cmp=%d", - cmp); - (*pp->isamb->method->log_item)(LOG_DEBUG, buf, ""); - - if (cmp <2) - { - if (untilbuf) - { - (*pp->isamb->method->log_item)(LOG_DEBUG, buf, - "isamb_pp_forward returning 1"); - } - else + if (p->offset == p->size) { + descending = 0; + } + else + { + assert (p->offset < p->size); + 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 (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->log_item)(LOG_DEBUG, buf, ""); +#endif + if (cmp <2) { - (*pp->isamb->method->log_item)(LOG_DEBUG, buf, - "isamb_pp_read returning 1 (fwd)"); +#if ISAMB_DEBUG + if (untilbuf) + { + (*pp->isamb->method->log_item)( + LOG_DEBUG, buf, "isamb_pp_forward returning 1"); + } + else + { + (*pp->isamb->method->log_item)( + LOG_DEBUG, buf, "isamb_pp_read returning 1 (fwd)"); + } +#endif + pp->returned_numbers++; + return 1; } - pp->returned_numbers++; - return 1; - } - else - pp->skipped_numbers++; + else + pp->skipped_numbers++; + } } /* leaf */ } /* main loop */ }