mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[svn-r18618] Description:
Add new internal object header routines to query the header chunk that a message is in, and to lock/unlock a message into a chunk (so it doesn't get moved into another chunk during allocation/free events). Also, move dataspace message to beginning of object header messages added to a dataset's object header, so it can be locked into chunk #0 (when performing SWMR operations). Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.6.3 (amazon) in debug mode Mac OS X/32 10.6.3 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
This commit is contained in:
parent
edf124f40b
commit
d94581e19b
@ -167,8 +167,7 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
|
||||
|
||||
/* Create the new dataset & get its ID */
|
||||
if(NULL == (dset = H5D_create_named(&loc, name, type_id, space, lcpl_id,
|
||||
dcpl_id, dapl_id, H5AC_dxpl_id)))
|
||||
if(NULL == (dset = H5D_create_named(&loc, name, type_id, space, lcpl_id, dcpl_id, dapl_id, H5AC_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
|
||||
if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
|
||||
@ -329,7 +328,7 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
|
||||
|
||||
/* Open the dataset */
|
||||
if((dset = H5D_open(&dset_loc, dapl_id, dxpl_id)) == NULL)
|
||||
if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
|
||||
|
||||
/* Register an atom for the dataset */
|
||||
|
@ -166,8 +166,7 @@ H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID")
|
||||
|
||||
/* Build and open the new dataset */
|
||||
if(NULL == (dset = H5D_create_named(&loc, name, type_id, space,
|
||||
H5P_LINK_CREATE_DEFAULT, dcpl_id, H5P_DATASET_ACCESS_DEFAULT, H5AC_dxpl_id)))
|
||||
if(NULL == (dset = H5D_create_named(&loc, name, type_id, space, H5P_LINK_CREATE_DEFAULT, dcpl_id, H5P_DATASET_ACCESS_DEFAULT, H5AC_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
|
||||
|
||||
/* Register the new dataset to get an ID for it */
|
||||
@ -240,7 +239,7 @@ H5Dopen1(hid_t loc_id, const char *name)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
|
||||
|
||||
/* Open the dataset */
|
||||
if((dset = H5D_open(&dset_loc, dapl_id, dxpl_id)) == NULL)
|
||||
if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
|
||||
|
||||
/* Register an atom for the dataset */
|
||||
|
15
src/H5Dint.c
15
src/H5Dint.c
@ -797,6 +797,12 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id)
|
||||
if(NULL == (oh = H5O_pin(oloc, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
|
||||
|
||||
/* Update the datatype and dataspace header messages */
|
||||
if(H5S_append(file, dxpl_id, oh, dset->shared->space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message")
|
||||
if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, type) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message")
|
||||
|
||||
/* Write new fill value message */
|
||||
if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update new fill value header message")
|
||||
@ -818,12 +824,6 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update old fill value header message")
|
||||
} /* end if */
|
||||
|
||||
/* Update the datatype and dataspace header messages */
|
||||
if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, type) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message")
|
||||
if(H5S_append(file, dxpl_id, oh, dset->shared->space) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message")
|
||||
|
||||
/* Update/create the layout (and I/O pipeline & EFL) messages */
|
||||
if(H5D_layout_oh_create(file, dxpl_id, oh, dset, dapl_id) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout/pline/efl header message")
|
||||
@ -1044,7 +1044,6 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't incr object ref. count")
|
||||
if(H5FO_insert(new_dset->oloc.file, new_dset->oloc.addr, new_dset->shared, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects")
|
||||
|
||||
new_dset->shared->fo_count = 1;
|
||||
|
||||
/* Success */
|
||||
@ -1357,7 +1356,7 @@ H5D_close(H5D_t *dataset)
|
||||
|
||||
/* check args */
|
||||
HDassert(dataset && dataset->oloc.file && dataset->shared);
|
||||
HDassert(dataset->shared->fo_count >0);
|
||||
HDassert(dataset->shared->fo_count > 0);
|
||||
|
||||
/* Dump debugging info */
|
||||
#ifdef H5D_CHUNK_DEBUG
|
||||
|
@ -290,9 +290,8 @@ H5O_dset_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id)
|
||||
HDassert(crt_info);
|
||||
HDassert(obj_loc);
|
||||
|
||||
/* Create the the dqtaset */
|
||||
if(NULL == (dset = H5D_create(f, crt_info->type_id, crt_info->space,
|
||||
crt_info->dcpl_id, crt_info->dapl_id, dxpl_id)))
|
||||
/* Create the the dataset */
|
||||
if(NULL == (dset = H5D_create(f, crt_info->type_id, crt_info->space, crt_info->dcpl_id, crt_info->dapl_id, dxpl_id)))
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset")
|
||||
|
||||
/* Set up the new dataset's location */
|
||||
|
12
src/H5O.c
12
src/H5O.c
@ -1971,10 +1971,10 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force)
|
||||
|
||||
/* Check version, to determine how to store time information */
|
||||
if(oh->version == H5O_VERSION_1) {
|
||||
unsigned idx; /* Index of modification time message to update */
|
||||
int idx; /* Index of modification time message to update */
|
||||
|
||||
/* Look for existing message */
|
||||
for(idx = 0; idx < oh->nmesgs; idx++)
|
||||
for(idx = 0; idx < (int)oh->nmesgs; idx++)
|
||||
if(H5O_MSG_MTIME == oh->mesg[idx].type || H5O_MSG_MTIME_NEW == oh->mesg[idx].type)
|
||||
break;
|
||||
|
||||
@ -1987,7 +1987,7 @@ H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t force)
|
||||
HGOTO_DONE(SUCCEED); /*nothing to do*/
|
||||
|
||||
/* Allocate space for the modification time message */
|
||||
if(UFAIL == (idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)))
|
||||
if((idx = H5O_msg_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, &mesg_flags, &now)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message")
|
||||
|
||||
/* Set the message's flags if appropriate */
|
||||
@ -2094,8 +2094,8 @@ done:
|
||||
herr_t
|
||||
H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags)
|
||||
{
|
||||
unsigned idx; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
int idx; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_bogus_oh, FAIL)
|
||||
|
||||
@ -2103,7 +2103,7 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags)
|
||||
HDassert(oh);
|
||||
|
||||
/* Look for existing message */
|
||||
for(idx = 0; idx < oh->nmesgs; idx++)
|
||||
for(idx = 0; idx < (int)oh->nmesgs; idx++)
|
||||
if(H5O_MSG_BOGUS == oh->mesg[idx].type)
|
||||
break;
|
||||
|
||||
|
377
src/H5Oalloc.c
377
src/H5Oalloc.c
@ -65,9 +65,8 @@ static herr_t H5O_eliminate_gap(H5O_t *oh, unsigned *chk_flags,
|
||||
static herr_t H5O_alloc_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned null_idx,
|
||||
const H5O_msg_class_t *new_type, void *new_native, size_t new_size);
|
||||
static htri_t H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
unsigned chunkno, size_t size, unsigned * msg_idx);
|
||||
static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
size_t size);
|
||||
unsigned chunkno, size_t size, int *msg_idx);
|
||||
static int H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size);
|
||||
static htri_t H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u);
|
||||
static htri_t H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
|
||||
static htri_t H5O_merge_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
|
||||
@ -506,7 +505,7 @@ done:
|
||||
*/
|
||||
static htri_t
|
||||
H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno,
|
||||
size_t size, unsigned * msg_idx)
|
||||
size_t size, int *msg_idx)
|
||||
{
|
||||
H5O_chunk_proxy_t *chk_proxy = NULL; /* Chunk that message is in */
|
||||
unsigned chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting chunk */
|
||||
@ -689,7 +688,7 @@ H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned chunkno,
|
||||
chk_flags |= H5AC__SIZE_CHANGED_FLAG;
|
||||
|
||||
/* Set return value */
|
||||
*msg_idx = (unsigned)extend_msg;
|
||||
*msg_idx = extend_msg;
|
||||
|
||||
done:
|
||||
/* Release chunk */
|
||||
@ -735,7 +734,7 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static unsigned
|
||||
static int
|
||||
H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
{
|
||||
/* Struct for storing information about "best" messages to allocate from */
|
||||
@ -760,7 +759,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
unsigned chunkno; /* Chunk allocated */
|
||||
haddr_t new_chunk_addr;
|
||||
unsigned u; /* Local index variable */
|
||||
unsigned ret_value; /* Return value */
|
||||
int ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk)
|
||||
|
||||
@ -794,6 +793,9 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
else if(curr_msg->type->id == H5O_CONT_ID) {
|
||||
/* Don't consider continuation messages (for now) */
|
||||
} /* end if */
|
||||
else if(curr_msg->locked) {
|
||||
/* Don't consider locked messages */
|
||||
} /* end if */
|
||||
else {
|
||||
unsigned msg_chunkno = curr_msg->chunkno; /* Chunk that the message is in */
|
||||
uint8_t *end_chunk_data = (oh->chunk[msg_chunkno].image + oh->chunk[msg_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[msg_chunkno].gap); /* End of message data in chunk */
|
||||
@ -846,7 +848,8 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
found_other.null_msgno = null_msgno;
|
||||
} /* end if */
|
||||
} /* end else */
|
||||
} else if(found_null < 0 && found_attr.msgno < 0 && found_other.msgno < 0 && msg_chunkno == oh->nchunks - 1)
|
||||
} /* end if */
|
||||
else if(found_null < 0 && found_attr.msgno < 0 && found_other.msgno < 0 && msg_chunkno == oh->nchunks - 1)
|
||||
/* Keep track of the total size of smaller messages in the last
|
||||
* chunk, in case we need to move more than 1 message.
|
||||
*/
|
||||
@ -896,7 +899,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
/* allocate space in file to hold the new chunk */
|
||||
new_chunk_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)size);
|
||||
if(HADDR_UNDEF == new_chunk_addr)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to allocate space for new chunk")
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for new chunk")
|
||||
|
||||
/*
|
||||
* Create the new chunk giving it a file address.
|
||||
@ -906,7 +909,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
H5O_chunk_t *x;
|
||||
|
||||
if(NULL == (x = H5FL_SEQ_REALLOC(H5O_chunk_t, oh->chunk, na)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
oh->alloc_nchunks = na;
|
||||
oh->chunk = x;
|
||||
} /* end if */
|
||||
@ -916,7 +919,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
oh->chunk[chunkno].size = size;
|
||||
oh->chunk[chunkno].gap = 0;
|
||||
if(NULL == (oh->chunk[chunkno].image = p = H5FL_BLK_CALLOC(chunk_image, size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
|
||||
/* If this is a later version of the object header format, put the magic
|
||||
* # at the beginning of the chunk image.
|
||||
@ -932,8 +935,9 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
*/
|
||||
if(oh->nmesgs + 3 > oh->alloc_nmesgs)
|
||||
if(H5O_alloc_msgs(oh, (size_t)3) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages")
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
|
||||
|
||||
/* Check if we need to move multiple messages, in order to make room for the new message */
|
||||
if(multi_size > 0) {
|
||||
/* Move all non-null messages in the last chunk to the new chunk. This
|
||||
* should be extremely rare so we don't care too much about minimizing
|
||||
@ -943,7 +947,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
|
||||
/* Protect last chunk */
|
||||
if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, chunkno - 1)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, UFAIL, "unable to load object header chunk")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
|
||||
/* Copy each message to the new location */
|
||||
for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++)
|
||||
@ -953,7 +957,8 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
if(u < oh->nmesgs - 1)
|
||||
HDmemmove(curr_msg, curr_msg + 1, ((oh->nmesgs - 1) - u) * sizeof(H5O_mesg_t));
|
||||
oh->nmesgs--;
|
||||
} else {
|
||||
} /* end if */
|
||||
else {
|
||||
/* Copy the raw data */
|
||||
HDmemcpy(p, curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh),
|
||||
curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
|
||||
@ -989,7 +994,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
|
||||
/* Release chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, H5AC__DIRTIED_FLAG) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, UFAIL, "unable to unprotect object header chunk")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} else if(found_null < 0) {
|
||||
/* Move message (that will be replaced with continuation message)
|
||||
* to new chunk, if necessary.
|
||||
@ -998,7 +1003,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
|
||||
/* Protect chunk */
|
||||
if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, oh->mesg[found_other.msgno].chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, UFAIL, "unable to load object header chunk")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
|
||||
/* Create null message for space that message to copy currently occupies */
|
||||
found_null = (int)oh->nmesgs++;
|
||||
@ -1055,7 +1060,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
|
||||
/* Release chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, H5AC__DIRTIED_FLAG) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, UFAIL, "unable to unprotect object header chunk")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} /* end if */
|
||||
HDassert(found_null >= 0);
|
||||
|
||||
@ -1071,21 +1076,21 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size)
|
||||
|
||||
/* Insert the new chunk into the cache */
|
||||
if(H5O_chunk_add(f, dxpl_id, oh, chunkno) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't add new chunk to cache")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't add new chunk to cache")
|
||||
|
||||
/* Initialize the continuation information */
|
||||
if(NULL == (cont = H5FL_MALLOC(H5O_cont_t)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
cont->addr = oh->chunk[chunkno].addr;
|
||||
cont->size = oh->chunk[chunkno].size;
|
||||
cont->chunkno = chunkno;
|
||||
|
||||
/* Split the null message and point at continuation message */
|
||||
if(H5O_alloc_null(f, dxpl_id, oh, (unsigned)found_null, H5O_MSG_CONT, cont, cont_size) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't split null message")
|
||||
|
||||
/* Set return value */
|
||||
ret_value = idx;
|
||||
ret_value = (int)idx;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@ -1098,7 +1103,6 @@ done:
|
||||
* Purpose: Allocate enough space in the object header for this message.
|
||||
*
|
||||
* Return: Success: Index of message
|
||||
*
|
||||
* Failure: Negative
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
@ -1107,16 +1111,16 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
unsigned
|
||||
int
|
||||
H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
const void *mesg)
|
||||
{
|
||||
size_t raw_size; /* Raw size of message */
|
||||
size_t aligned_size; /* Size of message including alignment */
|
||||
unsigned idx; /* Index of message which fits allocation */
|
||||
unsigned ret_value; /* Return value */
|
||||
size_t raw_size; /* Raw size of message */
|
||||
size_t aligned_size; /* Size of message including alignment */
|
||||
int idx; /* Index of message which fits allocation */
|
||||
int ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_alloc, UFAIL)
|
||||
FUNC_ENTER_NOAPI(H5O_alloc, FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(oh);
|
||||
@ -1125,16 +1129,16 @@ H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
|
||||
/* Compute the size needed to store the message in the object header */
|
||||
if((raw_size = (type->raw_size)(f, FALSE, mesg)) >= H5O_MESG_MAX_SIZE)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "object header message is too large")
|
||||
aligned_size = H5O_ALIGN_OH(oh, raw_size);
|
||||
|
||||
/* look for a null message which is large enough */
|
||||
for(idx = 0; idx < oh->nmesgs; idx++)
|
||||
for(idx = 0; idx < (int)oh->nmesgs; idx++)
|
||||
if(H5O_NULL_ID == oh->mesg[idx].type->id && oh->mesg[idx].raw_size >= aligned_size)
|
||||
break;
|
||||
|
||||
/* if we didn't find one, then allocate more header space */
|
||||
if(idx >= oh->nmesgs) {
|
||||
if(idx >= (int)oh->nmesgs) {
|
||||
unsigned chunkno;
|
||||
|
||||
/* check to see if we can extend one of the chunks. If we can,
|
||||
@ -1144,37 +1148,31 @@ H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
* must have file space allocated to them.
|
||||
*/
|
||||
for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
|
||||
htri_t tri_result;
|
||||
htri_t tri_result; /* Status from attempting to extend chunk */
|
||||
|
||||
HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
|
||||
|
||||
tri_result = H5O_alloc_extend_chunk(f, dxpl_id, oh, chunkno, raw_size, &idx);
|
||||
if((tri_result = H5O_alloc_extend_chunk(f, dxpl_id, oh, chunkno, raw_size, &idx)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTEXTEND, FAIL, "H5O_alloc_extend_chunk failed unexpectedly")
|
||||
if(tri_result == TRUE)
|
||||
break;
|
||||
else if(tri_result == FALSE)
|
||||
idx = UFAIL;
|
||||
else
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTEXTEND, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
|
||||
} /* end for */
|
||||
|
||||
/* If idx is still UFAIL, we were not able to extend a chunk,
|
||||
* create a new one.
|
||||
*/
|
||||
if(idx == UFAIL)
|
||||
if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, raw_size)) == UFAIL)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk")
|
||||
/* If we were not able to extend a chunk, create a new one */
|
||||
if(idx >= (int)oh->nmesgs)
|
||||
if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, raw_size)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "unable to create a new object header data chunk")
|
||||
} /* end if */
|
||||
HDassert(idx >= 0 && idx < (int)oh->nmesgs);
|
||||
|
||||
/* Split the null message and point at continuation message */
|
||||
if(H5O_alloc_null(f, dxpl_id, oh, idx, type, NULL, aligned_size) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, UFAIL, "can't split null message")
|
||||
if(H5O_alloc_null(f, dxpl_id, oh, (unsigned)idx, type, NULL, aligned_size) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't split null message")
|
||||
|
||||
/* Mark object header as dirty in cache */
|
||||
if(H5AC_mark_pinned_or_protected_entry_dirty(oh) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, UFAIL, "unable to mark object header as dirty")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty")
|
||||
|
||||
/* Set return value */
|
||||
ret_value = idx;
|
||||
ret_value = (int)idx;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@ -1294,13 +1292,23 @@ H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u)
|
||||
size_t gap_size; /* Size of gap produced */
|
||||
unsigned v; /* Local index variable */
|
||||
|
||||
/* Find size of all nonnull messages in the chunk pointed to by the continuation message */
|
||||
/* Spin through messages */
|
||||
nonnull_size = 0;
|
||||
for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++)
|
||||
if(curr_msg->chunkno == deleted_chunkno && curr_msg->type->id != H5O_NULL_ID) {
|
||||
HDassert(curr_msg->type->id != H5O_CONT_ID);
|
||||
nonnull_size += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++) {
|
||||
if(curr_msg->chunkno == deleted_chunkno) {
|
||||
/* If there's a locked message, we can't move all messages out of
|
||||
* chunk to delete, so get out now.
|
||||
*/
|
||||
if(curr_msg->locked)
|
||||
HGOTO_DONE(FALSE)
|
||||
|
||||
/* Find size of all non-null messages in the chunk pointed to by the continuation message */
|
||||
if(curr_msg->type->id != H5O_NULL_ID) {
|
||||
HDassert(curr_msg->type->id != H5O_CONT_ID);
|
||||
nonnull_size += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
} /* end if */
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
/* Size of gap in chunk w/continuation message */
|
||||
gap_size = oh->chunk[cont_msg->chunkno].gap;
|
||||
@ -1526,145 +1534,148 @@ H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
||||
} /* end else-if */
|
||||
} /* end if */
|
||||
|
||||
/* Loop over messages again, looking for large enough null message in earlier chunk */
|
||||
for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
|
||||
if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
|
||||
&& curr_msg->raw_size <= null_msg->raw_size) {
|
||||
H5O_chunk_proxy_t *null_chk_proxy; /* Chunk that null message is in */
|
||||
H5O_chunk_proxy_t *curr_chk_proxy; /* Chunk that message is in */
|
||||
unsigned null_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting null chunk */
|
||||
unsigned curr_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting curr chunk */
|
||||
unsigned old_chunkno; /* Old message information */
|
||||
uint8_t *old_raw;
|
||||
/* Don't let locked messages be moved into earlier chunk */
|
||||
if(!curr_msg->locked) {
|
||||
/* Loop over messages again, looking for large enough null message in earlier chunk */
|
||||
for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
|
||||
if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
|
||||
&& curr_msg->raw_size <= null_msg->raw_size) {
|
||||
H5O_chunk_proxy_t *null_chk_proxy; /* Chunk that null message is in */
|
||||
H5O_chunk_proxy_t *curr_chk_proxy; /* Chunk that message is in */
|
||||
unsigned null_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting null chunk */
|
||||
unsigned curr_chk_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting curr chunk */
|
||||
unsigned old_chunkno; /* Old message information */
|
||||
uint8_t *old_raw;
|
||||
|
||||
/* Keep old information about non-null message */
|
||||
old_chunkno = curr_msg->chunkno;
|
||||
old_raw = curr_msg->raw;
|
||||
/* Keep old information about non-null message */
|
||||
old_chunkno = curr_msg->chunkno;
|
||||
old_raw = curr_msg->raw;
|
||||
|
||||
/* Protect chunks */
|
||||
if(NULL == (null_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, null_msg->chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
if(NULL == (curr_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
/* Protect chunks */
|
||||
if(NULL == (null_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, null_msg->chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
if(NULL == (curr_chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, curr_msg->chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
|
||||
/* Copy raw data for non-null message to new chunk */
|
||||
HDmemcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
|
||||
/* Copy raw data for non-null message to new chunk */
|
||||
HDmemcpy(null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh), curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh));
|
||||
|
||||
/* Point non-null message at null message's space */
|
||||
curr_msg->chunkno = null_msg->chunkno;
|
||||
curr_msg->raw = null_msg->raw;
|
||||
curr_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Change information for null message */
|
||||
if(curr_msg->raw_size == null_msg->raw_size) {
|
||||
/* Point null message at old non-null space */
|
||||
/* (Instead of freeing it and allocating new message) */
|
||||
null_msg->chunkno = old_chunkno;
|
||||
null_msg->raw = old_raw;
|
||||
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Release current chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
|
||||
/* Check for gap in null message's chunk */
|
||||
if(oh->chunk[old_chunkno].gap > 0) {
|
||||
/* Eliminate the gap in the chunk */
|
||||
if(H5O_eliminate_gap(oh, &null_chk_flags, null_msg,
|
||||
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
|
||||
oh->chunk[old_chunkno].gap) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
|
||||
} /* end if */
|
||||
|
||||
/* Release null chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
unsigned new_null_msg; /* Message index for new null message */
|
||||
|
||||
/* Check if null message is large enough to still exist */
|
||||
if((null_msg->raw_size - curr_msg->raw_size) < (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
|
||||
size_t gap_size = null_msg->raw_size - curr_msg->raw_size; /* Size of gap produced */
|
||||
|
||||
/* Adjust the size of the null message being eliminated */
|
||||
null_msg->raw_size = curr_msg->raw_size;
|
||||
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Add the gap to the chunk */
|
||||
if(H5O_add_gap(f, oh, null_msg->chunkno, &null_chk_flags, v, null_msg->raw + null_msg->raw_size, gap_size) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk")
|
||||
|
||||
/* Re-use message # for new null message taking place of non-null message */
|
||||
new_null_msg = v;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Adjust null message's size & offset */
|
||||
null_msg->raw += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
null_msg->raw_size -= curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Create new null message for previous location of non-null message */
|
||||
if(oh->nmesgs >= oh->alloc_nmesgs) {
|
||||
if(H5O_alloc_msgs(oh, (size_t)1) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
|
||||
|
||||
/* "Retarget" 'curr_msg' pointer into newly re-allocated array of messages */
|
||||
curr_msg = &oh->mesg[u];
|
||||
} /* end if */
|
||||
|
||||
/* Get message # for new null message */
|
||||
new_null_msg = oh->nmesgs++;
|
||||
} /* end else */
|
||||
|
||||
/* Release null message's chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
|
||||
/* Initialize new null message to take over non-null message's location */
|
||||
oh->mesg[new_null_msg].type = H5O_MSG_NULL;
|
||||
oh->mesg[new_null_msg].native = NULL;
|
||||
oh->mesg[new_null_msg].raw = old_raw;
|
||||
oh->mesg[new_null_msg].raw_size = curr_msg->raw_size;
|
||||
oh->mesg[new_null_msg].chunkno = old_chunkno;
|
||||
|
||||
/* Mark new null message dirty */
|
||||
oh->mesg[new_null_msg].dirty = TRUE;
|
||||
/* Point non-null message at null message's space */
|
||||
curr_msg->chunkno = null_msg->chunkno;
|
||||
curr_msg->raw = null_msg->raw;
|
||||
curr_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Check for gap in new null message's chunk */
|
||||
if(oh->chunk[old_chunkno].gap > 0) {
|
||||
/* Eliminate the gap in the chunk */
|
||||
if(H5O_eliminate_gap(oh, &curr_chk_flags, &oh->mesg[new_null_msg],
|
||||
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
|
||||
oh->chunk[old_chunkno].gap) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
|
||||
/* Change information for null message */
|
||||
if(curr_msg->raw_size == null_msg->raw_size) {
|
||||
/* Point null message at old non-null space */
|
||||
/* (Instead of freeing it and allocating new message) */
|
||||
null_msg->chunkno = old_chunkno;
|
||||
null_msg->raw = old_raw;
|
||||
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Release current chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
|
||||
/* Check for gap in null message's chunk */
|
||||
if(oh->chunk[old_chunkno].gap > 0) {
|
||||
/* Eliminate the gap in the chunk */
|
||||
if(H5O_eliminate_gap(oh, &null_chk_flags, null_msg,
|
||||
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
|
||||
oh->chunk[old_chunkno].gap) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
|
||||
} /* end if */
|
||||
|
||||
/* Release null chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} /* end if */
|
||||
else {
|
||||
unsigned new_null_msg; /* Message index for new null message */
|
||||
|
||||
/* Release new null message's chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} /* end else */
|
||||
/* Check if null message is large enough to still exist */
|
||||
if((null_msg->raw_size - curr_msg->raw_size) < (size_t)H5O_SIZEOF_MSGHDR_OH(oh)) {
|
||||
size_t gap_size = null_msg->raw_size - curr_msg->raw_size; /* Size of gap produced */
|
||||
|
||||
/* Indicate that we packed messages */
|
||||
packed_msg = TRUE;
|
||||
/* Adjust the size of the null message being eliminated */
|
||||
null_msg->raw_size = curr_msg->raw_size;
|
||||
|
||||
/* Break out of loop */
|
||||
/* (If it's possible to move message to even earlier chunk
|
||||
* we'll get it on the next pass - QAK)
|
||||
*/
|
||||
break;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Add the gap to the chunk */
|
||||
if(H5O_add_gap(f, oh, null_msg->chunkno, &null_chk_flags, v, null_msg->raw + null_msg->raw_size, gap_size) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert gap in chunk")
|
||||
|
||||
/* Re-use message # for new null message taking place of non-null message */
|
||||
new_null_msg = v;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Adjust null message's size & offset */
|
||||
null_msg->raw += curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
null_msg->raw_size -= curr_msg->raw_size + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||
|
||||
/* Mark null message dirty */
|
||||
null_msg->dirty = TRUE;
|
||||
null_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Create new null message for previous location of non-null message */
|
||||
if(oh->nmesgs >= oh->alloc_nmesgs) {
|
||||
if(H5O_alloc_msgs(oh, (size_t)1) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages")
|
||||
|
||||
/* "Retarget" 'curr_msg' pointer into newly re-allocated array of messages */
|
||||
curr_msg = &oh->mesg[u];
|
||||
} /* end if */
|
||||
|
||||
/* Get message # for new null message */
|
||||
new_null_msg = oh->nmesgs++;
|
||||
} /* end else */
|
||||
|
||||
/* Release null message's chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
|
||||
/* Initialize new null message to take over non-null message's location */
|
||||
oh->mesg[new_null_msg].type = H5O_MSG_NULL;
|
||||
oh->mesg[new_null_msg].native = NULL;
|
||||
oh->mesg[new_null_msg].raw = old_raw;
|
||||
oh->mesg[new_null_msg].raw_size = curr_msg->raw_size;
|
||||
oh->mesg[new_null_msg].chunkno = old_chunkno;
|
||||
|
||||
/* Mark new null message dirty */
|
||||
oh->mesg[new_null_msg].dirty = TRUE;
|
||||
curr_chk_flags |= H5AC__DIRTIED_FLAG;
|
||||
|
||||
/* Check for gap in new null message's chunk */
|
||||
if(oh->chunk[old_chunkno].gap > 0) {
|
||||
/* Eliminate the gap in the chunk */
|
||||
if(H5O_eliminate_gap(oh, &curr_chk_flags, &oh->mesg[new_null_msg],
|
||||
((oh->chunk[old_chunkno].image + oh->chunk[old_chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[old_chunkno].gap)),
|
||||
oh->chunk[old_chunkno].gap) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTREMOVE, FAIL, "can't eliminate gap in chunk")
|
||||
} /* end if */
|
||||
|
||||
/* Release new null message's chunk, marking it dirty */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
} /* end else */
|
||||
|
||||
/* Indicate that we packed messages */
|
||||
packed_msg = TRUE;
|
||||
|
||||
/* Break out of loop */
|
||||
/* (If it's possible to move message to even earlier chunk
|
||||
* we'll get it on the next pass - QAK)
|
||||
*/
|
||||
break;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
|
||||
/* If we packed messages, get out of loop and start over */
|
||||
/* (Don't know if this has any benefit one way or the other -QAK) */
|
||||
|
213
src/H5Omessage.c
213
src/H5Omessage.c
@ -207,7 +207,7 @@ herr_t
|
||||
H5O_msg_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
unsigned mesg_flags, unsigned update_flags, void *mesg)
|
||||
{
|
||||
unsigned idx; /* Index of message to modify */
|
||||
int idx; /* Index of message to modify */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_msg_append_real, FAIL)
|
||||
@ -220,11 +220,11 @@ H5O_msg_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *t
|
||||
HDassert(mesg);
|
||||
|
||||
/* Allocate space for a new message */
|
||||
if((idx = H5O_msg_alloc(f, dxpl_id, oh, type, &mesg_flags, mesg)) == UFAIL)
|
||||
if((idx = H5O_msg_alloc(f, dxpl_id, oh, type, &mesg_flags, mesg)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, FAIL, "unable to create new message")
|
||||
|
||||
/* Copy the information for the message */
|
||||
if(H5O_copy_mesg(f, dxpl_id, oh, idx, type, mesg, mesg_flags, update_flags) < 0)
|
||||
if(H5O_copy_mesg(f, dxpl_id, oh, (unsigned)idx, type, mesg, mesg_flags, update_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to write message")
|
||||
#ifdef H5O_DEBUG
|
||||
H5O_assert(oh);
|
||||
@ -477,11 +477,11 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg,
|
||||
|
||||
/* Get the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to load object header")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, NULL, "unable to protect object header")
|
||||
|
||||
/* Call the "real" read routine */
|
||||
if(NULL == (ret_value = H5O_msg_read_oh(loc->file, dxpl_id, oh, type_id, mesg)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header message")
|
||||
|
||||
done:
|
||||
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
|
||||
@ -802,7 +802,7 @@ H5O_msg_count(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
|
||||
|
||||
/* Load the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Count the messages of the correct type */
|
||||
ret_value = H5O_msg_count_real(oh, type);
|
||||
@ -883,7 +883,7 @@ H5O_msg_exists(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
|
||||
|
||||
/* Load the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Call the "real" exists routine */
|
||||
if((ret_value = H5O_msg_exists_oh(oh, type_id)) < 0)
|
||||
@ -1223,7 +1223,7 @@ H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id,
|
||||
|
||||
/* Protect the object header to iterate over */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Call the "real" iterate routine */
|
||||
if((ret_value = H5O_msg_iterate_real(loc->file, oh, type, op, op_data, dxpl_id)) < 0)
|
||||
@ -1888,12 +1888,12 @@ done:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
unsigned
|
||||
int
|
||||
H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
unsigned *mesg_flags, void *native)
|
||||
{
|
||||
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
|
||||
unsigned ret_value = UFAIL; /* Return value */
|
||||
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
|
||||
int ret_value = FAIL; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5O_msg_alloc)
|
||||
|
||||
@ -1907,28 +1907,28 @@ H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
||||
|
||||
/* Check if message is already shared */
|
||||
if((shared_mesg = H5O_msg_is_shared(type->id, native)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, UFAIL, "error determining if message is shared")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "error determining if message is shared")
|
||||
else if(shared_mesg > 0) {
|
||||
/* Increment message's reference count */
|
||||
if(type->link && (type->link)(f, dxpl_id, oh, native) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared message ref count")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared message ref count")
|
||||
*mesg_flags |= H5O_MSG_FLAG_SHARED;
|
||||
} /* end if */
|
||||
else {
|
||||
/* Attempt to share message */
|
||||
if(H5SM_try_share(f, dxpl_id, oh, type->id, native, mesg_flags) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, UFAIL, "error determining if message should be shared")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "error determining if message should be shared")
|
||||
} /* end else */
|
||||
|
||||
/* Allocate space in the object header for the message */
|
||||
if((ret_value = H5O_alloc(f, dxpl_id, oh, type, native)) == UFAIL)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message")
|
||||
if((ret_value = H5O_alloc(f, dxpl_id, oh, type, native)) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for message")
|
||||
|
||||
/* Get the message's "creation index", if it has one */
|
||||
if(type->get_crt_index) {
|
||||
/* Retrieve the creation index from the native message */
|
||||
if((type->get_crt_index)(native, &oh->mesg[ret_value].crt_idx) < 0)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, UFAIL, "unable to retrieve creation index")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve creation index")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
@ -1970,7 +1970,7 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
|
||||
|
||||
/* Protect chunk */
|
||||
if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, idx_msg->chunkno)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header chunk")
|
||||
|
||||
/* Reset existing native information for the header's message */
|
||||
H5O_msg_reset_real(type, idx_msg->native);
|
||||
@ -1988,7 +1988,7 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
|
||||
|
||||
/* Release chunk */
|
||||
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, chk_flags) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk")
|
||||
chk_proxy = NULL;
|
||||
|
||||
/* Update the modification time, if requested */
|
||||
@ -1999,7 +1999,7 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
|
||||
done:
|
||||
/* Release chunk, if not already released */
|
||||
if(chk_proxy && H5O_chunk_unprotect(f, dxpl_id, chk_proxy, chk_flags) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header chunk")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_copy_mesg() */
|
||||
@ -2241,3 +2241,176 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_flush_msgs() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_msg_chunkno
|
||||
*
|
||||
* Purpose: Queries the object header chunk index for a message.
|
||||
*
|
||||
* Return: Success: >=0 value indicating the chunk number for
|
||||
* the message
|
||||
* Failure: <0
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@hdfgroup.org
|
||||
* Apr 22 2010
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
H5O_msg_get_chunkno(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
|
||||
{
|
||||
H5O_t *oh = NULL; /* Object header to use */
|
||||
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
|
||||
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
|
||||
unsigned idx; /* Index of message to modify */
|
||||
int ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_msg_get_chunkno, FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(loc);
|
||||
HDassert(loc->file);
|
||||
HDassert(H5F_addr_defined(loc->addr));
|
||||
HDassert(type_id < NELMTS(H5O_msg_class_g));
|
||||
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
|
||||
HDassert(type);
|
||||
|
||||
/* Get the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Locate message of correct type */
|
||||
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
|
||||
if(type == idx_msg->type)
|
||||
break;
|
||||
if(idx == oh->nmesgs)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
|
||||
|
||||
/* Set return value */
|
||||
ret_value = idx_msg->chunkno;
|
||||
|
||||
done:
|
||||
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_msg_get_chunkno() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_msg_lock
|
||||
*
|
||||
* Purpose: Locks a message into a particular chunk, preventing it from
|
||||
* being moved into another chunk.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@hdfgroup.org
|
||||
* Apr 22 2010
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
|
||||
{
|
||||
H5O_t *oh = NULL; /* Object header to use */
|
||||
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
|
||||
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
|
||||
unsigned idx; /* Index of message to modify */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_msg_lock, FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(loc);
|
||||
HDassert(loc->file);
|
||||
HDassert(H5F_addr_defined(loc->addr));
|
||||
HDassert(type_id < NELMTS(H5O_msg_class_g));
|
||||
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
|
||||
HDassert(type);
|
||||
|
||||
/* Get the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Locate message of correct type */
|
||||
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
|
||||
if(type == idx_msg->type)
|
||||
break;
|
||||
if(idx == oh->nmesgs)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
|
||||
|
||||
/* Fail if the message is already locked */
|
||||
if(idx_msg->locked)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOCK, FAIL, "message already locked")
|
||||
|
||||
/* Make the message locked */
|
||||
idx_msg->locked = TRUE;
|
||||
|
||||
done:
|
||||
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_msg_lock() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_msg_unlock
|
||||
*
|
||||
* Purpose: Unlocks a message, allowing it to be moved into another chunk.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@hdfgroup.org
|
||||
* Apr 22 2010
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
|
||||
{
|
||||
H5O_t *oh = NULL; /* Object header to use */
|
||||
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
|
||||
H5O_mesg_t *idx_msg; /* Pointer to message to modify */
|
||||
unsigned idx; /* Index of message to modify */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5O_msg_unlock, FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(loc);
|
||||
HDassert(loc->file);
|
||||
HDassert(H5F_addr_defined(loc->addr));
|
||||
HDassert(type_id < NELMTS(H5O_msg_class_g));
|
||||
type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
|
||||
HDassert(type);
|
||||
|
||||
/* Get the object header */
|
||||
if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
|
||||
|
||||
/* Locate message of correct type */
|
||||
for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
|
||||
if(type == idx_msg->type)
|
||||
break;
|
||||
if(idx == oh->nmesgs)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message type not found")
|
||||
|
||||
/* Fail if the message is not locked */
|
||||
if(!idx_msg->locked)
|
||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNLOCK, FAIL, "message not locked")
|
||||
|
||||
/* Make the message unlocked */
|
||||
idx_msg->locked = FALSE;
|
||||
|
||||
done:
|
||||
if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_msg_unlock() */
|
||||
|
||||
|
@ -244,6 +244,7 @@ struct H5O_msg_class_t {
|
||||
struct H5O_mesg_t {
|
||||
const H5O_msg_class_t *type; /*type of message */
|
||||
hbool_t dirty; /*raw out of date wrt native */
|
||||
hbool_t locked; /*message is locked into chunk */
|
||||
uint8_t flags; /*message flags */
|
||||
H5O_msg_crt_idx_t crt_idx; /*message creation index */
|
||||
unsigned chunkno; /*chunk number for this mesg */
|
||||
@ -529,7 +530,7 @@ H5_DLL herr_t H5O_dec_rc(H5O_t *oh);
|
||||
H5_DLL herr_t H5O_free(H5O_t *oh);
|
||||
|
||||
/* Object header message routines */
|
||||
H5_DLL unsigned H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
H5_DLL int H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
const H5O_msg_class_t *type, unsigned *mesg_flags, void *mesg);
|
||||
H5_DLL herr_t H5O_msg_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
const H5O_msg_class_t *type, unsigned mesg_flags, unsigned update_flags,
|
||||
@ -563,7 +564,7 @@ H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
|
||||
/* Object header allocation routines */
|
||||
H5_DLL herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
|
||||
H5_DLL unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
H5_DLL int H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
const H5O_msg_class_t *type, const void *mesg);
|
||||
H5_DLL herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||
|
@ -21,8 +21,6 @@
|
||||
*
|
||||
* Purpose: Object header private include file.
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef _H5Oprivate_H
|
||||
@ -692,6 +690,9 @@ H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
|
||||
unsigned type_id, const unsigned char *buf);
|
||||
H5_DLL herr_t H5O_msg_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
|
||||
unsigned type_id, void *mesg);
|
||||
H5_DLL int H5O_msg_get_chunkno(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
|
||||
|
||||
/* Object copying routines */
|
||||
H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
|
||||
|
173
test/ohdr.c
173
test/ohdr.c
@ -97,7 +97,7 @@ test_cont(char *filename, hid_t fapl)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &short_name, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
@ -137,8 +137,9 @@ error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5O_close(&oh_locA);
|
||||
H5O_close(&oh_locB);
|
||||
H5Fclose (file);
|
||||
H5Fclose(file);
|
||||
} H5E_END_TRY;
|
||||
|
||||
return -1;
|
||||
} /* test_cont() */
|
||||
|
||||
@ -146,30 +147,28 @@ error:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose:
|
||||
* Purpose: Exercise private object header behavior and routines
|
||||
*
|
||||
* Return: Success:
|
||||
*
|
||||
* Failure:
|
||||
* Return: Success: 0
|
||||
* Failure: 1
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, November 24, 1998
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
hid_t fapl=-1, file=-1;
|
||||
hid_t dset=-1;
|
||||
H5F_t *f=NULL;
|
||||
hid_t fapl = -1, file = -1;
|
||||
hid_t dset = -1;
|
||||
H5F_t *f = NULL;
|
||||
char filename[1024];
|
||||
H5O_hdr_info_t hdr_info; /* Object info */
|
||||
H5O_loc_t oh_loc;
|
||||
H5O_hdr_info_t hdr_info; /* Object info */
|
||||
H5O_loc_t oh_loc, oh_loc2; /* Object header locations */
|
||||
time_t time_new, ro;
|
||||
int i;
|
||||
int chunkno; /* Chunk index for message */
|
||||
int i; /* Local index variable */
|
||||
hbool_t b; /* Index for "new format" loop */
|
||||
herr_t ret; /* Generic return value */
|
||||
|
||||
@ -187,15 +186,18 @@ main(void)
|
||||
HDputs("Using default file format:");
|
||||
|
||||
/* Set the format to use for the file */
|
||||
if (H5Pset_libver_bounds(fapl, (b ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST) < 0) FAIL_STACK_ERROR
|
||||
if(H5Pset_libver_bounds(fapl, (b ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* test on object continuation block */
|
||||
if (test_cont(filename, fapl) < 0)
|
||||
if(test_cont(filename, fapl) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Create the file to operate on */
|
||||
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
|
||||
if(NULL == (f = (H5F_t *)H5I_object(file))) FAIL_STACK_ERROR
|
||||
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
|
||||
TEST_ERROR
|
||||
if(NULL == (f = (H5F_t *)H5I_object(file)))
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
|
||||
/*
|
||||
@ -359,6 +361,140 @@ main(void)
|
||||
FAIL_STACK_ERROR
|
||||
PASSED();
|
||||
|
||||
/*
|
||||
* Test moving message to first chunk
|
||||
*/
|
||||
TESTING("locking messages");
|
||||
HDmemset(&oh_loc, 0, sizeof(oh_loc));
|
||||
if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Create second object header, to guarantee that first object header uses multiple chunks */
|
||||
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
|
||||
if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Fill object header with messages, creating multiple chunks */
|
||||
for(i = 0; i < 10; i++) {
|
||||
time_new = (i + 1) * 1000 + 10;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
} /* end for */
|
||||
|
||||
/* Get # of object header chunks */
|
||||
if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(hdr_info.nchunks != 2)
|
||||
TEST_ERROR
|
||||
|
||||
/* Add message to lock to object header */
|
||||
time_new = 11111111;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Verify chunk index for message */
|
||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(chunkno != 1)
|
||||
TEST_ERROR
|
||||
|
||||
/* Lock the message into the chunk */
|
||||
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Attempt to lock the message twice */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Delete all the other messages, which would move the message into
|
||||
* chunk #0, if it wasn't locked
|
||||
*/
|
||||
if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Verify chunk index for message */
|
||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(chunkno != 1)
|
||||
TEST_ERROR
|
||||
|
||||
/* Unlock the message */
|
||||
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Attempt to unlock the message twice */
|
||||
H5E_BEGIN_TRY {
|
||||
ret = H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
|
||||
} H5E_END_TRY;
|
||||
if(ret >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Close object headers */
|
||||
if(H5O_close(&oh_loc2) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5O_close(&oh_loc) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Open first object header */
|
||||
HDmemset(&oh_loc, 0, sizeof(oh_loc));
|
||||
if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Create second object header, to guarantee that first object header uses multiple chunks */
|
||||
HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
|
||||
if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Add message to move to object header */
|
||||
time_new = 11111111;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Verify chunk index for message */
|
||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(chunkno != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Lock the message into the chunk */
|
||||
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Fill object header with messages, creating multiple chunks */
|
||||
/* (would normally move locked message to new chunk) */
|
||||
for(i = 0; i < 10; i++) {
|
||||
time_new = (i + 1) * 1000 + 10;
|
||||
if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
} /* end for */
|
||||
|
||||
/* Get # of object header chunks */
|
||||
if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(hdr_info.nchunks != 2)
|
||||
TEST_ERROR
|
||||
|
||||
/* Verify chunk index for message */
|
||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(chunkno != 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Unlock the message */
|
||||
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
/* Close object headers */
|
||||
if(H5O_close(&oh_loc2) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
if(H5O_close(&oh_loc) < 0)
|
||||
FAIL_STACK_ERROR
|
||||
|
||||
PASSED();
|
||||
|
||||
|
||||
/* Test reading datasets with undefined object header messages */
|
||||
HDputs("Accessing objects with unknown header messages:");
|
||||
@ -477,6 +613,7 @@ error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Fclose(file);
|
||||
} H5E_END_TRY;
|
||||
|
||||
return(1);
|
||||
} /* end main() */
|
||||
|
||||
|
@ -2446,15 +2446,9 @@ static void test_sohm_size2(int close_reopen)
|
||||
if((mult_index_med.dsets2 - mult_index_med.dsets1) >
|
||||
(list_index_med.dsets2 - list_index_med.dsets1) * OVERHEAD_ALLOWED)
|
||||
VERIFY(0, 1, "h5_get_file_size");
|
||||
if((mult_index_med.dsets2 - mult_index_med.dsets1) <
|
||||
(list_index_med.dsets2 - list_index_med.dsets1))
|
||||
VERIFY(0, 1, "h5_get_file_size");
|
||||
if((mult_index_btree.dsets2 - mult_index_btree.dsets1) >
|
||||
(btree_index.dsets2 - btree_index.dsets1) * OVERHEAD_ALLOWED)
|
||||
VERIFY(0, 1, "h5_get_file_size");
|
||||
if((mult_index_btree.dsets2 - mult_index_btree.dsets1) <
|
||||
(btree_index.dsets2 - btree_index.dsets1))
|
||||
VERIFY(0, 1, "h5_get_file_size");
|
||||
|
||||
if((mult_index_med.interleaved - mult_index_med.dsets2) >
|
||||
(list_index_med.interleaved - list_index_med.dsets2) * OVERHEAD_ALLOWED)
|
||||
|
Loading…
Reference in New Issue
Block a user