X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=isamb%2Fisamb.c;h=c46246a5f35943411455fa75ea2b468138adc9d4;hb=9f8807e43ac456d96e56bd6a4d1c2edcf1851ba7;hp=59d0b2657b05dd39585fdc05f87a7e7650f6fe7e;hpb=2fb4c6ee4faf175f2837e794366539c8683f42c8;p=idzebra-moved-to-github.git diff --git a/isamb/isamb.c b/isamb/isamb.c index 59d0b26..c46246a 100644 --- a/isamb/isamb.c +++ b/isamb/isamb.c @@ -1,4 +1,4 @@ -/* $Id: isamb.c,v 1.31 2004-06-01 13:46:41 adam Exp $ +/* $Id: isamb.c,v 1.37 2004-06-02 14:07:01 heikki Exp $ Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 Index Data Aps @@ -208,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; } @@ -323,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; @@ -1005,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 @@ -1065,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; } @@ -1090,12 +1149,12 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) * if cmp * return 1 */ - /* - * The upper nodes consist of a sequence of nodenumbers and keys - * When opening a block, the first node number is read in, and - * offset points to the first key, which is the upper limit of keys - * in the node just read. - */ + /* + * The upper nodes consist of a sequence of nodenumbers and keys + * When opening a block, the first node number is read in, and + * offset points to the first key, which is the upper limit of keys + * in the node just read. + */ char *dst = buf; char *src; struct ISAMB_block *p = pp->block[pp->level]; @@ -1103,6 +1162,7 @@ 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 @@ -1114,8 +1174,9 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) 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); @@ -1136,6 +1197,7 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) p->pos, p->offset); #endif assert(!p->leaf); + assert(p->offset <= p->size); /* skip the child we have handled */ if (p->offset != p->size) { @@ -1149,21 +1211,23 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) 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); #if ISAMB_DEBUG - logf(LOG_DEBUG,"isamb_pp_forward (B) on a high node. ofs=%d sz=%d nxtpos=%d ", + 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 @@ -1180,6 +1244,7 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) 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 ; @@ -1204,7 +1269,8 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) (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 @@ -1214,39 +1280,46 @@ int isamb_pp_forward (ISAMB_PP pp, void *buf, const void *untilbuf) } /* 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; + 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, ""); + logf(LOG_DEBUG,"isamb_pp_forward on a leaf. cmp=%d", + cmp); + (*pp->isamb->method->log_item)(LOG_DEBUG, buf, ""); #endif - if (cmp <2) - { -#if ISAMB_DEBUG - if (untilbuf) - { - (*pp->isamb->method->log_item)(LOG_DEBUG, buf, - "isamb_pp_forward returning 1"); - } - else + 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; - } - else - pp->skipped_numbers++; + pp->returned_numbers++; + return 1; + } + else + pp->skipped_numbers++; + } } /* leaf */ } /* main loop */ }