From df933f159390cf6f221af93740dcdc943fff6de2 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 29 Oct 1996 16:44:56 +0000 Subject: [PATCH] Work on isc_merge. --- isamc/isamc.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 165 insertions(+), 11 deletions(-) diff --git a/isamc/isamc.c b/isamc/isamc.c index 611f3fa..6dd1fd9 100644 --- a/isamc/isamc.c +++ b/isamc/isamc.c @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: isamc.c,v $ - * Revision 1.1 1996-10-29 13:40:48 adam + * Revision 1.2 1996-10-29 16:44:56 adam + * Work on isc_merge. + * + * Revision 1.1 1996/10/29 13:40:48 adam * First work. * */ @@ -113,12 +116,6 @@ int isc_close (ISAMC is) return 0; } -void isc_catpos (ISAMC_P ipos, int *cat, int *pos) -{ - *pos = ipos >> 3; - *cat = ipos & 7; -} - int isc_read_block (ISAMC is, int cat, int pos, char *dst) { if (is->method->debug > 1) @@ -290,8 +287,164 @@ ISAMC_P isc_merge_first (ISAMC is, ISAMC_I data) ISAMC_P isc_merge (ISAMC is, ISAMC_P ipos, ISAMC_I data) { - assert (ipos == 0); - return isc_merge_first (is, data); + char i_item[128], *i_item_ptr; + int i_more, i_mode, i; + + ISAMC_PP pp; + char f_item[128], *f_item_ptr; + int f_more; + int block_ptr[100]; /* block pointer (0 if none) */ + int dirty_ptr[100]; /* dirty flag pointer (1 if dirty) */ + + int firstpos = 0; + int nextpos = 0; + int cat = 0; + char r_item_buf[128]; /* temporary result output */ + char *r_buf; /* block with resulting data */ + int r_offset = 0; /* current offset in r_buf */ + int r_ptr[100]; /* offset pointer */ + int r_ptri = 0; /* pointer */ + void *r_clientData; /* encode client data */ + + if (ipos == 0) + return isc_merge_first (is, data); + + r_clientData = (*is->method->code_start)(ISAMC_ENCODE); + r_buf = is->r_buf + ISAMC_BLOCK_OFFSET; + + pp = isc_pp_open (is, ipos); + f_item_ptr = f_item; + f_more = isc_read_item (pp, &f_item_ptr); + cat = pp->cat; + + /* read first item from i */ + i_item_ptr = i_item; + i_more = (*data->read_item)(data->clientData, &i_item_ptr, &i_mode); + block_ptr[r_ptri] = pp->pos; + dirty_ptr[r_ptri] = 0; + r_ptr[r_ptri++] = 0; + + while (i_more || f_more) + { + char *r_item = r_item_buf; + int cmp; + + if (!f_more) + cmp = -1; + else if (!i_more) + cmp = 1; + else + cmp = (*is->method->compare_item)(i_item, f_item); + if (cmp == 0) /* insert i=f */ + { + if (!i_mode) + { + r_item = NULL; + dirty_ptr[r_ptri-1] = 1; + } + else + memcpy (r_item, f_item, f_item_ptr - f_item); + + /* move i */ + i_item_ptr = i_item; + i_more = (*data->read_item)(data->clientData, &i_item_ptr, + &i_mode); + /* move f */ + f_item_ptr = f_item; + f_more = isc_read_item (pp, &f_item_ptr); + } + else if (cmp > 0) /* insert f */ + { + memcpy (r_item, f_item, f_item_ptr - f_item); + /* move f */ + f_item_ptr = f_item; + f_more = isc_read_item (pp, &f_item_ptr); + } + else /* insert i */ + { + if (!i_mode) /* delete item which isn't there? */ + { + logf (LOG_FATAL, "Inconsistent register"); + abort (); + } + memcpy (r_item, i_item, i_item_ptr - i_item); + dirty_ptr[r_ptri-1] = 1; + /* move i */ + i_item_ptr = i_item; + i_more = (*data->read_item)(data->clientData, &i_item_ptr, + &i_mode); + } + if (r_item) /* insert resulting item? */ + { + char *r_out_ptr = r_buf + r_offset; + int new_offset; + int border; + + /* border set to initial fill or block size depending on + whether we are creating a new one or updating and old + */ + if (block_ptr[r_ptri-1]) + border = r_ptr[r_ptri-1] + is->method->filecat[cat].bsize + -ISAMC_BLOCK_OFFSET; + else + border = r_ptr[r_ptri-1] + is->method->filecat[cat].ifill + -ISAMC_BLOCK_OFFSET; + + (*is->method->code_item)(ISAMC_ENCODE, r_clientData, + &r_out_ptr, &r_item); + new_offset = r_out_ptr - r_buf; + + if (border >= r_offset && border < new_offset) + { + /* Initial fill of current block category reached... + Save offset in r_ptr + */ + r_ptr[r_ptri++] = r_offset; + if (cat == is->max_cat) + { + /* We are dealing with block of max size. Block(s) + will be flushed. Note: the block(s) are surely not + the last one(s). + */ + if (is->method->debug > 1) + logf (LOG_LOG, "isc: flush %d sections", r_ptri-1); + isc_flush_blocks (is, r_ptr, r_ptri, r_buf, + &nextpos, &firstpos, cat, 0); + r_ptri = 0; + r_ptr[r_ptri++] = 0; + memcpy (r_buf, r_buf + r_offset, new_offset - r_offset); + new_offset = (new_offset - r_offset); + } + } + r_offset = new_offset; + if (cat < is->max_cat && + r_ptri>is->method->filecat[cat].mblocks) + { + /* Max number blocks in current category reached -> + must switch to next category (with larger block size) + */ + int j = 1; + cat++; + /* r_ptr[0] = r_ptr[0] = 0 true anyway.. */ + /* AD: Any old blocks should be deleted */ + for (i = 2; i < r_ptri; i++) + { + border = is->method->filecat[cat].ifill - + ISAMC_BLOCK_OFFSET + r_ptr[j-1]; + if (r_ptr[i] > border && r_ptr[i-1] <= border) + r_ptr[j++] = r_ptr[i-1]; + } + r_ptri = j; + } + } + } + r_ptr[r_ptri++] = r_offset; + /* flush rest of block(s) in r_buf */ + if (is->method->debug > 1) + logf (LOG_LOG, "isc: flush rest, %d sections", r_ptri-1); + isc_flush_blocks (is, r_ptr, r_ptri, r_buf, &nextpos, &firstpos, cat, 1); + (*is->method->code_stop)(ISAMC_ENCODE, r_clientData); + return cat + firstpos * 8; } @@ -434,8 +587,9 @@ ISAMC_PP isc_pp_open (ISAMC is, ISAMC_P ipos) { ISAMC_PP pp = xmalloc (sizeof(*pp)); char *src; - - isc_catpos (ipos, &pp->cat, &pp->next); + + pp->cat = isc_type(ipos); + pp->next = isc_block(ipos); src = pp->buf = xmalloc (is->method->filecat[pp->cat].bsize); -- 1.7.10.4