-static int save_both_pps (ISAMD_PP firstpp, ISAMD_PP pp)
-{
- /* order of things: Better to save firstpp first, if there are just two */
- /* blocks, but last if there are blocks in between, as these have already */
- /* been saved... optimise later (that's why this is in its own func...*/
- int retval = save_first_pp(firstpp);
- if (firstpp!=pp){
- save_last_pp(pp);
- isamd_pp_close(pp);
- }
- isamd_pp_close(firstpp);
- return retval;
-} /* save_both_pps */
-
-static ISAMD_PP read_diff_block(ISAMD_PP firstpp, int* p_diffidx)
-{ /* reads the diff block (if separate) and sets diffidx right */
- ISAMD_PP pp=firstpp;
- int diffidx;
- if (pp->diffs == 0)
- { /* no diffs yet, create room for them */
- if (separateDiffBlock(firstpp))
- { /* create a new block */
- pp=isamd_pp_open(pp->is,isamd_addr(0,firstpp->cat));
- pp->pos = isamd_alloc_block(pp->is, pp->cat);
- firstpp->diffs = pp->pos*2 +1;
- diffidx = pp->size = pp->offset = ISAMD_BLOCK_OFFSET_N;
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd_appd: alloc diff (d=%d) %d=%d:%d ix=%d",
- firstpp->diffs,
- isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos,
- diffidx);
- }
- else
- { /* prepare to append diffs in head */
- diffidx = pp->size;
- pp->diffs = diffidx *2 +0;
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd_appd: set up diffhead (d=%d) %d=%d:%d ix=%d",
- firstpp->diffs,
- isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos,
- diffidx);
- }
- } /* new */
- else
- { /* existing diffs */
- if (pp->diffs & 1)
- { /* diffs in a separate block, load it */
- pp=isamd_pp_open(pp->is, isamd_addr(firstpp->diffs/2,pp->cat));
- diffidx = pp->offset= pp->size;
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd_appd: loaded diff (d=%d) %d=%d:%d ix=%d",
- firstpp->diffs,
- isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos,
- diffidx);
- }
- else
- { /* diffs within the nead */
- diffidx= pp->diffs/2;
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd_appd: diffs in head d=%d %d=%d:%d ix=%d sz=%d",
- pp->diffs,
- isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos,
- diffidx, pp->size);
- }
- } /* diffs exist already */
- *p_diffidx = diffidx;
- return pp;
-} /* read_diff_block */
-
-
-
-
-/*******************************************************************
- * Building main blocks (no diffs)
- *******************************************************************/
-
-
-
-static ISAMD_PP get_new_main_block( ISAMD_PP firstpp, ISAMD_PP pp)
-{ /* allocates a new block for the main data, and links it in */
- int newblock;
- if (firstpp==pp)
- { /* special case: it was the first block. Save much later */
- if (0==firstpp->pos)
- { /* firstpp not allocated yet, do so now, */
- /* to keep blocks in order. Don't save yet, though */
- firstpp->pos = isamd_alloc_block(pp->is, firstpp->cat);
- }
- newblock = isamd_alloc_block(pp->is, firstpp->cat);
- firstpp->next = isamd_addr(newblock,firstpp->cat);
- /* keep the largest category */
- pp=isamd_pp_open(pp->is,isamd_addr(0,firstpp->cat));/*don't load*/
- pp->pos=newblock;
- pp->size = pp->offset = ISAMD_BLOCK_OFFSET_N;
- pp->next=0;
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd_build: Alloc2 f=%d (%d:%d) n=%d(%d:%d)",
- isamd_addr(firstpp->pos,firstpp->cat),
- firstpp->cat, firstpp->pos,
- isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos );
- }
- else
- { /* it was not the first block */
- newblock = isamd_alloc_block(pp->is, firstpp->cat);
- pp->next = isamd_addr(newblock,firstpp->cat);
- isamd_buildlaterblock(pp);
- isamd_write_block(pp->is,pp->cat,pp->pos,pp->buf);
- pp->size = pp->offset = ISAMD_BLOCK_OFFSET_N;
- pp->next=0;
- pp->cat = firstpp->cat;
- pp->pos = isamd_block(firstpp->next);
- }
- return pp;
-} /* get_new_main_block */
-
-
-static ISAMD_PP append_main_item(ISAMD_PP firstpp,
- ISAMD_PP pp,
- struct it_key *i_key,
- void *encoder_data)
-{ /* appends one item in the main data block, allocates new if needed */
- char *i_item= (char *) i_key; /* same as char */
- char *i_ptr=i_item;
- char codebuff[128];
- char *c_ptr = codebuff;
- int codelen;
- char hexbuff[64];
-
- int maxsize = pp->is->method->filecat[pp->is->max_cat].bsize;
-
- c_ptr=codebuff;
- i_ptr=i_item;
- (*pp->is->method->code_item)(ISAMD_ENCODE, encoder_data, &c_ptr, &i_ptr);
- codelen = c_ptr - codebuff;
- assert ( (codelen<128) && (codelen>0));
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd:build: coded into %s (nk=%d)",
- hexdump(codebuff, c_ptr-codebuff,hexbuff), firstpp->numKeys+1);
-
- if (pp->offset + codelen > maxsize )
- { /* oops, block full - get a new one */
- pp = get_new_main_block( firstpp, pp );
- /* reset encoging and code again */
- (*pp->is->method->code_reset)(encoder_data);
- c_ptr=codebuff;
- i_ptr=i_item;
- (*pp->is->method->code_item)(ISAMD_ENCODE, encoder_data, &c_ptr, &i_ptr);
- codelen = c_ptr - codebuff;
- assert ( (codelen<128) && (codelen>0));
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd:build: recoded into %s (nk=%d)",
- hexdump(codebuff, c_ptr-codebuff,hexbuff), firstpp->numKeys+1);
- } /* block full */
-
- /* write the data into pp, now we must have room */
- memcpy(&(pp->buf[pp->offset]),codebuff,codelen);
- pp->offset += codelen;
- pp->size += codelen;
- firstpp->numKeys++;
- return pp;
-} /* append_main_item */
-
-
-static int isamd_build_first_block(ISAMD is, ISAMD_I data)
-{
- struct it_key i_key; /* input key */
- char *i_item= (char *) &i_key; /* same as char */
- char *i_ptr=i_item;
- int i_more =1;
- int i_mode; /* 0 for delete, 1 for insert */
-
- ISAMD_PP firstpp;
- ISAMD_PP pp;
- void *encoder_data;
-
- char hexbuff[64];
-
- firstpp=pp=isamd_pp_open(is, isamd_addr(0,is->max_cat));
- firstpp->size = firstpp->offset = ISAMD_BLOCK_OFFSET_1;
- encoder_data=(*is->method->code_start)(ISAMD_ENCODE);
-
- if (is->method->debug >3)
- logf(LOG_LOG,"isamd_bld start: p=%d c=%d sz=%d maxsz=%d ",
- pp->pos, pp->cat, pp->size,
- pp->is->method->filecat[pp->is->max_cat].bsize);
-
- /* read first input */
- i_ptr = i_item;
- i_more = (*data->read_item)(data->clientData, &i_ptr, &i_mode);
- if (i_more)
- assert( i_ptr-i_item == sizeof(i_key) );
-
- if (pp->is->method->debug >3)
- logf(LOG_LOG,"isamd: build_fi start: m=%d %s",
- i_mode, hexdump(i_item,i_ptr-i_item,hexbuff) );
-
- while (i_more)
- {
- if (i_mode!=0)
- { /* ignore deletes here, should not happen */
- pp= append_main_item(firstpp, pp, &i_key, encoder_data);
- } /* not delete */
-
- /* (try to) read the next item */
- i_ptr = i_item;
- i_more = (*data->read_item)(data->clientData, &i_ptr, &i_mode);
-
- if ( (i_more) && (pp->is->method->debug >3) )
- logf(LOG_LOG,"isamd: build_fi start: m=%d %s",
- i_mode, hexdump(i_item,i_ptr-i_item,hexbuff) );
-
- } /* i_more */
-
- return save_both_pps( firstpp, pp );
-
-} /* build_first_block */
-
-