X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=isam%2Fphysical.c;h=9dccb47b6ee0a01c5dc6243ca46a6adea855a335;hb=e39158d4c6147865c129d2524f1b910e4e7921ed;hp=3ea43b9f547fe4f118c8612f42c5714e398c635d;hpb=8fa8b7c5d10dd87654e5c219cceebe1a9664544a;p=idzebra-moved-to-github.git diff --git a/isam/physical.c b/isam/physical.c index 3ea43b9..9dccb47 100644 --- a/isam/physical.c +++ b/isam/physical.c @@ -4,7 +4,22 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: physical.c,v $ - * Revision 1.2 1994-09-26 17:06:36 quinn + * Revision 1.7 1995-12-06 14:48:27 quinn + * Fixed some strange bugs. + * + * Revision 1.6 1995/09/04 12:33:47 adam + * Various cleanup. YAZ util used instead. + * + * Revision 1.5 1994/09/28 11:29:33 quinn + * Added cmp parameter. + * + * Revision 1.4 1994/09/27 20:03:53 quinn + * Seems relatively bug-free. + * + * Revision 1.3 1994/09/26 17:11:31 quinn + * Trivial + * + * Revision 1.2 1994/09/26 17:06:36 quinn * Back again... * * Revision 1.1 1994/09/26 16:07:57 quinn @@ -17,9 +32,9 @@ */ #include +#include #include -#include static int is_freestore_alloc(ISAM is, int type) { @@ -31,13 +46,14 @@ static int is_freestore_alloc(ISAM is, int type) if (bf_read(is->types[type].bf, tmp, 0, sizeof(tmp), &is->types[type].freelist) <=0) { - log(LOG_FATAL, "Failed to allocate block"); + logf (LOG_FATAL, "Failed to allocate block"); exit(1); } } else tmp = is->types[type].top++; + logf (LOG_DEBUG, "Allocating block #%d", tmp); return tmp; } @@ -45,11 +61,12 @@ static void is_freestore_free(ISAM is, int type, int block) { int tmp; + logf (LOG_DEBUG, "Releasing block #%d", block); tmp = is->types[type].freelist; is->types[type].freelist = block; if (bf_write(is->types[type].bf, block, 0, sizeof(tmp), &tmp) < 0) { - log(LOG_FATAL, "Failed to deallocate block."); + logf (LOG_FATAL, "Failed to deallocate block."); exit(1); } } @@ -73,7 +90,7 @@ int is_p_read_partial(is_mtable *tab, is_mblock *block) if (bf_read(tab->is->types[tab->pos_type].bf, block->diskpos, 0, toread, buf->data) < 0) { - log(LOG_FATAL, "bfread failed."); + logf (LOG_FATAL, "bfread failed."); return -1; } /* extract header info */ @@ -107,7 +124,7 @@ int is_p_read_full(is_mtable *tab, is_mblock *block) if (block->state == IS_MBSTATE_UNREAD && is_p_read_partial(tab, block) < 0) { - log(LOG_FATAL, "partial read failed."); + logf (LOG_FATAL, "partial read failed."); return -1; } if (block->state == IS_MBSTATE_PARTIAL) @@ -126,7 +143,7 @@ int is_p_read_full(is_mtable *tab, is_mblock *block) if (bf_read(tab->is->types[tab->pos_type].bf, block->diskpos, block->bread, toread * is_keysize(tab->is), buf->data) < 0) { - log(LOG_FATAL, "bfread failed."); + logf (LOG_FATAL, "bfread failed."); return -1; } buf->offset = 0; @@ -134,7 +151,9 @@ int is_p_read_full(is_mtable *tab, is_mblock *block) dread += toread; block->bread += toread * is_keysize(tab->is); } + block->state = IS_MBSTATE_CLEAN; } + logf (LOG_DEBUG, "R: Block #%d contains %d records.", block->diskpos, block->num_records); return 0; } @@ -152,6 +171,8 @@ void is_p_sync(is_mtable *tab) type = &tab->is->types[tab->pos_type]; for (p = tab->data; p; p = p->next) { + if (p->state < IS_MBSTATE_DIRTY) + continue; /* make sure that blocks are allocated. */ if (p->diskpos < 0) p->diskpos = is_freestore_alloc(tab->is, tab->pos_type); @@ -163,6 +184,8 @@ void is_p_sync(is_mtable *tab) else p->nextpos = p->next->diskpos; } + else + p->nextpos = 0; sum = 0; memcpy(type->dbuf, &p->num_records, sizeof(p->num_records)); sum += sizeof(p->num_records); @@ -183,9 +206,10 @@ void is_p_sync(is_mtable *tab) } if (bf_write(type->bf, p->diskpos, 0, sum, type->dbuf) < 0) { - log(LOG_FATAL, "Failed to write block."); + logf (LOG_FATAL, "Failed to write block."); exit(1); } + logf (LOG_DEBUG, "W: Block #%d contains %d records.", p->diskpos, p->num_records); } } @@ -209,6 +233,8 @@ static is_mbuf *mbuf_takehead(is_mbuf **mb, int *num, int keysize) is_mbuf *p = 0, **pp = &p, *new; int toget = *num; + if (!toget) + return 0; while (*mb && toget >= (*mb)->num) { toget -= (*mb)->num; @@ -243,14 +269,33 @@ static is_mbuf *mbuf_takehead(is_mbuf **mb, int *num, int keysize) */ void is_p_align(is_mtable *tab) { - is_mblock *mblock, *new; + is_mblock *mblock, *new, *last = 0, *next; is_mbuf *mbufs, *mbp; int blocks, recsblock; - log(LOG_DEBUG, "Realigning table."); - for (mblock = tab->data; mblock; mblock = mblock->next) + logf (LOG_DEBUG, "Realigning table."); + for (mblock = tab->data; mblock; mblock = next) { - if (mblock->state == IS_MBSTATE_DIRTY && mblock->num_records > + next = mblock->next; + if (mblock->state == IS_MBSTATE_DIRTY && mblock->num_records == 0) + { + if (last) + { + last->next = mblock->next; + last->state = IS_MBSTATE_DIRTY; + next = mblock->next; + } + else + { + tab->data = tab->data->next; + tab->data->state = IS_MBSTATE_DIRTY; + next = tab->data; + } + if (mblock->diskpos >= 0) + is_freestore_free(tab->is, tab->pos_type, mblock->diskpos); + xrelease_mblock(mblock); + } + else if (mblock->state == IS_MBSTATE_DIRTY && mblock->num_records > (mblock == tab->data ? tab->is->types[tab->pos_type].max_keys_block0 : tab->is->types[tab->pos_type].max_keys_block)) @@ -265,18 +310,25 @@ void is_p_align(is_mtable *tab) recsblock = 1; mbufs = mblock->data; while ((mbp = mbuf_takehead(&mbufs, &recsblock, - is_keysize(tab->is)))) + is_keysize(tab->is))) && recsblock) { - new = xmalloc_mblock(); - new->diskpos = -1; - new->state = IS_MBSTATE_DIRTY; - new->next = mblock->next; - mblock->next = new; + if (mbufs) + { + new = xmalloc_mblock(); + new->diskpos = -1; + new->state = IS_MBSTATE_DIRTY; + new->next = mblock->next; + mblock->next = new; + } mblock->data = mbp; mblock->num_records = recsblock; + last = mblock; mblock = mblock->next; } + next = mblock; } + else + last = mblock; } } @@ -292,11 +344,16 @@ void is_p_remap(is_mtable *tab) is_mblock *blockp, **blockpp; int recsblock, blocks; - log(LOG_DEBUG, "Remapping table."); + logf (LOG_DEBUG, "Remapping table."); /* collect all data */ bufpp = &mbufs; for (blockp = tab->data; blockp; blockp = blockp->next) { + if (blockp->state < IS_MBSTATE_CLEAN && is_m_read_full(tab, blockp) < 0) + { + logf (LOG_FATAL, "Read-full failed in remap."); + exit(1); + } *bufpp = blockp->data; while (*bufpp) bufpp = &(*bufpp)->next; @@ -305,11 +362,14 @@ void is_p_remap(is_mtable *tab) blocks = tab->num_records / tab->is->types[tab->pos_type].nice_keys_block; if (tab->num_records % tab->is->types[tab->pos_type].nice_keys_block) blocks++; - recsblock = tab->num_records / blocks; - if (recsblock < 1) - recsblock = 1; + if (blocks == 0) + blocks = 1; + recsblock = tab->num_records / blocks + 1; + if (recsblock > tab->is->types[tab->pos_type].nice_keys_block) + recsblock--; blockpp = &tab->data; - while ((mbp = mbuf_takehead(&mbufs, &recsblock, is_keysize(tab->is)))) + while ((mbp = mbuf_takehead(&mbufs, &recsblock, is_keysize(tab->is))) && + recsblock) { if (!*blockpp) { @@ -321,4 +381,14 @@ void is_p_remap(is_mtable *tab) (*blockpp)->state = IS_MBSTATE_DIRTY; blockpp = &(*blockpp)->next; } + if (mbp) + xfree_mbufs(mbp); + if (*blockpp) + { + for (blockp = *blockpp; blockp; blockp = blockp->next) + if (blockp->diskpos >= 0) + is_freestore_free(tab->is, tab->pos_type, blockp->diskpos); + xfree_mblocks(*blockpp); + *blockpp = 0; + } }