mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-24 17:51:25 +08:00
Refactor H5O code to clean up message allocation, align cache deserialize code
with revise_chunks changes, and remove unused "message locking" code.
This commit is contained in:
parent
70938cbf28
commit
1c6924f18b
421
src/H5Oalloc.c
421
src/H5Oalloc.c
@ -67,8 +67,11 @@ static herr_t H5O_alloc_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t null_idx
|
|||||||
const H5O_msg_class_t *new_type, void *new_native, size_t new_size);
|
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,
|
static htri_t H5O_alloc_extend_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||||
unsigned chunkno, size_t size, size_t *msg_idx);
|
unsigned chunkno, size_t size, size_t *msg_idx);
|
||||||
|
static herr_t H5O__alloc_find_best_nonnull(const H5F_t *f, const H5O_t *oh, size_t *size,
|
||||||
|
H5O_msg_alloc_info_t *found_msg);
|
||||||
static herr_t H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size,
|
static herr_t H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size,
|
||||||
size_t *new_idx);
|
size_t *new_idx);
|
||||||
|
static herr_t H5O__alloc_find_best_null(const H5O_t *oh, size_t size, size_t *mesg_idx);
|
||||||
static htri_t H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u);
|
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_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);
|
static htri_t H5O_merge_null(H5F_t *f, hid_t dxpl_id, H5O_t *oh);
|
||||||
@ -707,17 +710,10 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
* Function: H5O_alloc_new_chunk
|
* Function: H5O__alloc_find_best_nonnull
|
||||||
*
|
*
|
||||||
* Purpose: Allocates a new chunk for the object header, including
|
* Purpose: Find the best fit non-null message for a given size of message
|
||||||
* file space.
|
* to allocate.
|
||||||
*
|
|
||||||
* One of the other chunks will get an object continuation
|
|
||||||
* message. If there isn't room in any other chunk for the
|
|
||||||
* object continuation message, then some message from
|
|
||||||
* another chunk is moved into this chunk to make room.
|
|
||||||
*
|
|
||||||
* SIZE need not be aligned.
|
|
||||||
*
|
*
|
||||||
* Note: The algorithm for finding a message to replace with a
|
* Note: The algorithm for finding a message to replace with a
|
||||||
* continuation message is still fairly limited. It's possible
|
* continuation message is still fairly limited. It's possible
|
||||||
@ -735,50 +731,34 @@ done:
|
|||||||
*
|
*
|
||||||
* Failure: Negative
|
* Failure: Negative
|
||||||
*
|
*
|
||||||
* Programmer: Robb Matzke
|
* Programmer: Quincey Koziol
|
||||||
* matzke@llnl.gov
|
* koziol@lbl.gov
|
||||||
* Aug 7 1997
|
* Oct 21 2016
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
static herr_t
|
static herr_t
|
||||||
H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new_idx)
|
H5O__alloc_find_best_nonnull(const H5F_t *f, const H5O_t *oh, size_t *size,
|
||||||
|
H5O_msg_alloc_info_t *found_msg)
|
||||||
{
|
{
|
||||||
/* Struct for storing information about "best" messages to allocate from */
|
|
||||||
typedef struct {
|
|
||||||
int msgno; /* Index in message array */
|
|
||||||
size_t gap_size; /* Size of any "gap" in the chunk immediately after message */
|
|
||||||
size_t null_size; /* Size of any null message in the chunk immediately after message */
|
|
||||||
size_t total_size; /* Total size of "available" space around message */
|
|
||||||
unsigned null_msgno; /* Message index of null message immediately after message */
|
|
||||||
} alloc_info;
|
|
||||||
|
|
||||||
H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
|
H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
|
||||||
H5O_chunk_proxy_t *chk_proxy; /* Chunk that message is in */
|
size_t cont_size; /* Continuation message size */
|
||||||
size_t cont_size; /*continuation message size */
|
size_t multi_size; /* Size of all the messages in the last chunk */
|
||||||
size_t multi_size = 0; /* Size of all the messages in the last chunk */
|
|
||||||
int found_null = (-1); /* Best fit null message */
|
|
||||||
alloc_info found_attr = {-1, 0, 0, 0, 0}; /* Best fit attribute message */
|
|
||||||
alloc_info found_other = {-1, 0, 0, 0, 0}; /* Best fit other message */
|
|
||||||
size_t idx; /* Message number */
|
|
||||||
uint8_t *p = NULL; /*ptr into new chunk */
|
|
||||||
H5O_cont_t *cont = NULL; /*native continuation message */
|
|
||||||
unsigned chunkno; /* Chunk allocated */
|
|
||||||
haddr_t new_chunk_addr;
|
|
||||||
unsigned u; /* Local index variable */
|
unsigned u; /* Local index variable */
|
||||||
herr_t ret_value = SUCCEED; /* Return value */
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
FUNC_ENTER_NOAPI_NOINIT
|
FUNC_ENTER_STATIC
|
||||||
|
|
||||||
/* check args */
|
/* Check args */
|
||||||
|
HDassert(f);
|
||||||
HDassert(oh);
|
HDassert(oh);
|
||||||
HDassert(size > 0);
|
HDassert(size);
|
||||||
size = H5O_ALIGN_OH(oh, size);
|
HDassert(*size > 0);
|
||||||
|
HDassert(found_msg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the smallest null message that will hold an object
|
* Find the smallest message that could be moved to make room for the
|
||||||
* continuation message. Failing that, find the smallest message
|
* continuation message.
|
||||||
* that could be moved to make room for the continuation message.
|
|
||||||
*
|
*
|
||||||
* Don't ever move continuation message from one chunk to another.
|
* Don't ever move continuation message from one chunk to another.
|
||||||
*
|
*
|
||||||
@ -787,23 +767,10 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
cont_size = H5O_ALIGN_OH(oh, (size_t)(H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f)));
|
cont_size = H5O_ALIGN_OH(oh, (size_t)(H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f)));
|
||||||
|
multi_size = 0;
|
||||||
for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
|
for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
|
||||||
if(curr_msg->type->id == H5O_NULL_ID) {
|
|
||||||
if(cont_size == curr_msg->raw_size) {
|
|
||||||
found_null = (int)u;
|
|
||||||
break;
|
|
||||||
} /* end if */
|
|
||||||
else if(curr_msg->raw_size > cont_size &&
|
|
||||||
(found_null < 0 || curr_msg->raw_size < oh->mesg[found_null].raw_size))
|
|
||||||
found_null = (int)u;
|
|
||||||
} /* end if */
|
|
||||||
else if(curr_msg->type->id == H5O_CONT_ID) {
|
|
||||||
/* Don't consider continuation messages (for now) */
|
/* Don't consider continuation messages (for now) */
|
||||||
} /* end if */
|
if(H5O_CONT_ID != curr_msg->type->id) {
|
||||||
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 */
|
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 */
|
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 */
|
||||||
uint8_t *end_msg = curr_msg->raw + curr_msg->raw_size; /* End of current message */
|
uint8_t *end_msg = curr_msg->raw + curr_msg->raw_size; /* End of current message */
|
||||||
@ -837,34 +804,51 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
|
|
||||||
/* Check if message is large enough to hold continuation info */
|
/* Check if message is large enough to hold continuation info */
|
||||||
if(total_size >= cont_size) {
|
if(total_size >= cont_size) {
|
||||||
if(curr_msg->type->id == H5O_ATTR_ID) {
|
hbool_t better = FALSE; /* Whether the current message is better than a previous one */
|
||||||
if(found_attr.msgno < 0 || total_size < found_attr.total_size) {
|
|
||||||
found_attr.msgno = (int)u;
|
/* Check for first message that can be moved */
|
||||||
found_attr.gap_size = gap_size;
|
if(found_msg->msgno < 0)
|
||||||
found_attr.null_size = null_size;
|
better = TRUE;
|
||||||
found_attr.total_size = total_size;
|
|
||||||
found_attr.null_msgno = null_msgno;
|
|
||||||
} /* end if */
|
|
||||||
} /* end if */
|
|
||||||
else {
|
else {
|
||||||
if(found_other.msgno < 0 || total_size < found_other.total_size) {
|
/* Prioritize moving non-attributes above attributes */
|
||||||
found_other.msgno = (int)u;
|
/* (Even attributes with an otherwise better fit */
|
||||||
found_other.gap_size = gap_size;
|
if(found_msg->id == H5O_ATTR_ID && curr_msg->type->id != H5O_ATTR_ID)
|
||||||
found_other.null_size = null_size;
|
better = TRUE;
|
||||||
found_other.total_size = total_size;
|
/* Either two attributes, or two non-attributes */
|
||||||
found_other.null_msgno = null_msgno;
|
else {
|
||||||
} /* end if */
|
/* Take a smaller one */
|
||||||
|
if(total_size < found_msg->total_size)
|
||||||
|
better = TRUE;
|
||||||
|
/* If they are the same size, choose the earliest one
|
||||||
|
* in the chunk array */
|
||||||
|
/* (Could also bias toward message earlier / later
|
||||||
|
* chunk in, but shouldn't be a big deal - QAK, 2016/10/21)
|
||||||
|
*/
|
||||||
|
else if(total_size == found_msg->total_size) {
|
||||||
|
if(msg_chunkno < found_msg->chunkno)
|
||||||
|
better = TRUE;
|
||||||
|
} /* end else-if */
|
||||||
} /* end else */
|
} /* end else */
|
||||||
|
} /* end else */
|
||||||
|
|
||||||
|
/* If we found a better message, keep its info */
|
||||||
|
if(better) {
|
||||||
|
found_msg->msgno = (int)u;
|
||||||
|
found_msg->id = curr_msg->type->id;
|
||||||
|
found_msg->chunkno = msg_chunkno;
|
||||||
|
found_msg->gap_size = gap_size;
|
||||||
|
found_msg->null_size = null_size;
|
||||||
|
found_msg->total_size = total_size;
|
||||||
|
found_msg->null_msgno = null_msgno;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
else if(found_null < 0 && found_attr.msgno < 0 && found_other.msgno < 0 && msg_chunkno == oh->nchunks - 1)
|
} /* end if */
|
||||||
|
else if(found_msg->msgno < 0 && msg_chunkno == oh->nchunks - 1)
|
||||||
/* Keep track of the total size of smaller messages in the last
|
/* Keep track of the total size of smaller messages in the last
|
||||||
* chunk, in case we need to move more than 1 message.
|
* chunk, in case we need to move more than 1 message.
|
||||||
*/
|
*/
|
||||||
multi_size += curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
|
multi_size += curr_msg->raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
|
||||||
} /* end else */
|
} /* end if */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
if(found_null >= 0 || found_attr.msgno >= 0 || found_other.msgno >= 0)
|
|
||||||
multi_size = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we must move some other message to make room for the null
|
* If we must move some other message to make room for the null
|
||||||
@ -876,17 +860,56 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
* If all else fails, move every message in the last chunk.
|
* If all else fails, move every message in the last chunk.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if(multi_size == 0) {
|
if(found_msg->msgno < 0)
|
||||||
if(found_null < 0) {
|
*size += multi_size;
|
||||||
if(found_other.msgno < 0)
|
|
||||||
found_other = found_attr;
|
|
||||||
|
|
||||||
HDassert(found_other.msgno >= 0);
|
|
||||||
size += (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other.msgno].raw_size;
|
|
||||||
} /* end if */
|
|
||||||
} /* end if */
|
|
||||||
else
|
else
|
||||||
size += multi_size;
|
*size += (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_msg->msgno].raw_size;
|
||||||
|
|
||||||
|
done:
|
||||||
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
|
} /* H5O__alloc_find_best_nonnull() */
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Function: H5O__alloc_chunk
|
||||||
|
*
|
||||||
|
* Purpose: Allocates and initializes a new chunk for the object header,
|
||||||
|
* including file space.
|
||||||
|
*
|
||||||
|
* Return: Success: SUCCEED, with chunk number for the
|
||||||
|
* new chunk and a pointer to the location in its
|
||||||
|
* image where the first message should be placed.
|
||||||
|
*
|
||||||
|
* Failure: Negative
|
||||||
|
*
|
||||||
|
* Programmer: Quincey Koziol
|
||||||
|
* koziol@lbl.gov
|
||||||
|
* Oct 21 2016
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
herr_t
|
||||||
|
H5O__alloc_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size,
|
||||||
|
size_t found_null, const H5O_msg_alloc_info_t *found_msg, size_t *new_idx)
|
||||||
|
{
|
||||||
|
H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
|
||||||
|
H5O_chunk_proxy_t *chk_proxy; /* Chunk that message is in */
|
||||||
|
size_t cont_size; /*continuation message size */
|
||||||
|
size_t idx; /* Message number */
|
||||||
|
uint8_t *p = NULL; /* Pointer into new chunk image */
|
||||||
|
H5O_cont_t *cont = NULL; /*native continuation message */
|
||||||
|
unsigned chunkno; /* Chunk allocated */
|
||||||
|
haddr_t new_chunk_addr; /* Address of new chunk in file */
|
||||||
|
unsigned u; /* Local index variable */
|
||||||
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
|
FUNC_ENTER_PACKAGE
|
||||||
|
|
||||||
|
/* check args */
|
||||||
|
HDassert(f);
|
||||||
|
HDassert(oh);
|
||||||
|
HDassert(found_msg);
|
||||||
|
HDassert(new_idx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The total chunk size must include the requested space plus enough
|
* The total chunk size must include the requested space plus enough
|
||||||
@ -944,7 +967,9 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "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 */
|
/* Check if we need to move multiple messages, in order to make room for the new message */
|
||||||
if(multi_size > 0) {
|
cont_size = H5O_ALIGN_OH(oh, (size_t)(H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f)));
|
||||||
|
if(found_null >= oh->nmesgs) {
|
||||||
|
if(found_msg->msgno < 0) {
|
||||||
/* Move all non-null messages in the last chunk to the new chunk. This
|
/* 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
|
* should be extremely rare so we don't care too much about minimizing
|
||||||
* the space used.
|
* the space used.
|
||||||
@ -982,7 +1007,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
} /* end if */
|
} /* end if */
|
||||||
|
|
||||||
/* Create a null message spanning the entire last chunk */
|
/* Create a null message spanning the entire last chunk */
|
||||||
found_null = (int)oh->nmesgs++;
|
found_null = oh->nmesgs++;
|
||||||
null_msg = &(oh->mesg[found_null]);
|
null_msg = &(oh->mesg[found_null]);
|
||||||
null_msg->type = H5O_MSG_NULL;
|
null_msg->type = H5O_MSG_NULL;
|
||||||
null_msg->dirty = TRUE;
|
null_msg->dirty = TRUE;
|
||||||
@ -1003,57 +1028,58 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
/* Release chunk, marking it dirty */
|
/* Release chunk, marking it dirty */
|
||||||
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, TRUE) < 0)
|
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, TRUE) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||||
} else if(found_null < 0) {
|
} /* end if */
|
||||||
|
else {
|
||||||
/* Move message (that will be replaced with continuation message)
|
/* Move message (that will be replaced with continuation message)
|
||||||
* to new chunk, if necessary.
|
* to new chunk, if necessary.
|
||||||
*/
|
*/
|
||||||
H5O_mesg_t *null_msg; /* Pointer to new null message */
|
H5O_mesg_t *null_msg; /* Pointer to new null message */
|
||||||
|
|
||||||
/* Protect chunk */
|
/* Protect chunk */
|
||||||
if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, oh->mesg[found_other.msgno].chunkno)))
|
if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, oh->mesg[found_msg->msgno].chunkno)))
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "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 */
|
/* Create null message for space that message to copy currently occupies */
|
||||||
found_null = (int)oh->nmesgs++;
|
found_null = oh->nmesgs++;
|
||||||
null_msg = &(oh->mesg[found_null]);
|
null_msg = &(oh->mesg[found_null]);
|
||||||
null_msg->type = H5O_MSG_NULL;
|
null_msg->type = H5O_MSG_NULL;
|
||||||
null_msg->native = NULL;
|
null_msg->native = NULL;
|
||||||
null_msg->raw = oh->mesg[found_other.msgno].raw;
|
null_msg->raw = oh->mesg[found_msg->msgno].raw;
|
||||||
null_msg->raw_size = oh->mesg[found_other.msgno].raw_size;
|
null_msg->raw_size = oh->mesg[found_msg->msgno].raw_size;
|
||||||
null_msg->chunkno = oh->mesg[found_other.msgno].chunkno;
|
null_msg->chunkno = oh->mesg[found_msg->msgno].chunkno;
|
||||||
|
|
||||||
/* Copy the message to move (& its prefix) to its new location */
|
/* Copy the message to move (& its prefix) to its new location */
|
||||||
HDmemcpy(p, oh->mesg[found_other.msgno].raw - H5O_SIZEOF_MSGHDR_OH(oh),
|
HDmemcpy(p, oh->mesg[found_msg->msgno].raw - H5O_SIZEOF_MSGHDR_OH(oh),
|
||||||
oh->mesg[found_other.msgno].raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh));
|
oh->mesg[found_msg->msgno].raw_size + (size_t)H5O_SIZEOF_MSGHDR_OH(oh));
|
||||||
|
|
||||||
/* Switch moved message to point to new location */
|
/* Switch moved message to point to new location */
|
||||||
oh->mesg[found_other.msgno].raw = p + H5O_SIZEOF_MSGHDR_OH(oh);
|
oh->mesg[found_msg->msgno].raw = p + H5O_SIZEOF_MSGHDR_OH(oh);
|
||||||
oh->mesg[found_other.msgno].chunkno = chunkno;
|
oh->mesg[found_msg->msgno].chunkno = chunkno;
|
||||||
|
|
||||||
/* Account for copied message in new chunk */
|
/* Account for copied message in new chunk */
|
||||||
p += (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other.msgno].raw_size;
|
p += (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_msg->msgno].raw_size;
|
||||||
size -= (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_other.msgno].raw_size;
|
size -= (size_t)H5O_SIZEOF_MSGHDR_OH(oh) + oh->mesg[found_msg->msgno].raw_size;
|
||||||
|
|
||||||
/* Add any available space after the message to move to the new null message */
|
/* Add any available space after the message to move to the new null message */
|
||||||
if(found_other.gap_size > 0) {
|
if(found_msg->gap_size > 0) {
|
||||||
/* Absorb a gap after the moved message */
|
/* Absorb a gap after the moved message */
|
||||||
HDassert(oh->chunk[null_msg->chunkno].gap == found_other.gap_size);
|
HDassert(oh->chunk[null_msg->chunkno].gap == found_msg->gap_size);
|
||||||
null_msg->raw_size += found_other.gap_size;
|
null_msg->raw_size += found_msg->gap_size;
|
||||||
oh->chunk[null_msg->chunkno].gap = 0;
|
oh->chunk[null_msg->chunkno].gap = 0;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
else if(found_other.null_size > 0) {
|
else if(found_msg->null_size > 0) {
|
||||||
H5O_mesg_t *old_null_msg = &oh->mesg[found_other.null_msgno]; /* Pointer to NULL message to eliminate */
|
H5O_mesg_t *old_null_msg = &oh->mesg[found_msg->null_msgno]; /* Pointer to NULL message to eliminate */
|
||||||
|
|
||||||
/* Absorb a null message after the moved message */
|
/* Absorb a null message after the moved message */
|
||||||
HDassert((null_msg->raw + null_msg->raw_size) == (old_null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)));
|
HDassert((null_msg->raw + null_msg->raw_size) == (old_null_msg->raw - H5O_SIZEOF_MSGHDR_OH(oh)));
|
||||||
null_msg->raw_size += found_other.null_size;
|
null_msg->raw_size += found_msg->null_size;
|
||||||
|
|
||||||
/* Release any information/memory for message */
|
/* Release any information/memory for message */
|
||||||
H5O_msg_free_mesg(old_null_msg);
|
H5O_msg_free_mesg(old_null_msg);
|
||||||
|
|
||||||
/* Remove null message from list of messages */
|
/* Remove null message from list of messages */
|
||||||
if(found_other.null_msgno < (oh->nmesgs - 1))
|
if(found_msg->null_msgno < (oh->nmesgs - 1))
|
||||||
HDmemmove(old_null_msg, old_null_msg + 1, ((oh->nmesgs - 1) - found_other.null_msgno) * sizeof(H5O_mesg_t));
|
HDmemmove(old_null_msg, old_null_msg + 1, ((oh->nmesgs - 1) - found_msg->null_msgno) * sizeof(H5O_mesg_t));
|
||||||
|
|
||||||
/* Decrement # of messages */
|
/* Decrement # of messages */
|
||||||
/* (Don't bother reducing size of message array for now -QAK) */
|
/* (Don't bother reducing size of message array for now -QAK) */
|
||||||
@ -1070,7 +1096,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, TRUE) < 0)
|
if(H5O_chunk_unprotect(f, dxpl_id, chk_proxy, TRUE) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header chunk")
|
||||||
} /* end if */
|
} /* end if */
|
||||||
HDassert(found_null >= 0);
|
} /* end if */
|
||||||
|
|
||||||
/* Create null message for [rest of] space in new chunk */
|
/* Create null message for [rest of] space in new chunk */
|
||||||
/* (account for chunk's magic # & checksum) */
|
/* (account for chunk's magic # & checksum) */
|
||||||
@ -1083,7 +1109,7 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
oh->mesg[idx].chunkno = chunkno;
|
oh->mesg[idx].chunkno = chunkno;
|
||||||
|
|
||||||
/* Insert the new chunk into the cache */
|
/* Insert the new chunk into the cache */
|
||||||
if(H5O_chunk_add(f, dxpl_id, oh, chunkno) < 0)
|
if(H5O_chunk_add(f, dxpl_id, oh, chunkno, oh->mesg[found_null].chunkno) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "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 */
|
/* Initialize the continuation information */
|
||||||
@ -1094,16 +1120,168 @@ H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new
|
|||||||
cont->chunkno = chunkno;
|
cont->chunkno = chunkno;
|
||||||
|
|
||||||
/* Split the null message and point at continuation message */
|
/* Split the null message and point at continuation message */
|
||||||
if(H5O_alloc_null(f, dxpl_id, oh, (size_t)found_null, H5O_MSG_CONT, cont, cont_size) < 0)
|
if(H5O_alloc_null(f, dxpl_id, oh, found_null, H5O_MSG_CONT, cont, cont_size) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't split null message")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't split null message")
|
||||||
|
|
||||||
/* Set new message index value */
|
/* Set new message index value */
|
||||||
*new_idx = idx;
|
*new_idx = idx;
|
||||||
|
|
||||||
|
done:
|
||||||
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
|
} /* H5O__alloc_chunk() */
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Function: H5O_alloc_new_chunk
|
||||||
|
*
|
||||||
|
* Purpose: Allocates a new chunk for the object header, including
|
||||||
|
* file space.
|
||||||
|
*
|
||||||
|
* One of the other chunks will get an object continuation
|
||||||
|
* message. If there isn't room in any other chunk for the
|
||||||
|
* object continuation message, then some message from
|
||||||
|
* another chunk is moved into this chunk to make room.
|
||||||
|
*
|
||||||
|
* SIZE need not be aligned.
|
||||||
|
*
|
||||||
|
* Note: The algorithm for finding a message to replace with a
|
||||||
|
* continuation message is still fairly limited. It's possible
|
||||||
|
* that two (or more) messages smaller than a continuation message
|
||||||
|
* might occupy a chunk and need to be moved in order to make
|
||||||
|
* room for the continuation message.
|
||||||
|
*
|
||||||
|
* Also, we aren't checking for NULL messages in front of another
|
||||||
|
* message right now...
|
||||||
|
*
|
||||||
|
* Return: Success: Index number of the null message for the
|
||||||
|
* new chunk. The null message will be at
|
||||||
|
* least SIZE bytes not counting the message
|
||||||
|
* ID or size fields.
|
||||||
|
*
|
||||||
|
* Failure: Negative
|
||||||
|
*
|
||||||
|
* Programmer: Robb Matzke
|
||||||
|
* matzke@llnl.gov
|
||||||
|
* Aug 7 1997
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static herr_t
|
||||||
|
H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size, size_t *new_idx)
|
||||||
|
{
|
||||||
|
size_t cont_size; /*continuation message size */
|
||||||
|
size_t idx; /* Message number */
|
||||||
|
H5O_msg_alloc_info_t found_msg; /* Best fit non-null message */
|
||||||
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
|
FUNC_ENTER_NOAPI_NOINIT
|
||||||
|
|
||||||
|
/* check args */
|
||||||
|
HDassert(oh);
|
||||||
|
HDassert(size > 0);
|
||||||
|
size = H5O_ALIGN_OH(oh, size);
|
||||||
|
|
||||||
|
/* Find the smallest null message that could hold a continuation message */
|
||||||
|
idx = oh->nmesgs;
|
||||||
|
cont_size = H5O_ALIGN_OH(oh, (size_t)(H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f)));
|
||||||
|
if(H5O__alloc_find_best_null(oh, cont_size, &idx) < 0)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "error while locating best null header message")
|
||||||
|
|
||||||
|
/* If we couldn't find a null message, locate the best message to move to new chunk */
|
||||||
|
if(idx >= oh->nmesgs) {
|
||||||
|
found_msg.msgno = -1;
|
||||||
|
if(H5O__alloc_find_best_nonnull(f, oh, &size, &found_msg) < 0)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "error while locating best non-null header message")
|
||||||
|
} /* end if */
|
||||||
|
|
||||||
|
/* Allocate and initialize new chunk in the file */
|
||||||
|
if(H5O__alloc_chunk(f, dxpl_id, oh, size, idx, &found_msg, new_idx) < 0)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "can't allocate new object header chunk")
|
||||||
|
|
||||||
done:
|
done:
|
||||||
FUNC_LEAVE_NOAPI(ret_value)
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
} /* H5O_alloc_new_chunk() */
|
} /* H5O_alloc_new_chunk() */
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Function: H5O__alloc_find_best_null
|
||||||
|
*
|
||||||
|
* Purpose: Find the best fit null message for a given size of message
|
||||||
|
* to allocate.
|
||||||
|
*
|
||||||
|
* Return: Non-negative on success/Negative on failure
|
||||||
|
*
|
||||||
|
* Programmer: Quincey Koziol
|
||||||
|
* koziol@lbl.gov
|
||||||
|
* Oct 21 2016
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static herr_t
|
||||||
|
H5O__alloc_find_best_null(const H5O_t *oh, size_t size, size_t *mesg_idx)
|
||||||
|
{
|
||||||
|
size_t idx; /* Index of message which fits allocation */
|
||||||
|
int found_null; /* Best fit null message */
|
||||||
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
|
FUNC_ENTER_STATIC
|
||||||
|
|
||||||
|
/* check args */
|
||||||
|
HDassert(oh);
|
||||||
|
HDassert(size > 0);
|
||||||
|
HDassert(mesg_idx);
|
||||||
|
|
||||||
|
/* Find the smallest null message that could hold the new object header message */
|
||||||
|
found_null = -1;
|
||||||
|
for(idx = 0; idx < oh->nmesgs; idx++) {
|
||||||
|
if(H5O_NULL_ID == oh->mesg[idx].type->id) {
|
||||||
|
/* If we found an exact fit, use it */
|
||||||
|
if(oh->mesg[idx].raw_size == size) {
|
||||||
|
/* Keep first exact fit */
|
||||||
|
if(found_null < 0)
|
||||||
|
found_null = idx;
|
||||||
|
else
|
||||||
|
/* If we've got more than one exact fit, choose the one in the earliest chunk */
|
||||||
|
if(oh->mesg[idx].chunkno < oh->mesg[found_null].chunkno) {
|
||||||
|
found_null = idx;
|
||||||
|
|
||||||
|
/* If we found an exact fit in object header chunk #0, we can get out */
|
||||||
|
/* (Could extend this to look for earliest message in
|
||||||
|
* chunk #0 - QAK, 2016/10/21)
|
||||||
|
*/
|
||||||
|
if(0 == oh->mesg[idx].chunkno)
|
||||||
|
break;
|
||||||
|
} /* end if */
|
||||||
|
} /* end if */
|
||||||
|
/* Look for null message that's larger than needed */
|
||||||
|
else if(oh->mesg[idx].raw_size > size) {
|
||||||
|
/* Keep first one found */
|
||||||
|
if(found_null < 0)
|
||||||
|
found_null = idx;
|
||||||
|
else
|
||||||
|
/* Check for better fit */
|
||||||
|
if(oh->mesg[idx].raw_size < oh->mesg[found_null].raw_size)
|
||||||
|
found_null = idx;
|
||||||
|
else {
|
||||||
|
/* If they are the same size, choose the one in the earliest chunk */
|
||||||
|
if(oh->mesg[idx].raw_size == oh->mesg[found_null].raw_size) {
|
||||||
|
if(oh->mesg[idx].chunkno < oh->mesg[found_null].chunkno)
|
||||||
|
found_null = idx;
|
||||||
|
} /* end if */
|
||||||
|
} /* end else */
|
||||||
|
} /* end else-if */
|
||||||
|
/* Ignore too-small null messages */
|
||||||
|
else
|
||||||
|
;
|
||||||
|
} /* end if */
|
||||||
|
} /* end for */
|
||||||
|
if(found_null >= 0)
|
||||||
|
*mesg_idx = found_null;
|
||||||
|
|
||||||
|
done:
|
||||||
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
|
} /* H5O__alloc_find_best_null() */
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
* Function: H5O_alloc
|
* Function: H5O_alloc
|
||||||
@ -1143,10 +1321,10 @@ H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
|
|||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "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);
|
aligned_size = H5O_ALIGN_OH(oh, raw_size);
|
||||||
|
|
||||||
/* look for a null message which is large enough */
|
/* Find the smallest null message that could hold the new object header message */
|
||||||
for(idx = 0; idx < oh->nmesgs; idx++)
|
idx = oh->nmesgs;
|
||||||
if(H5O_NULL_ID == oh->mesg[idx].type->id && oh->mesg[idx].raw_size >= aligned_size)
|
if(H5O__alloc_find_best_null(oh, aligned_size, &idx) < 0)
|
||||||
break;
|
HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "error while locating best null header message")
|
||||||
|
|
||||||
/* if we didn't find one, then allocate more header space */
|
/* if we didn't find one, then allocate more header space */
|
||||||
if(idx >= oh->nmesgs) {
|
if(idx >= oh->nmesgs) {
|
||||||
@ -1307,12 +1485,6 @@ H5O_move_cont(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned cont_u)
|
|||||||
nonnull_size = 0;
|
nonnull_size = 0;
|
||||||
for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++) {
|
for(v = 0, curr_msg = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg++) {
|
||||||
if(curr_msg->chunkno == deleted_chunkno) {
|
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 */
|
/* Find size of all non-null messages in the chunk pointed to by the continuation message */
|
||||||
if(curr_msg->type->id != H5O_NULL_ID) {
|
if(curr_msg->type->id != H5O_NULL_ID) {
|
||||||
HDassert(curr_msg->type->id != H5O_CONT_ID);
|
HDassert(curr_msg->type->id != H5O_CONT_ID);
|
||||||
@ -1552,8 +1724,6 @@ H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
|||||||
} /* end else-if */
|
} /* end else-if */
|
||||||
} /* end if */
|
} /* end if */
|
||||||
|
|
||||||
/* 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 */
|
/* 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++) {
|
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
|
if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
|
||||||
@ -1697,7 +1867,6 @@ H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
|||||||
break;
|
break;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
} /* end if */
|
|
||||||
|
|
||||||
/* If we packed messages, get out of loop and start over */
|
/* 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) */
|
/* (Don't know if this has any benefit one way or the other -QAK) */
|
||||||
@ -1715,10 +1884,14 @@ H5O_move_msgs_forward(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
|
|||||||
ret_value = (htri_t)did_packing;
|
ret_value = (htri_t)did_packing;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if(ret_value < 0) {
|
||||||
if(null_chk_proxy && H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_dirtied) < 0)
|
if(null_chk_proxy && H5O_chunk_unprotect(f, dxpl_id, null_chk_proxy, null_chk_dirtied) < 0)
|
||||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect null object header chunk")
|
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect null object header chunk")
|
||||||
if(curr_chk_proxy && H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_dirtied) < 0)
|
if(curr_chk_proxy && H5O_chunk_unprotect(f, dxpl_id, curr_chk_proxy, curr_chk_dirtied) < 0)
|
||||||
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect current object header chunk")
|
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect current object header chunk")
|
||||||
|
} /* end if */
|
||||||
|
else
|
||||||
|
HDassert(!null_chk_proxy && !curr_chk_proxy);
|
||||||
|
|
||||||
FUNC_LEAVE_NOAPI(ret_value)
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
} /* H5O_move_msgs_forward() */
|
} /* H5O_move_msgs_forward() */
|
||||||
|
315
src/H5Ocache.c
315
src/H5Ocache.c
@ -88,9 +88,6 @@ static herr_t H5O__cache_chk_serialize(const H5F_t *f, void *image, size_t len,
|
|||||||
static herr_t H5O__cache_chk_free_icr(void *thing);
|
static herr_t H5O__cache_chk_free_icr(void *thing);
|
||||||
static herr_t H5O__cache_chk_clear(const H5F_t *f, void *thing, hbool_t about_to_destroy);
|
static herr_t H5O__cache_chk_clear(const H5F_t *f, void *thing, hbool_t about_to_destroy);
|
||||||
|
|
||||||
/* Chunk proxy routines */
|
|
||||||
static herr_t H5O__chunk_proxy_dest(H5O_chunk_proxy_t *chunk_proxy);
|
|
||||||
|
|
||||||
/* Chunk routines */
|
/* Chunk routines */
|
||||||
static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len,
|
static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len,
|
||||||
const uint8_t *image, H5O_common_cache_ud_t *udata, hbool_t *dirty);
|
const uint8_t *image, H5O_common_cache_ud_t *udata, hbool_t *dirty);
|
||||||
@ -99,6 +96,7 @@ static herr_t H5O__chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno);
|
|||||||
/* Misc. routines */
|
/* Misc. routines */
|
||||||
static herr_t H5O__add_cont_msg(H5O_cont_msgs_t *cont_msg_info,
|
static herr_t H5O__add_cont_msg(H5O_cont_msgs_t *cont_msg_info,
|
||||||
const H5O_cont_t *cont);
|
const H5O_cont_t *cont);
|
||||||
|
static herr_t H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata);
|
||||||
|
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
@ -158,6 +156,149 @@ H5FL_SEQ_DEFINE(H5O_cont_t);
|
|||||||
/* Local Variables */
|
/* Local Variables */
|
||||||
/*******************/
|
/*******************/
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Function: H5O_decode_prefix
|
||||||
|
*
|
||||||
|
* Purpose: To decode the object header prefix.
|
||||||
|
* The coding is extracted fromt H5O__cache_deserialize() to this routine.
|
||||||
|
*
|
||||||
|
* Return: Non-negative on success/Negative on failure
|
||||||
|
*
|
||||||
|
* Programmer: Vailin Choi; Aug 2015
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static herr_t
|
||||||
|
H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata)
|
||||||
|
{
|
||||||
|
H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
|
||||||
|
const uint8_t *p = buf; /* Pointer into buffer to decode */
|
||||||
|
size_t prefix_size; /* Size of object header prefix */
|
||||||
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
|
FUNC_ENTER_NOAPI_NOINIT
|
||||||
|
|
||||||
|
/* Check arguments */
|
||||||
|
HDassert(f);
|
||||||
|
HDassert(oh);
|
||||||
|
HDassert(buf);
|
||||||
|
HDassert(udata);
|
||||||
|
|
||||||
|
/* Check for presence of magic number */
|
||||||
|
/* (indicates version 2 or later) */
|
||||||
|
if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
|
||||||
|
/* Magic number */
|
||||||
|
p += H5_SIZEOF_MAGIC;
|
||||||
|
|
||||||
|
/* Version */
|
||||||
|
oh->version = *p++;
|
||||||
|
if(H5O_VERSION_2 != oh->version)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
oh->flags = *p++;
|
||||||
|
if(oh->flags & ~H5O_HDR_ALL_FLAGS)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unknown object header status flag(s)")
|
||||||
|
|
||||||
|
/* Number of links to object (unless overridden by refcount message) */
|
||||||
|
oh->nlink = 1;
|
||||||
|
|
||||||
|
/* Time fields */
|
||||||
|
if(oh->flags & H5O_HDR_STORE_TIMES) {
|
||||||
|
uint32_t tmp; /* Temporary value */
|
||||||
|
|
||||||
|
UINT32DECODE(p, tmp);
|
||||||
|
oh->atime = (time_t)tmp;
|
||||||
|
UINT32DECODE(p, tmp);
|
||||||
|
oh->mtime = (time_t)tmp;
|
||||||
|
UINT32DECODE(p, tmp);
|
||||||
|
oh->ctime = (time_t)tmp;
|
||||||
|
UINT32DECODE(p, tmp);
|
||||||
|
oh->btime = (time_t)tmp;
|
||||||
|
} /* end if */
|
||||||
|
else
|
||||||
|
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
|
||||||
|
|
||||||
|
/* Attribute fields */
|
||||||
|
if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
|
||||||
|
UINT16DECODE(p, oh->max_compact);
|
||||||
|
UINT16DECODE(p, oh->min_dense);
|
||||||
|
if(oh->max_compact < oh->min_dense)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header attribute phase change values")
|
||||||
|
} /* end if */
|
||||||
|
else {
|
||||||
|
oh->max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF;
|
||||||
|
oh->min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF;
|
||||||
|
} /* end else */
|
||||||
|
|
||||||
|
/* First chunk size */
|
||||||
|
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
|
||||||
|
case 0: /* 1 byte size */
|
||||||
|
oh->chunk0_size = *p++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* 2 byte size */
|
||||||
|
UINT16DECODE(p, oh->chunk0_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* 4 byte size */
|
||||||
|
UINT32DECODE(p, oh->chunk0_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* 8 byte size */
|
||||||
|
UINT64DECODE(p, oh->chunk0_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad size for chunk 0")
|
||||||
|
} /* end switch */
|
||||||
|
if(oh->chunk0_size > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh))
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header chunk size")
|
||||||
|
} /* end if */
|
||||||
|
else {
|
||||||
|
/* Version */
|
||||||
|
oh->version = *p++;
|
||||||
|
if(H5O_VERSION_1 != oh->version)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, FAIL, "bad object header version number")
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
oh->flags = H5O_CRT_OHDR_FLAGS_DEF;
|
||||||
|
|
||||||
|
/* Reserved */
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* Number of messages */
|
||||||
|
UINT16DECODE(p, udata->v1_pfx_nmesgs);
|
||||||
|
|
||||||
|
/* Link count */
|
||||||
|
UINT32DECODE(p, oh->nlink);
|
||||||
|
|
||||||
|
/* Reset unused time fields */
|
||||||
|
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
|
||||||
|
|
||||||
|
/* Reset unused attribute fields */
|
||||||
|
oh->max_compact = 0;
|
||||||
|
oh->min_dense = 0;
|
||||||
|
|
||||||
|
/* First chunk size */
|
||||||
|
UINT32DECODE(p, oh->chunk0_size);
|
||||||
|
if((udata->v1_pfx_nmesgs > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) ||
|
||||||
|
(udata->v1_pfx_nmesgs == 0 && oh->chunk0_size > 0))
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "bad object header chunk size")
|
||||||
|
|
||||||
|
/* Reserved, in version 1 (for 8-byte alignment padding) */
|
||||||
|
p += 4;
|
||||||
|
} /* end else */
|
||||||
|
|
||||||
|
/* Determine object header prefix length */
|
||||||
|
prefix_size = (size_t)(p - buf);
|
||||||
|
HDassert((size_t)prefix_size == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
|
||||||
|
|
||||||
|
done:
|
||||||
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
|
} /* H5O_decode_prefix() */
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
* Function: H5O__cache_get_load_size()
|
* Function: H5O__cache_get_load_size()
|
||||||
@ -216,7 +357,6 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
|
|||||||
H5O_t *oh = NULL; /* Object header read in */
|
H5O_t *oh = NULL; /* Object header read in */
|
||||||
H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
|
H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
|
||||||
const uint8_t *image = (const uint8_t *)_image; /* Pointer into buffer to decode */
|
const uint8_t *image = (const uint8_t *)_image; /* Pointer into buffer to decode */
|
||||||
size_t prefix_size; /* Size of object header prefix */
|
|
||||||
size_t buf_size; /* Size of prefix+chunk #0 buffer */
|
size_t buf_size; /* Size of prefix+chunk #0 buffer */
|
||||||
void * ret_value = NULL; /* Return value */
|
void * ret_value = NULL; /* Return value */
|
||||||
|
|
||||||
@ -238,122 +378,14 @@ H5O__cache_deserialize(const void *_image, size_t len, void *_udata,
|
|||||||
oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f);
|
oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f);
|
||||||
oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f);
|
oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f);
|
||||||
|
|
||||||
/* Check for presence of magic number */
|
/* Decode header prefix */
|
||||||
/* (indicates version 2 or later) */
|
if(H5O_decode_prefix(udata->common.f, oh, image, udata) < 0)
|
||||||
if(!HDmemcmp(image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) {
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header prefix")
|
||||||
/* Magic number */
|
|
||||||
image += H5_SIZEOF_MAGIC;
|
|
||||||
|
|
||||||
/* Version */
|
|
||||||
oh->version = *image++;
|
|
||||||
if(H5O_VERSION_2 != oh->version)
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")
|
|
||||||
|
|
||||||
/* Flags */
|
|
||||||
oh->flags = *image++;
|
|
||||||
if(oh->flags & ~H5O_HDR_ALL_FLAGS)
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)")
|
|
||||||
|
|
||||||
/* Number of links to object (unless overridden by refcount message) */
|
|
||||||
oh->nlink = 1;
|
|
||||||
|
|
||||||
/* Time fields */
|
|
||||||
if(oh->flags & H5O_HDR_STORE_TIMES) {
|
|
||||||
uint32_t tmp; /* Temporary value */
|
|
||||||
|
|
||||||
UINT32DECODE(image, tmp);
|
|
||||||
oh->atime = (time_t)tmp;
|
|
||||||
UINT32DECODE(image, tmp);
|
|
||||||
oh->mtime = (time_t)tmp;
|
|
||||||
UINT32DECODE(image, tmp);
|
|
||||||
oh->ctime = (time_t)tmp;
|
|
||||||
UINT32DECODE(image, tmp);
|
|
||||||
oh->btime = (time_t)tmp;
|
|
||||||
} /* end if */
|
|
||||||
else
|
|
||||||
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
|
|
||||||
|
|
||||||
/* Attribute fields */
|
|
||||||
if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) {
|
|
||||||
UINT16DECODE(image, oh->max_compact);
|
|
||||||
UINT16DECODE(image, oh->min_dense);
|
|
||||||
|
|
||||||
if(oh->max_compact < oh->min_dense)
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header attribute phase change values")
|
|
||||||
} /* end if */
|
|
||||||
else {
|
|
||||||
oh->max_compact = H5O_CRT_ATTR_MAX_COMPACT_DEF;
|
|
||||||
oh->min_dense = H5O_CRT_ATTR_MIN_DENSE_DEF;
|
|
||||||
} /* end else */
|
|
||||||
|
|
||||||
/* First chunk size */
|
|
||||||
switch(oh->flags & H5O_HDR_CHUNK0_SIZE) {
|
|
||||||
case 0: /* 1 byte size */
|
|
||||||
oh->chunk0_size = *image++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* 2 byte size */
|
|
||||||
UINT16DECODE(image, oh->chunk0_size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: /* 4 byte size */
|
|
||||||
UINT32DECODE(image, oh->chunk0_size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: /* 8 byte size */
|
|
||||||
UINT64DECODE(image, oh->chunk0_size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad size for chunk 0")
|
|
||||||
} /* end switch */
|
|
||||||
if(oh->chunk0_size > 0 && oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh))
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size")
|
|
||||||
} /* end if */
|
|
||||||
else {
|
|
||||||
/* Version */
|
|
||||||
oh->version = *image++;
|
|
||||||
if(H5O_VERSION_1 != oh->version)
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number")
|
|
||||||
|
|
||||||
/* Flags */
|
|
||||||
oh->flags = H5O_CRT_OHDR_FLAGS_DEF;
|
|
||||||
|
|
||||||
/* Reserved */
|
|
||||||
image++;
|
|
||||||
|
|
||||||
/* Number of messages */
|
|
||||||
UINT16DECODE(image, udata->v1_pfx_nmesgs);
|
|
||||||
|
|
||||||
/* Link count */
|
|
||||||
UINT32DECODE(image, oh->nlink);
|
|
||||||
|
|
||||||
/* Reset unused time fields */
|
|
||||||
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
|
|
||||||
|
|
||||||
/* Reset unused attribute fields */
|
|
||||||
oh->max_compact = 0;
|
|
||||||
oh->min_dense = 0;
|
|
||||||
|
|
||||||
/* First chunk size */
|
|
||||||
UINT32DECODE(image, oh->chunk0_size);
|
|
||||||
|
|
||||||
if((udata->v1_pfx_nmesgs > 0 &&
|
|
||||||
oh->chunk0_size < H5O_SIZEOF_MSGHDR_OH(oh)) ||
|
|
||||||
(udata->v1_pfx_nmesgs == 0 && oh->chunk0_size > 0))
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "bad object header chunk size")
|
|
||||||
|
|
||||||
/* Reserved, in version 1 (for 8-byte alignment padding) */
|
|
||||||
image += 4;
|
|
||||||
} /* end else */
|
|
||||||
|
|
||||||
/* Determine object header prefix length */
|
|
||||||
prefix_size = (size_t)(image - (const uint8_t *)_image);
|
|
||||||
HDassert((size_t)prefix_size == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)));
|
|
||||||
|
|
||||||
/* Compute the size of the buffer used */
|
/* Compute the size of the buffer used */
|
||||||
buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh);
|
buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh);
|
||||||
|
|
||||||
|
|
||||||
/* Check to see if the buffer provided is large enough to contain both
|
/* Check to see if the buffer provided is large enough to contain both
|
||||||
* the prefix and the first chunk. If it isn't, make note of the desired
|
* the prefix and the first chunk. If it isn't, make note of the desired
|
||||||
* size, but otherwise do nothing. H5C_load_entry() will notice the
|
* size, but otherwise do nothing. H5C_load_entry() will notice the
|
||||||
@ -768,32 +800,35 @@ H5O__cache_chk_deserialize(const void *image, size_t len, void *_udata,
|
|||||||
if(H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, &(udata->common), dirty) < 0)
|
if(H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, &(udata->common), dirty) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk")
|
||||||
|
|
||||||
/* Set the fields for the chunk proxy */
|
/* Set the chunk number for the chunk proxy */
|
||||||
chk_proxy->oh = udata->oh;
|
|
||||||
H5_CHECKED_ASSIGN(chk_proxy->chunkno, unsigned, udata->oh->nchunks - 1, size_t);
|
H5_CHECKED_ASSIGN(chk_proxy->chunkno, unsigned, udata->oh->nchunks - 1, size_t);
|
||||||
} /* end if */
|
} /* end if */
|
||||||
else {
|
else {
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
HDassert(udata->chunkno < udata->oh->nchunks);
|
HDassert(udata->chunkno < udata->oh->nchunks);
|
||||||
|
|
||||||
/* Set the fields for the chunk proxy */
|
/* Set the chunk number for the chunk proxy */
|
||||||
chk_proxy->oh = udata->oh;
|
|
||||||
chk_proxy->chunkno = udata->chunkno;
|
chk_proxy->chunkno = udata->chunkno;
|
||||||
|
|
||||||
/* Sanity check that the chunk representation we have in memory is
|
/* Sanity check that the chunk representation we have in memory is
|
||||||
* the same as the one being brought in from disk.
|
* the same as the one being brought in from disk.
|
||||||
*/
|
*/
|
||||||
HDassert(0 == HDmemcmp(image, chk_proxy->oh->chunk[chk_proxy->chunkno].image, chk_proxy->oh->chunk[chk_proxy->chunkno].size));
|
HDassert(0 == HDmemcmp(image, udata->oh->chunk[chk_proxy->chunkno].image, udata->oh->chunk[chk_proxy->chunkno].size));
|
||||||
} /* end else */
|
} /* end else */
|
||||||
|
|
||||||
/* Increment reference count of object header */
|
/* Increment reference count of object header */
|
||||||
if(H5O_inc_rc(udata->oh) < 0)
|
if(H5O_inc_rc(udata->oh) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
|
||||||
|
chk_proxy->oh = udata->oh;
|
||||||
|
|
||||||
/* Set return value */
|
/* Set return value */
|
||||||
ret_value = chk_proxy;
|
ret_value = chk_proxy;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
if(NULL == ret_value)
|
||||||
|
if(chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
|
||||||
|
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header chunk")
|
||||||
|
|
||||||
FUNC_LEAVE_NOAPI(ret_value)
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
} /* end H5O__cache_chk_deserialize() */
|
} /* end H5O__cache_chk_deserialize() */
|
||||||
|
|
||||||
@ -920,7 +955,7 @@ H5O__cache_chk_free_icr(void *_thing)
|
|||||||
HDassert(chk_proxy->cache_info.type == H5AC_OHDR_CHK);
|
HDassert(chk_proxy->cache_info.type == H5AC_OHDR_CHK);
|
||||||
|
|
||||||
/* Destroy object header chunk proxy */
|
/* Destroy object header chunk proxy */
|
||||||
if(H5O__chunk_proxy_dest(chk_proxy) < 0)
|
if(H5O__chunk_dest(chk_proxy) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk proxy")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk proxy")
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -1453,39 +1488,3 @@ done:
|
|||||||
FUNC_LEAVE_NOAPI(ret_value)
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
} /* H5O__chunk_serialize() */
|
} /* H5O__chunk_serialize() */
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
|
||||||
* Function: H5O__chunk_proxy_dest
|
|
||||||
*
|
|
||||||
* Purpose: Destroy a chunk proxy object
|
|
||||||
*
|
|
||||||
* Return: Success: SUCCEED
|
|
||||||
* Failure: FAIL
|
|
||||||
*
|
|
||||||
* Programmer: Quincey Koziol
|
|
||||||
* koziol@hdfgroup.org
|
|
||||||
* July 13, 2008
|
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
static herr_t
|
|
||||||
H5O__chunk_proxy_dest(H5O_chunk_proxy_t *chk_proxy)
|
|
||||||
{
|
|
||||||
herr_t ret_value = SUCCEED; /* Return value */
|
|
||||||
|
|
||||||
FUNC_ENTER_STATIC
|
|
||||||
|
|
||||||
/* Check arguments */
|
|
||||||
HDassert(chk_proxy);
|
|
||||||
|
|
||||||
/* Decrement reference count of object header */
|
|
||||||
if(chk_proxy->oh && H5O_dec_rc(chk_proxy->oh) < 0)
|
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement reference count on object header")
|
|
||||||
|
|
||||||
/* Release the chunk proxy object */
|
|
||||||
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
|
|
||||||
|
|
||||||
done:
|
|
||||||
FUNC_LEAVE_NOAPI(ret_value)
|
|
||||||
} /* H5O__chunk_proxy_dest() */
|
|
||||||
|
|
||||||
|
@ -93,7 +93,8 @@ H5FL_DEFINE(H5O_chunk_proxy_t);
|
|||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
herr_t
|
herr_t
|
||||||
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
|
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
|
||||||
|
unsigned cont_chunkno)
|
||||||
{
|
{
|
||||||
H5O_chunk_proxy_t *chk_proxy = NULL; /* Proxy for chunk, to mark it dirty in the cache */
|
H5O_chunk_proxy_t *chk_proxy = NULL; /* Proxy for chunk, to mark it dirty in the cache */
|
||||||
herr_t ret_value = SUCCEED; /* Return value */
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
@ -110,14 +111,16 @@ H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
|
|||||||
if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
|
if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
|
||||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||||
|
|
||||||
/* Set the values in the chunk proxy */
|
|
||||||
chk_proxy->oh = oh;
|
|
||||||
chk_proxy->chunkno = idx;
|
|
||||||
|
|
||||||
/* Increment reference count on object header */
|
/* Increment reference count on object header */
|
||||||
if(H5O_inc_rc(oh) < 0)
|
if(H5O_inc_rc(oh) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header")
|
||||||
|
|
||||||
|
/* Set the values in the chunk proxy */
|
||||||
|
chk_proxy->f = f;
|
||||||
|
chk_proxy->oh = oh;
|
||||||
|
chk_proxy->chunkno = idx;
|
||||||
|
chk_proxy->cont_chunkno = cont_chunkno;
|
||||||
|
|
||||||
/* Insert the chunk proxy into the cache */
|
/* Insert the chunk proxy into the cache */
|
||||||
if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0)
|
if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0)
|
||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk")
|
||||||
@ -126,8 +129,8 @@ H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
if(ret_value < 0)
|
if(ret_value < 0)
|
||||||
if(chk_proxy)
|
if(chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
|
||||||
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
|
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to destroy object header chunk")
|
||||||
|
|
||||||
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
|
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
|
||||||
} /* end H5O_chunk_add() */
|
} /* end H5O_chunk_add() */
|
||||||
@ -172,6 +175,7 @@ H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
|
|||||||
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")
|
||||||
|
|
||||||
/* Set chunk proxy fields */
|
/* Set chunk proxy fields */
|
||||||
|
chk_proxy->f = f;
|
||||||
chk_proxy->oh = oh;
|
chk_proxy->oh = oh;
|
||||||
chk_proxy->chunkno = idx;
|
chk_proxy->chunkno = idx;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
@ -200,8 +204,8 @@ H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
|
|||||||
done:
|
done:
|
||||||
/* Cleanup on error */
|
/* Cleanup on error */
|
||||||
if(!ret_value)
|
if(!ret_value)
|
||||||
if(0 == idx && chk_proxy)
|
if(0 == idx && chk_proxy && H5O__chunk_dest(chk_proxy) < 0)
|
||||||
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
|
HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "unable to destroy object header chunk")
|
||||||
|
|
||||||
FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
|
FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
|
||||||
} /* end H5O_chunk_protect() */
|
} /* end H5O_chunk_protect() */
|
||||||
@ -409,3 +413,39 @@ done:
|
|||||||
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
|
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
|
||||||
} /* end H5O_chunk_delete() */
|
} /* end H5O_chunk_delete() */
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Function: H5O__chunk_dest
|
||||||
|
*
|
||||||
|
* Purpose: Destroy a chunk proxy object
|
||||||
|
*
|
||||||
|
* Return: Success: SUCCEED
|
||||||
|
* Failure: FAIL
|
||||||
|
*
|
||||||
|
* Programmer: Quincey Koziol
|
||||||
|
* koziol@hdfgroup.org
|
||||||
|
* July 13, 2008
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
herr_t
|
||||||
|
H5O__chunk_dest(H5O_chunk_proxy_t *chk_proxy)
|
||||||
|
{
|
||||||
|
herr_t ret_value = SUCCEED; /* Return value */
|
||||||
|
|
||||||
|
FUNC_ENTER_PACKAGE
|
||||||
|
|
||||||
|
/* Check arguments */
|
||||||
|
HDassert(chk_proxy);
|
||||||
|
|
||||||
|
/* Decrement reference count of object header */
|
||||||
|
if(chk_proxy->oh && H5O_dec_rc(chk_proxy->oh) < 0)
|
||||||
|
HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement reference count on object header")
|
||||||
|
|
||||||
|
/* Release the chunk proxy object */
|
||||||
|
chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
|
||||||
|
|
||||||
|
done:
|
||||||
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
|
} /* H5O__chunk_dest() */
|
||||||
|
|
||||||
|
173
src/H5Omessage.c
173
src/H5Omessage.c
@ -2254,176 +2254,3 @@ done:
|
|||||||
FUNC_LEAVE_NOAPI(ret_value)
|
FUNC_LEAVE_NOAPI(ret_value)
|
||||||
} /* end H5O_flush_msgs() */
|
} /* 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 = -1; /* Return value */
|
|
||||||
|
|
||||||
FUNC_ENTER_NOAPI(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_ONLY_FLAG)))
|
|
||||||
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 */
|
|
||||||
H5_CHECKED_ASSIGN(ret_value, int, idx_msg->chunkno, unsigned);
|
|
||||||
|
|
||||||
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(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_ONLY_FLAG)))
|
|
||||||
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(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_ONLY_FLAG)))
|
|
||||||
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() */
|
|
||||||
|
|
||||||
|
20
src/H5Opkg.h
20
src/H5Opkg.h
@ -245,7 +245,6 @@ struct H5O_msg_class_t {
|
|||||||
struct H5O_mesg_t {
|
struct H5O_mesg_t {
|
||||||
const H5O_msg_class_t *type; /*type of message */
|
const H5O_msg_class_t *type; /*type of message */
|
||||||
hbool_t dirty; /*raw out of date wrt native */
|
hbool_t dirty; /*raw out of date wrt native */
|
||||||
hbool_t locked; /*message is locked into chunk */
|
|
||||||
uint8_t flags; /*message flags */
|
uint8_t flags; /*message flags */
|
||||||
H5O_msg_crt_idx_t crt_idx; /*message creation index */
|
H5O_msg_crt_idx_t crt_idx; /*message creation index */
|
||||||
unsigned chunkno; /*chunk number for this mesg */
|
unsigned chunkno; /*chunk number for this mesg */
|
||||||
@ -254,6 +253,17 @@ struct H5O_mesg_t {
|
|||||||
size_t raw_size; /*size with alignment */
|
size_t raw_size; /*size with alignment */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Struct for storing information about "best" message to move to new chunk */
|
||||||
|
typedef struct H5O_msg_alloc_info_t {
|
||||||
|
int msgno; /* Index in message array */
|
||||||
|
unsigned id; /* Message type ID on disk */
|
||||||
|
unsigned chunkno; /* Index in chunk array */
|
||||||
|
size_t gap_size; /* Size of any "gap" in the chunk immediately after message */
|
||||||
|
size_t null_size; /* Size of any null message in the chunk immediately after message */
|
||||||
|
size_t total_size; /* Total size of "available" space around message */
|
||||||
|
unsigned null_msgno; /* Message index of null message immediately after message */
|
||||||
|
} H5O_msg_alloc_info_t;
|
||||||
|
|
||||||
typedef struct H5O_chunk_t {
|
typedef struct H5O_chunk_t {
|
||||||
haddr_t addr; /*chunk file address */
|
haddr_t addr; /*chunk file address */
|
||||||
size_t size; /*chunk size */
|
size_t size; /*chunk size */
|
||||||
@ -369,8 +379,10 @@ typedef struct H5O_chunk_proxy_t {
|
|||||||
H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */
|
H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */
|
||||||
/* first field in structure */
|
/* first field in structure */
|
||||||
|
|
||||||
|
H5F_t *f; /* Pointer to file for object header/chunk */
|
||||||
H5O_t *oh; /* Object header for this chunk */
|
H5O_t *oh; /* Object header for this chunk */
|
||||||
unsigned chunkno; /* Chunk number for this chunk */
|
unsigned chunkno; /* Chunk number for this chunk */
|
||||||
|
unsigned cont_chunkno; /* Chunk number for the chunk containing the continuation message that points to this chunk */
|
||||||
} H5O_chunk_proxy_t;
|
} H5O_chunk_proxy_t;
|
||||||
|
|
||||||
/* Callback information for loading object header chunk from disk */
|
/* Callback information for loading object header chunk from disk */
|
||||||
@ -559,7 +571,8 @@ H5_DLL herr_t H5O_msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *t
|
|||||||
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
|
const H5O_mesg_operator_t *op, void *op_data, hid_t dxpl_id);
|
||||||
|
|
||||||
/* Object header chunk routines */
|
/* Object header chunk routines */
|
||||||
H5_DLL herr_t H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
|
H5_DLL herr_t H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
|
||||||
|
unsigned cont_chunkno);
|
||||||
H5_DLL H5O_chunk_proxy_t *H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
H5_DLL H5O_chunk_proxy_t *H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||||
unsigned idx);
|
unsigned idx);
|
||||||
H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id,
|
H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id,
|
||||||
@ -567,6 +580,7 @@ H5_DLL herr_t H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id,
|
|||||||
H5_DLL herr_t H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
|
H5_DLL herr_t H5O_chunk_update_idx(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
|
||||||
H5_DLL herr_t H5O_chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_proxy);
|
H5_DLL herr_t H5O_chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_proxy);
|
||||||
H5_DLL herr_t H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
|
H5_DLL herr_t H5O_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx);
|
||||||
|
H5_DLL herr_t H5O__chunk_dest(H5O_chunk_proxy_t *chunk_proxy);
|
||||||
|
|
||||||
/* Collect storage info for btree and heap */
|
/* Collect storage info for btree and heap */
|
||||||
H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||||
@ -574,6 +588,8 @@ H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
|||||||
|
|
||||||
/* Object header allocation routines */
|
/* Object header allocation routines */
|
||||||
H5_DLL herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
|
H5_DLL herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc);
|
||||||
|
H5_DLL herr_t H5O__alloc_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh, size_t size,
|
||||||
|
size_t found_null, const H5O_msg_alloc_info_t *found_msg, size_t *new_idx);
|
||||||
H5_DLL herr_t H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
H5_DLL herr_t H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
|
||||||
const H5O_msg_class_t *type, const void *mesg, size_t *mesg_idx);
|
const H5O_msg_class_t *type, const void *mesg, size_t *mesg_idx);
|
||||||
H5_DLL herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
|
H5_DLL herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
|
||||||
|
@ -898,9 +898,6 @@ H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
|
|||||||
unsigned type_id, const unsigned char *buf);
|
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,
|
H5_DLL herr_t H5O_msg_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
|
||||||
unsigned type_id, void *mesg);
|
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 metadata flush/refresh routines */
|
/* Object metadata flush/refresh routines */
|
||||||
H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id);
|
H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id);
|
||||||
|
142
test/ohdr.c
142
test/ohdr.c
@ -811,148 +811,6 @@ main(void)
|
|||||||
FAIL_STACK_ERROR
|
FAIL_STACK_ERROR
|
||||||
PASSED();
|
PASSED();
|
||||||
|
|
||||||
/*
|
|
||||||
* Test moving message to first chunk
|
|
||||||
*/
|
|
||||||
TESTING("locking messages");
|
|
||||||
HDmemset(&oh_loc, 0, sizeof(oh_loc));
|
|
||||||
if(H5O_create(f, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(1 != H5O_link(&oh_loc, 1, H5AC_ind_read_dxpl_id))
|
|
||||||
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, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(1 != H5O_link(&oh_loc2, 1, H5AC_ind_read_dxpl_id))
|
|
||||||
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, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
} /* end for */
|
|
||||||
|
|
||||||
/* Get # of object header chunks */
|
|
||||||
if(H5O_get_hdr_info(&oh_loc, H5AC_ind_read_dxpl_id, &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, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
|
|
||||||
/* Verify chunk index for message */
|
|
||||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(chunkno != 1)
|
|
||||||
TEST_ERROR
|
|
||||||
|
|
||||||
/* Lock the message into the chunk */
|
|
||||||
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
|
|
||||||
/* Attempt to lock the message twice */
|
|
||||||
H5E_BEGIN_TRY {
|
|
||||||
ret = H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id);
|
|
||||||
} 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, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
|
|
||||||
/* Verify chunk index for message */
|
|
||||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(chunkno != 1)
|
|
||||||
TEST_ERROR
|
|
||||||
|
|
||||||
/* Unlock the message */
|
|
||||||
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
|
|
||||||
/* Attempt to unlock the message twice */
|
|
||||||
H5E_BEGIN_TRY {
|
|
||||||
ret = H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id);
|
|
||||||
} 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, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(1 != H5O_link(&oh_loc, 1, H5AC_ind_read_dxpl_id))
|
|
||||||
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, H5AC_ind_read_dxpl_id, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(1 != H5O_link(&oh_loc2, 1, H5AC_ind_read_dxpl_id))
|
|
||||||
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, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
|
|
||||||
/* Verify chunk index for message */
|
|
||||||
if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id)) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(chunkno != 0)
|
|
||||||
TEST_ERROR
|
|
||||||
|
|
||||||
/* Lock the message into the chunk */
|
|
||||||
if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 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, H5AC_ind_read_dxpl_id) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
} /* end for */
|
|
||||||
|
|
||||||
/* Get # of object header chunks */
|
|
||||||
if(H5O_get_hdr_info(&oh_loc, H5AC_ind_read_dxpl_id, &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, H5AC_ind_read_dxpl_id)) < 0)
|
|
||||||
FAIL_STACK_ERROR
|
|
||||||
if(chunkno != 0)
|
|
||||||
TEST_ERROR
|
|
||||||
|
|
||||||
/* Unlock the message */
|
|
||||||
if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5AC_ind_read_dxpl_id) < 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();
|
|
||||||
|
|
||||||
/* Close the file we created */
|
/* Close the file we created */
|
||||||
if(H5Fclose(file) < 0)
|
if(H5Fclose(file) < 0)
|
||||||
TEST_ERROR
|
TEST_ERROR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user