📄 isamd.c
字号:
memcpy (abuf + sizeof(int), &block, sizeof(int)); is->files[cat].head.freelist = pos; is->files[cat].head_is_dirty = 1; } else { memcpy (abuf + sizeof(int) + is->files[cat].alloc_entries_num*sizeof(int), &pos, sizeof(int)); } is->files[cat].alloc_entries_num++;}#elsestatic void flush_block (ISAMD is, int cat){ char *abuf = is->files[cat].alloc_buf; xfree (abuf);}static int alloc_block (ISAMD is, int cat){ int block; char buf[sizeof(int)]; is->files[cat].head_is_dirty = 1; (is->files[cat].no_allocated)++; if ((block = is->files[cat].head.freelist)) { bf_read (is->files[cat].bf, block, 0, sizeof(int), buf); memcpy (&is->files[cat].head.freelist, buf, sizeof(int)); } else block = (is->files[cat].head.lastblock)++; return block;}static void release_block (ISAMD is, int cat, int pos){ char buf[sizeof(int)]; (is->files[cat].no_released)++; is->files[cat].head_is_dirty = 1; memcpy (buf, &is->files[cat].head.freelist, sizeof(int)); is->files[cat].head.freelist = pos; bf_write (is->files[cat].bf, pos, 0, sizeof(int), buf);}#endifint isamd_alloc_block (ISAMD is, int cat){ int block = 0; if (is->files[cat].fc_list) { int j, nb; for (j = 0; j < is->files[cat].fc_max; j++) if ((nb = is->files[cat].fc_list[j]) && (!block || nb < block)) { is->files[cat].fc_list[j] = 0; block = nb; break; } } if (!block) block = alloc_block (is, cat); if (is->method->debug > 4) logf (LOG_LOG, "isamd: alloc_block in cat %d: %d", cat, block); return block;}void isamd_release_block (ISAMD is, int cat, int pos){ if (is->method->debug > 4) logf (LOG_LOG, "isamd: release_block in cat %d: %d", cat, pos); assert(pos!=0); if (is->files[cat].fc_list) { int j; for (j = 0; j<is->files[cat].fc_max; j++) if (!is->files[cat].fc_list[j]) { is->files[cat].fc_list[j] = pos; return; } } release_block (is, cat, pos);}static void init_fc (ISAMD is, int cat){ int j = 100; is->files[cat].fc_max = j; is->files[cat].fc_list = (int *) xmalloc (sizeof(*is->files[0].fc_list) * j); while (--j >= 0) is->files[cat].fc_list[j] = 0;}static void release_fc (ISAMD is, int cat){ int b, j = is->files[cat].fc_max; while (--j >= 0) if ((b = is->files[cat].fc_list[j])) { release_block (is, cat, b); is->files[cat].fc_list[j] = 0; }}void isamd_pp_close (ISAMD_PP pp){ ISAMD is = pp->is; (*is->method->code_stop)(ISAMD_DECODE, pp->decodeClientData); isamd_free_diffs(pp); /* see merge-d.h */ if (is->method->debug > 5) logf (LOG_LOG, "isamd_pp_close %p %d=%d:%d sz=%d n=%d=%d:%d nk=%d", pp, isamd_addr(pp->pos, pp->cat), pp->cat, pp->pos, pp->size, pp->next, isamd_type(pp->next), isamd_block(pp->next), pp->numKeys ); xfree (pp->buf); xfree (pp);}ISAMD_PP isamd_pp_create (ISAMD is, int cat)/* creates a pp_buff without data in it. pos=0, cat as given */{ ISAMD_PP pp = (ISAMD_PP) xmalloc (sizeof(*pp)); int sz = is->method->filecat[is->max_cat].bsize; pp->numKeys = 0; pp->buf = (char *) xmalloc (sz); memset(pp->buf,'\0',sz); /* clear the buffer, for new blocks */ pp->next = 0; pp->size = 0; pp->offset = 0; pp->is = is; pp->diffs=0; pp->diffbuf=0; pp->diffinfo=0; pp->decodeClientData = (*is->method->code_start)(ISAMD_DECODE); pp->cat = cat; pp->pos = 0; is->no_op_new++; return pp; }ISAMD_PP isamd_pp_open (ISAMD is, const char *dictbuf, int dictlen){ ISAMD_P ipos; ISAMD_PP pp = (ISAMD_PP) xmalloc (sizeof(*pp)); char *src; int sz = is->method->filecat[is->max_cat].bsize; /* always allocate for the largest blocks, saves trouble */ int dictnum; pp->numKeys = 0; src = pp->buf = (char *) xmalloc (sz); memset(src,'\0',sz); /* clear the buffer, for new blocks */ pp->next = 0; pp->size = 0; pp->offset = 0; pp->is = is; pp->diffs=0; pp->diffbuf=0; pp->diffinfo=0; pp->decodeClientData = (*is->method->code_start)(ISAMD_DECODE); dictnum=*dictbuf; /* numkeys for internals, 0 for externals */ if (0==dictnum) { memcpy(&ipos, dictbuf+1, sizeof(ISAMD_P) ); } else /* dictionary block, fake a real one */ { pp->cat=0; pp->pos=0; if (is->method->debug > 5) logf (LOG_LOG, "isamd_pp_open dict"); pp->numKeys=(unsigned char) dictbuf[0]; memcpy(pp->buf+ISAMD_BLOCK_OFFSET_1, dictbuf+1,dictlen-1); pp->size=pp->offset=dictlen+ISAMD_BLOCK_OFFSET_1-1; is->no_op_single++; return pp; } /* dict block */ pp->cat = isamd_type(ipos); pp->pos = isamd_block(ipos); if (0==pp->pos) is->no_op_new++; if (pp->pos) { src = pp->buf; isamd_read_block (is, pp->cat, pp->pos, src); memcpy (&pp->next, src, sizeof(pp->next)); src += sizeof(pp->next); memcpy (&pp->size, src, sizeof(pp->size)); src += sizeof(pp->size); memcpy (&pp->numKeys, src, sizeof(pp->numKeys)); src += sizeof(pp->numKeys); assert (pp->next != isamd_addr(pp->pos,pp->cat)); pp->offset = src - pp->buf; assert (pp->offset == ISAMD_BLOCK_OFFSET_1); assert(pp->size>=ISAMD_BLOCK_OFFSET_1); /*??*/ if (pp->next) is->files[pp->cat].no_op_main++; else is->files[pp->cat].no_op_diffonly++; } if (is->method->debug > 5) logf (LOG_LOG, "isamd_pp_open %p %d=%d:%d sz=%d n=%d=%d:%d", pp, isamd_addr(pp->pos, pp->cat), pp->cat, pp->pos, pp->size, pp->next, isamd_type(pp->next), isamd_block(pp->next) ); return pp;}void isamd_buildfirstblock(ISAMD_PP pp){ char *dst=pp->buf; assert(pp->buf); assert(pp->next != isamd_addr(pp->pos,pp->cat)); memcpy(dst, &pp->next, sizeof(pp->next) ); dst += sizeof(pp->next); memcpy(dst, &pp->size,sizeof(pp->size)); dst += sizeof(pp->size); memcpy(dst, &pp->numKeys, sizeof(pp->numKeys)); dst += sizeof(pp->numKeys); assert (dst - pp->buf == ISAMD_BLOCK_OFFSET_1); if (pp->is->method->debug > 5) logf (LOG_LOG, "isamd: bldfirst: p=%d=%d:%d n=%d:%d:%d sz=%d nk=%d ", isamd_addr(pp->pos,pp->cat),pp->cat, pp->pos, pp->next, isamd_type(pp->next), isamd_block(pp->next), pp->size, pp->numKeys);}void isamd_buildlaterblock(ISAMD_PP pp){ char *dst=pp->buf; assert(pp->buf); assert(pp->next != isamd_addr(pp->pos,pp->cat)); memcpy(dst, &pp->next, sizeof(pp->next) ); dst += sizeof(pp->next); memcpy(dst, &pp->size,sizeof(pp->size)); dst += sizeof(pp->size); assert (dst - pp->buf == ISAMD_BLOCK_OFFSET_N); if (pp->is->method->debug > 5) logf (LOG_LOG, "isamd: l8r: sz=%d p=%d/%d>%d/%d", pp->size, pp->pos, pp->cat, isamd_block(pp->next), isamd_type(pp->next) );}/* returns non-zero if item could be read; 0 otherwise */int isamd_pp_read (ISAMD_PP pp, void *buf){ return isamd_read_item (pp, (char **) &buf); /* note: isamd_read_item is in merge-d.c, because it is so */ /* convoluted with the merge process */}/* read one main item from file - decode and store it in *dst. Does not worry about diffs Returns 0 if end-of-file 1 if item could be read ok*/int isamd_read_main_item (ISAMD_PP pp, char **dst){ ISAMD is = pp->is; char *src = pp->buf + pp->offset; int newcat; int oldoffs; if (pp->offset >= pp->size) { if (!pp->next) { pp->pos = 0; return 0; /* end of file */ } if (pp->next > pp->pos) { if (pp->next == pp->pos + 1) is->files[pp->cat].no_next++; else { is->files[pp->cat].no_forward++; is->files[pp->cat].sum_forward += pp->next - pp->pos; } } else { if (pp->next + 1 == pp->pos) is->files[pp->cat].no_prev++; else { is->files[pp->cat].no_backward++; is->files[pp->cat].sum_backward += pp->pos - pp->next; } } /* out new block position */ newcat = isamd_type(pp->next); pp->pos = isamd_block(pp->next); pp->cat = isamd_type(pp->next); pp->is->no_read_main++; src = pp->buf; /* read block and save 'next' and 'size' entry */ isamd_read_block (is, pp->cat, pp->pos, src); memcpy (&pp->next, src, sizeof(pp->next)); src += sizeof(pp->next); memcpy (&pp->size, src, sizeof(pp->size)); src += sizeof(pp->size); /* assume block is non-empty */ pp->offset = oldoffs = src - pp->buf; assert (pp->offset == ISAMD_BLOCK_OFFSET_N); assert (pp->next != isamd_addr(pp->pos,pp->cat)); (*is->method->code_reset)(pp->decodeClientData); /* finally, read the item */ (*is->method->code_item)(ISAMD_DECODE, pp->decodeClientData, dst, &src); pp->offset = src - pp->buf; if (is->method->debug > 8) logf (LOG_LOG, "isamd: read_m: block %d:%d sz=%d ofs=%d-%d next=%d", pp->cat, pp->pos, pp->size, oldoffs, pp->offset, pp->next); return 2; } oldoffs=pp->offset; (*is->method->code_item)(ISAMD_DECODE, pp->decodeClientData, dst, &src); pp->offset = src - pp->buf; if (is->method->debug > 8) logf (LOG_LOG, "isamd: read_m: got %d:%d sz=%d ofs=%d-%d next=%d", pp->cat, pp->pos, pp->size, oldoffs, pp->offset, pp->next); return 1;}int isamd_pp_num (ISAMD_PP pp){ return pp->numKeys;}#if 0/* for testing .. */static char *hexdump(unsigned char *p, int len, char *buff) { static char localbuff[128]; char bytebuff[8]; if (!buff) buff=localbuff; *buff='\0'; while (len--) { sprintf(bytebuff,"%02x",*p); p++; strcat(buff,bytebuff); if (len) strcat(buff," "); } return buff;}#endif#ifdef SKIPTHIS /* needs different arguments, or something */void isamd_pp_dump (ISAMD is, ISAMD_P ipos){ ISAMD_PP pp; ISAMD_P oldaddr=0; struct it_key key; int i,n; int occur =0; int oldoffs; int diffmax=1; int diffidx; char hexbuff[64]; int olddebug= is->method->debug; is->method->debug=0; /* no debug logs while reading for dump */ logf(LOG_LOG,"dumping isamd block %d (%d:%d)", (int)ipos, isamd_type(ipos), isamd_block(ipos) ); pp=isamd_pp_open(is,ipos); logf(LOG_LOG,"numKeys=%d, ofs=%d sz=%d", pp->numKeys, pp->offset, pp->size ); diffidx=oldoffs= pp->offset; while ((diffidx < is->method->filecat[pp->cat].bsize) && (diffmax>0)) { memcpy(&diffmax,&(pp->buf[diffidx]),sizeof(int)); logf (LOG_LOG,"diff set at %d-%d: %s", diffidx, diffmax, hexdump(pp->buf+diffidx,8,0)); /*! todo: dump the actual diffs as well !!! */ diffidx=diffmax; } /* dump diffs */ while(isamd_pp_read(pp, &key)) { if (oldaddr != isamd_addr(pp->pos,pp->cat) ) { oldaddr = isamd_addr(pp->pos,pp->cat); logf(LOG_LOG,"block %d=%d:%d sz=%d nx=%d=%d:%d ofs=%d", isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos, pp->size, pp->next, isamd_type(pp->next), isamd_block(pp->next), pp->offset); i=0; while (i<pp->size) { n=pp->size-i; if (n>8) n=8; logf(LOG_LOG," %05x: %s",i,hexdump(pp->buf+i,n,hexbuff)); i+=n; } if (oldoffs > ISAMD_BLOCK_OFFSET_N) oldoffs=ISAMD_BLOCK_OFFSET_N; } /* new block */ occur++; logf (LOG_LOG," got %d:%d=%x:%x from %s at %d=%x", key.sysno, key.seqno, key.sysno, key.seqno, hexdump(pp->buf+oldoffs, pp->offset-oldoffs, hexbuff), oldoffs, oldoffs); oldoffs = pp->offset; } /*!*/ /*TODO: dump diffs too!!! */ isamd_pp_close(pp); is->method->debug=olddebug;} /* dump */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -