⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isamb.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
        assert (p->size >= 0);        if (p->size <= b->file[p->cat].head.block_max)        {            memcpy (startp, dst_buf, dst - dst_buf);        }        else        {            int p_new_size;            char *half;            src = dst_buf;            endp = dst;            half = src + b->file[p->cat].head.block_size/2;            decode_ptr (&src, &pos);            while (src <= half)            {                decode_ptr (&src, split_size);                src += *split_size;                decode_ptr (&src, &pos);            }            p_new_size = src - dst_buf;            memcpy (p->bytes, dst_buf, p_new_size);            decode_ptr (&src, split_size);            memcpy (split_item, src, *split_size);            src += *split_size;            *sp = new_int (b, p->cat);            (*sp)->size = endp - src;            memcpy ((*sp)->bytes, src, (*sp)->size);            p->size = p_new_size;        }        p->dirty = 1;        close_block (b, sub_p2);    }    close_block (b, sub_p1);    return more;}int insert_leaf (ISAMB b, struct ISAMB_block **sp1, void *lookahead_item,                 int *lookahead_mode, ISAMC_I *stream,		 struct ISAMB_block **sp2,                 void *sub_item, int *sub_size,                 void *max_item){    struct ISAMB_block *p = *sp1;    char *src = 0, *endp = 0;    char dst_buf[DST_BUF_SIZE], *dst = dst_buf;    int new_size;    void *c1 = (*b->method->code_start)(ISAMC_DECODE);    void *c2 = (*b->method->code_start)(ISAMC_ENCODE);    int more = 1;    int quater = b->file[b->no_cat-1].head.block_max / 4;    char *cut = dst_buf + quater * 2;    char *maxp = dst_buf + b->file[b->no_cat-1].head.block_max;    char *half1 = 0;    char *half2 = 0;    char cut_item_buf[DST_ITEM_MAX];    int cut_item_size = 0;    if (p && p->size)    {        char file_item_buf[DST_ITEM_MAX];        char *file_item = file_item_buf;                    src = p->bytes;        endp = p->bytes + p->size;        (*b->method->code_item)(ISAMC_DECODE, c1, &file_item, &src);        while (1)        {            char *dst_item = 0;            char *dst_0 = dst;            char *lookahead_next;            int d = -1;                        if (lookahead_item)                d = (*b->method->compare_item)(file_item_buf, lookahead_item);                        if (d > 0)            {                dst_item = lookahead_item;                if (!*lookahead_mode)                {                    yaz_log (LOG_WARN, "isamb: Inconsistent register (1)");                    assert (*lookahead_mode);                }            }            else                dst_item = file_item_buf;            if (!*lookahead_mode && d == 0)            {                p->dirty = 1;            }            else if (!half1 && dst > cut)            {                char *dst_item_0 = dst_item;                half1 = dst; /* candidate for splitting */                                (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &dst_item);                                cut_item_size = dst_item - dst_item_0;                memcpy (cut_item_buf, dst_item_0, cut_item_size);                                half2 = dst;            }            else                (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &dst_item);            if (d > 0)              {                if (dst > maxp)                {                    dst = dst_0;                    lookahead_item = 0;                }                else                {                    lookahead_next = lookahead_item;                    if (!(*stream->read_item)(stream->clientData,                                              &lookahead_next,                                              lookahead_mode))                    {                        lookahead_item = 0;                        more = 0;                    }                    if (lookahead_item && max_item &&                        (*b->method->compare_item)(max_item, lookahead_item) <= 0)                    {                        /* max_item 1 */                        lookahead_item = 0;                    }                                        p->dirty = 1;                }            }            else if (d == 0)            {                lookahead_next = lookahead_item;                if (!(*stream->read_item)(stream->clientData,                                          &lookahead_next, lookahead_mode))                {                    lookahead_item = 0;                    more = 0;                }                if (src == endp)                    break;                file_item = file_item_buf;                (*b->method->code_item)(ISAMC_DECODE, c1, &file_item, &src);            }            else            {                if (src == endp)                    break;                file_item = file_item_buf;                (*b->method->code_item)(ISAMC_DECODE, c1, &file_item, &src);            }        }    }    maxp = dst_buf + b->file[b->no_cat-1].head.block_max + quater;    while (lookahead_item)    {        char *dst_item = lookahead_item;        char *dst_0 = dst;                if (max_item &&            (*b->method->compare_item)(max_item, lookahead_item) <= 0)        {            /* max_item 2 */            break;        }        if (!*lookahead_mode)        {            yaz_log (LOG_WARN, "isamb: Inconsistent register (2)");            abort();        }        else if (!half1 && dst > cut)           {            char *dst_item_0 = dst_item;            half1 = dst; /* candidate for splitting */                        (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &dst_item);                        cut_item_size = dst_item - dst_item_0;            memcpy (cut_item_buf, dst_item_0, cut_item_size);                        half2 = dst;        }        else            (*b->method->code_item)(ISAMC_ENCODE, c2, &dst, &dst_item);        if (dst > maxp)        {            dst = dst_0;            break;        }        if (p)            p->dirty = 1;        dst_item = lookahead_item;        if (!(*stream->read_item)(stream->clientData, &dst_item,                                  lookahead_mode))        {            lookahead_item = 0;            more = 0;        }    }    new_size = dst - dst_buf;    if (p && p->cat != b->no_cat-1 &&         new_size > b->file[p->cat].head.block_max)    {        /* non-btree block will be removed */        p->deleted = 1;        close_block (b, p);        /* delete it too!! */        p = 0; /* make a new one anyway */    }    if (!p)    {   /* must create a new one */        int i;        for (i = 0; i < b->no_cat; i++)            if (new_size <= b->file[i].head.block_max)                break;        if (i == b->no_cat)            i = b->no_cat - 1;        p = new_leaf (b, i);    }    if (new_size > b->file[p->cat].head.block_max)    {        char *first_dst;        char *cut_item = cut_item_buf;        assert (half1);        assert (half2);       /* first half */        p->size = half1 - dst_buf;        memcpy (p->bytes, dst_buf, half1 - dst_buf);        /* second half */        *sp2 = new_leaf (b, p->cat);        (*b->method->code_reset)(c2);        first_dst = (*sp2)->bytes;        (*b->method->code_item)(ISAMC_ENCODE, c2, &first_dst, &cut_item);        memcpy (first_dst, half2, dst - half2);        (*sp2)->size = (first_dst - (*sp2)->bytes) + (dst - half2);        (*sp2)->dirty = 1;        p->dirty = 1;        memcpy (sub_item, cut_item_buf, cut_item_size);        *sub_size = cut_item_size;    }    else    {        memcpy (p->bytes, dst_buf, dst - dst_buf);        p->size = new_size;    }    (*b->method->code_stop)(ISAMC_DECODE, c1);    (*b->method->code_stop)(ISAMC_ENCODE, c2);    *sp1 = p;    return more;}int insert_sub (ISAMB b, struct ISAMB_block **p, void *new_item,                int *mode,                ISAMC_I *stream,                struct ISAMB_block **sp,                void *sub_item, int *sub_size,                void *max_item){    if (!*p || (*p)->leaf)        return insert_leaf (b, p, new_item, mode, stream, sp, sub_item,                             sub_size, max_item);    else        return insert_int (b, *p, new_item, mode, stream, sp, sub_item,                           sub_size, max_item);}int isamb_unlink (ISAMB b, ISAMC_P pos){    struct ISAMB_block *p1;    if (!pos)	return 0;    p1 = open_block(b, pos);    p1->deleted = 1;    if (!p1->leaf)    {	int sub_p;	int item_len;	char *src = p1->bytes + p1->offset;	decode_ptr(&src, &sub_p);	isamb_unlink(b, sub_p);		while (src != p1->bytes + p1->size)	{	    decode_ptr(&src, &item_len);	    src += item_len;	    decode_ptr(&src, &sub_p);	    isamb_unlink(b, sub_p);	}    }    close_block(b, p1);    return 0;}int isamb_merge (ISAMB b, ISAMC_P pos, ISAMC_I *stream){    char item_buf[DST_ITEM_MAX];    char *item_ptr;    int i_mode;    int more;    if (b->cache < 0)    {        int more = 1;        while (more)        {            item_ptr = item_buf;            more =                (*stream->read_item)(stream->clientData, &item_ptr, &i_mode);        }        return 1;    }    item_ptr = item_buf;    more = (*stream->read_item)(stream->clientData, &item_ptr, &i_mode);    while (more)    {        struct ISAMB_block *p = 0, *sp = 0;        char sub_item[DST_ITEM_MAX];        int sub_size;                if (pos)            p = open_block (b, pos);        more = insert_sub (b, &p, item_buf, &i_mode, stream, &sp,                            sub_item, &sub_size, 0);        if (sp)        {    /* increase level of tree by one */            struct ISAMB_block *p2 = new_int (b, p->cat);            char *dst = p2->bytes + p2->size;                        encode_ptr (&dst, p->pos);            assert (sub_size < 20);            encode_ptr (&dst, sub_size);            memcpy (dst, sub_item, sub_size);            dst += sub_size;            encode_ptr (&dst, sp->pos);                        p2->size = dst - p2->bytes;            pos = p2->pos;  /* return new super page */            close_block (b, sp);            close_block (b, p2);        }        else            pos = p->pos;   /* return current one (again) */        close_block (b, p);    }    return pos;}ISAMB_PP isamb_pp_open_x (ISAMB isamb, ISAMB_P pos, int *level){    ISAMB_PP pp = xmalloc (sizeof(*pp));    pp->isamb = isamb;    pp->block = xmalloc (10 * sizeof(*pp->block));    pp->pos = pos;    pp->level = 0;    pp->total_size = 0;    pp->no_blocks = 0;    while (1)    {        struct ISAMB_block *p = open_block (isamb, pos);        char *src = p->bytes + p->offset;        pp->block[pp->level] = p;        pp->total_size += p->size;        pp->no_blocks++;        if (p->leaf)            break;        decode_ptr (&src, &pos);        p->offset = src - p->bytes;        pp->level++;    }    pp->block[pp->level+1] = 0;    if (level)        *level = pp->level;    return pp;}ISAMB_PP isamb_pp_open (ISAMB isamb, ISAMB_P pos){    return isamb_pp_open_x (isamb, pos, 0);}void isamb_pp_close_x (ISAMB_PP pp, int *size, int *blocks){    int i;    if (!pp)        return;    if (size)        *size = pp->total_size;    if (blocks)        *blocks = pp->no_blocks;    for (i = 0; i <= pp->level; i++)        close_block (pp->isamb, pp->block[i]);    xfree (pp->block);    xfree (pp);}int isamb_block_info (ISAMB isamb, int cat){    if (cat >= 0 && cat < isamb->no_cat)        return isamb->file[cat].head.block_size;    return -1;}void isamb_pp_close (ISAMB_PP pp){    isamb_pp_close_x (pp, 0, 0);}int isamb_pp_read (ISAMB_PP pp, void *buf){    char *dst = buf;    char *src;    struct ISAMB_block *p = pp->block[pp->level];    if (!p)        return 0;    while (p->offset == p->size)    {        int pos, item_len;        while (p->offset == p->size)        {            if (pp->level == 0)                return 0;            close_block (pp->isamb, pp->block[pp->level]);            pp->block[pp->level] = 0;            (pp->level)--;            p = pp->block[pp->level];            assert (!p->leaf);  /* must be int */        }        src = p->bytes + p->offset;                decode_ptr (&src, &item_len);        src += item_len;        decode_ptr (&src, &pos);                p->offset = src - (char*) p->bytes;        ++(pp->level);                while (1)        {            pp->block[pp->level] = p = open_block (pp->isamb, pos);            pp->total_size += p->size;            pp->no_blocks++;                        if (p->leaf) /* leaf */            {                break;            }            src = p->bytes + p->offset;            decode_ptr (&src, &pos);            p->offset = src - (char*) p->bytes;            pp->level++;        }    }    assert (p->offset < p->size);    assert (p->leaf);    src = p->bytes + p->offset;    (*pp->isamb->method->code_item)(ISAMC_DECODE, p->decodeClientData,                                    &dst, &src);    p->offset = src - (char*) p->bytes;    return 1;}int isamb_pp_num (ISAMB_PP pp){    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -