X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=isamb%2Fisamb.c;h=460b8ad7eb25dbd04862b483e1f9c238b612124e;hb=dbf15c09e6ad1986b914c695c161f81f774e9f39;hp=4fa613a79d0dbaade6b784bb3f8f6f3eeeeacab5;hpb=26a5a4b96b90361859cf856d6c41852b03ca2f84;p=idzebra-moved-to-github.git diff --git a/isamb/isamb.c b/isamb/isamb.c index 4fa613a..460b8ad 100644 --- a/isamb/isamb.c +++ b/isamb/isamb.c @@ -1,5 +1,5 @@ -/* $Id: isamb.c,v 1.22 2003-02-04 12:06:47 pop Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 +/* $Id: isamb.c,v 1.24 2003-03-17 20:22:54 adam Exp $ + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 Index Data Aps This file is part of the Zebra server. @@ -45,7 +45,7 @@ struct ISAMB_head { struct ISAMB_cache_entry { ISAMB_P pos; - char *buf; + unsigned char *buf; int dirty; int hits; struct ISAMB_cache_entry *next; @@ -118,6 +118,7 @@ ISAMB isamb_open (BFiles bfs, const char *name, int writeflag, ISAMC_M method, isamb->log_io = 0; isamb->cache = cache; + assert (cache == 0); isamb->file = xmalloc (sizeof(*isamb->file) * isamb->no_cat); for (i = 0; ino_cat; i++) { @@ -249,6 +250,7 @@ void isamb_close (ISAMB isamb) bf_write (isamb->file[i].bf, 0, 0, sizeof(struct ISAMB_head), &isamb->file[i].head); + bf_close (isamb->file[i].bf); } xfree (isamb->file); xfree (isamb->method); @@ -279,7 +281,12 @@ struct ISAMB_block *open_block (ISAMB b, ISAMC_P pos) } p->bytes = p->buf + ISAMB_DATA_OFFSET; p->leaf = p->buf[0]; - p->size = p->buf[1] + 256 * p->buf[2] - ISAMB_DATA_OFFSET; + p->size = (p->buf[1] + 256 * p->buf[2]) - ISAMB_DATA_OFFSET; + if (p->size < 0) + { + fprintf (stderr, "pos=%d\n", pos); + } + assert (p->size >= 0); p->offset = 0; p->dirty = 0; p->deleted = 0; @@ -303,6 +310,7 @@ struct ISAMB_block *new_block (ISAMB b, int leaf, int cat) else { p->pos = b->file[cat].head.free_list; + assert((p->pos & 3) == cat); if (!get_block (b, p->pos, p->buf, 0)) { yaz_log (b->log_io, "bf_read: new_block"); @@ -341,6 +349,34 @@ struct ISAMB_block *new_int (ISAMB b, int cat) return new_block (b, 0, cat); } +static void check_block (ISAMB b, struct ISAMB_block *p) +{ + if (p->leaf) + { + ; + } + else + { + /* sanity check */ + char *startp = p->bytes; + char *src = startp; + char *endp = p->bytes + p->size; + int pos; + + decode_ptr (&src, &pos); + assert ((pos&3) == p->cat); + while (src != endp) + { + int item_len; + decode_ptr (&src, &item_len); + assert (item_len > 0 && item_len < 30); + src += item_len; + decode_ptr (&src, &pos); + assert ((pos&3) == p->cat); + } + } +} + void close_block (ISAMB b, struct ISAMB_block *p) { if (!p) @@ -353,16 +389,18 @@ void close_block (ISAMB b, struct ISAMB_block *p) b->file[p->cat].head.free_list = p->pos; if (!get_block (b, p->pos, p->buf, 1)) { - yaz_log (b->log_io, "bf_write: close_block"); + yaz_log (b->log_io, "bf_write: close_block (deleted)"); bf_write (b->file[p->cat].bf, p->pos/4, 0, 0, p->buf); } } else if (p->dirty) { int size = p->size + ISAMB_DATA_OFFSET; + assert (p->size >= 0); p->buf[0] = p->leaf; p->buf[1] = size & 255; p->buf[2] = size >> 8; + check_block(b, p); if (!get_block (b, p->pos, p->buf, 1)) { yaz_log (b->log_io, "bf_write: close_block"); @@ -397,11 +435,13 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item, *sp = 0; + assert(p->size >= 0); decode_ptr (&src, &pos); while (src != endp) { int item_len; int d; + char *src0 = src; decode_ptr (&src, &item_len); d = (*b->method->compare_item)(src, lookahead_item); if (d > 0) @@ -411,6 +451,7 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item, more = insert_sub (b, &sub_p1, lookahead_item, mode, stream, &sub_p2, sub_item, &sub_size, src); + src = src0; break; } src += item_len; @@ -447,6 +488,7 @@ int insert_int (ISAMB b, struct ISAMB_block *p, void *lookahead_item, dst += endp - src; } p->size = dst - dst_buf; + assert (p->size >= 0); if (p->size <= b->file[p->cat].head.block_max) { memcpy (startp, dst_buf, dst - dst_buf);