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

📄 blob.c

📁 About: hamsterdb is a database engine written in ANSI C. It supports a B+Tree index structure, uses
💻 C
📖 第 1 页 / 共 2 页
字号:
        }    }    else        blob_set_alloc_size(&hdr, alloc_size);    blob_set_real_size(&hdr, sizeof(blob_t)+size);    blob_set_user_size(&hdr, size);    blob_set_self(&hdr, addr);    /*      * write header and data      */    chunk_data[0]=(ham_u8_t *)&hdr;    chunk_size[0]=sizeof(hdr);    chunk_data[1]=(ham_u8_t *)data;    chunk_size[1]=size;    st=my_write_chunks(db, page, addr, chunk_data, chunk_size, 2);    if (st)        return (st);    *blobid=addr;    return (0);}ham_status_tblob_read(ham_db_t *db, ham_offset_t blobid,         ham_record_t *record, ham_u32_t flags){    ham_status_t st;    blob_t hdr;    record->size=0;    /*     * in-memory-database: the blobid is actually a pointer to the memory     * buffer, in which the blob is stored     */    if (db_get_rt_flags(db)&HAM_IN_MEMORY_DB) {        blob_t *hdr=(blob_t *)blobid;        ham_u8_t *data=((ham_u8_t *)blobid)+sizeof(blob_t);        /* when the database is closing, the header is already deleted */        if (!hdr)            return (0);        /* resize buffer, if necessary */        if (!(record->flags & HAM_RECORD_USER_ALLOC)) {            if (blob_get_user_size(hdr)>db_get_record_allocsize(db)) {                void *newdata=ham_mem_alloc(db,                         (ham_u32_t)blob_get_user_size(hdr));                if (!newdata)                     return (HAM_OUT_OF_MEMORY);                if (db_get_record_allocdata(db))                    ham_mem_free(db, db_get_record_allocdata(db));                record->data=newdata;                db_set_record_allocdata(db, newdata);                db_set_record_allocsize(db,(ham_size_t)blob_get_user_size(hdr));            }            else                record->data=db_get_record_allocdata(db);        }        /* and copy the data */        memcpy(record->data, data, (ham_size_t)blob_get_user_size(hdr));        record->size=(ham_size_t)blob_get_user_size(hdr);        return (0);    }    ham_assert(blobid%DB_CHUNKSIZE==0, ("blobid is %llu", blobid));    /*     * first step: read the blob header      */    st=my_read_chunk(db, blobid, (ham_u8_t *)&hdr, sizeof(hdr));    if (st)        return (st);    ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0));    /*     * sanity check     */    ham_assert(blob_get_self(&hdr)==blobid,             ("invalid blobid %llu != %llu", blob_get_self(&hdr), blobid));    if (blob_get_self(&hdr)!=blobid)        return (HAM_BLOB_NOT_FOUND);    /*     * second step: resize the blob buffer     */    if (!(record->flags & HAM_RECORD_USER_ALLOC)) {        if (blob_get_real_size(&hdr)>db_get_record_allocsize(db)) {            void *newdata=ham_mem_alloc(db,                     (ham_size_t)blob_get_real_size(&hdr));            if (!newdata)                 return (HAM_OUT_OF_MEMORY);            if (db_get_record_allocdata(db))                ham_mem_free(db, db_get_record_allocdata(db));            record->data=newdata;            db_set_record_allocdata(db, newdata);            db_set_record_allocsize(db, (ham_size_t)blob_get_real_size(&hdr));        }        else            record->data=db_get_record_allocdata(db);    }    /*     * third step: read the blob data     */    st=my_read_chunk(db, blobid+sizeof(blob_t), record->data,             (ham_size_t)blob_get_user_size(&hdr));    if (st)        return (st);    record->size=(ham_size_t)blob_get_user_size(&hdr);    return (0);}ham_status_tblob_replace(ham_db_t *db, ham_offset_t old_blobid,         ham_u8_t *data, ham_size_t size, ham_u32_t flags,         ham_offset_t *new_blobid){    ham_status_t st;    ham_size_t alloc_size;    blob_t old_hdr, new_hdr;    /*     * inmemory-databases: free the old blob,      * allocate a new blob     */    if (db_get_rt_flags(db)&HAM_IN_MEMORY_DB) {        st=blob_free(db, old_blobid, flags);        if (st)            return (st);        return (blob_allocate(db, data, size, flags, new_blobid));    }    ham_assert(old_blobid%DB_CHUNKSIZE==0, (0));    /*     * blobs are CHUNKSIZE-allocated      */    alloc_size=sizeof(blob_t)+size;    if (alloc_size%DB_CHUNKSIZE!=0)        alloc_size=((alloc_size/DB_CHUNKSIZE)*DB_CHUNKSIZE)+DB_CHUNKSIZE;    /*     * first, read the blob header; if the new blob fits into the      * old blob, we overwrite the old blob (and add the remaining     * space to the freelist, if there is any)     */    st=my_read_chunk(db, old_blobid, (ham_u8_t *)&old_hdr,             sizeof(old_hdr));    if (st)        return (st);    ham_assert(blob_get_alloc_size(&old_hdr)%DB_CHUNKSIZE==0, (0));    /*     * sanity check     */    ham_assert(blob_get_self(&old_hdr)==old_blobid,             ("invalid blobid %llu != %llu", blob_get_self(&old_hdr),             old_blobid));    if (blob_get_self(&old_hdr)!=old_blobid)        return (HAM_BLOB_NOT_FOUND);    /*     * now compare the sizes     */    if (alloc_size<=blob_get_alloc_size(&old_hdr)) {        ham_u8_t *chunk_data[2]={(ham_u8_t *)&new_hdr, data};        ham_size_t chunk_size[2]={sizeof(new_hdr), size};        /*          * setup the new blob header         */        blob_set_self(&new_hdr, blob_get_self(&old_hdr));        blob_set_user_size(&new_hdr, size);        blob_set_real_size(&new_hdr, size+sizeof(blob_t));        if (blob_get_alloc_size(&old_hdr)-alloc_size>SMALLEST_CHUNK_SIZE)            blob_set_alloc_size(&new_hdr, alloc_size);        else            blob_set_alloc_size(&new_hdr, blob_get_alloc_size(&old_hdr));        st=my_write_chunks(db, 0, blob_get_self(&new_hdr),                chunk_data, chunk_size, 2);        if (st)            return (st);        /*         * move remaining data to the freelist         */        if (blob_get_alloc_size(&old_hdr)!=blob_get_alloc_size(&new_hdr)) {            (void)freel_mark_free(db,                   blob_get_self(&new_hdr)+blob_get_alloc_size(&new_hdr),                   (ham_size_t)(blob_get_alloc_size(&old_hdr)-                    blob_get_alloc_size(&new_hdr)));        }        /*         * the old rid is the new rid         */        *new_blobid=blob_get_self(&new_hdr);        return (0);    }    else {        (void)freel_mark_free(db, old_blobid,                 (ham_size_t)blob_get_alloc_size(&old_hdr));        return (blob_allocate(db, data, size, flags, new_blobid));    }}ham_status_tblob_free(ham_db_t *db, ham_offset_t blobid, ham_u32_t flags){    ham_status_t st;    blob_t hdr;    /*     * in-memory-database: the blobid is actually a pointer to the memory     * buffer, in which the blob is stored     */    if (db_get_rt_flags(db)&HAM_IN_MEMORY_DB) {        ham_u8_t *data=(ham_u8_t *)blobid;        ham_mem_free(db, data);        return (0);    }    ham_assert(blobid%DB_CHUNKSIZE==0, (0));    /*     * fetch the blob header      */    st=my_read_chunk(db, blobid, (ham_u8_t *)&hdr, sizeof(hdr));    if (st)        return (st);    ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0));    /*     * sanity check     */    ham_assert(blob_get_self(&hdr)==blobid,             ("invalid blobid %llu != %llu", blob_get_self(&hdr), blobid);)    if (blob_get_self(&hdr)!=blobid)        return (HAM_BLOB_NOT_FOUND);    /*     * move the blob to the freelist     */    (void)freel_mark_free(db, blobid,             (ham_size_t)blob_get_alloc_size(&hdr));    return (0);}

⌨️ 快捷键说明

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