📄 blob.c
字号:
} } 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 + -