diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2009-09-29 21:53:19 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2009-09-29 21:53:19 (GMT) |
commit | e3101ecc4674224d442d8308c53cccf569ef0007 (patch) | |
tree | 0079c1be854a754344572523032679d3508b0a53 /src | |
parent | 89404acc45281bef751d1073ce5cf82b5d1db4d1 (diff) | |
download | hdf5-e3101ecc4674224d442d8308c53cccf569ef0007.zip hdf5-e3101ecc4674224d442d8308c53cccf569ef0007.tar.gz hdf5-e3101ecc4674224d442d8308c53cccf569ef0007.tar.bz2 |
[svn-r17555] Description:
Bring r17553 from trunk to 1.8 branch:
Bring general fixes/improvements from file_free_space branch back to
trunk.
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/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) 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 production mode
Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Mac OS X/32 10.5.8 (amazon) in debug mode
Mac OS X/32 10.5.8 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Defl.c | 37 | ||||
-rw-r--r-- | src/H5Doh.c | 32 | ||||
-rw-r--r-- | src/H5Dpkg.h | 5 | ||||
-rw-r--r-- | src/H5F.c | 6 | ||||
-rw-r--r-- | src/H5Fsuper.c | 8 | ||||
-rw-r--r-- | src/H5Fsuper_cache.c | 1 | ||||
-rw-r--r-- | src/H5Goh.c | 9 | ||||
-rw-r--r-- | src/H5O.c | 244 | ||||
-rw-r--r-- | src/H5Opkg.h | 8 | ||||
-rw-r--r-- | src/H5Oprivate.h | 3 | ||||
-rw-r--r-- | src/H5Opublic.h | 35 | ||||
-rw-r--r-- | src/H5Toh.c | 3 |
12 files changed, 266 insertions, 125 deletions
diff --git a/src/H5Defl.c b/src/H5Defl.c index 7ce0c67..63f07a7 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -50,7 +50,6 @@ /* Layout operation callbacks */ static herr_t H5D_efl_construct(H5F_t *f, H5D_t *dset); -static hbool_t H5D_efl_is_space_alloc(const H5O_storage_t *storage); static herr_t H5D_efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info, hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space, H5D_chunk_map_t *cm); @@ -181,7 +180,7 @@ done: * *------------------------------------------------------------------------- */ -static hbool_t +hbool_t H5D_efl_is_space_alloc(const H5O_storage_t UNUSED *storage) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_efl_is_space_alloc) @@ -556,3 +555,37 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_efl_writevv() */ + +/*------------------------------------------------------------------------- + * Function: H5D_efl_bh_size + * + * Purpose: Retrieve the amount of heap storage used for External File + * List message + * + * Return: Success: Non-negative + * Failure: negative + * + * Programmer: Vailin Choi; August 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, hsize_t *heap_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_efl_bh_info, FAIL) + + /* Check args */ + HDassert(f); + HDassert(efl); + HDassert(H5F_addr_defined(efl->heap_addr)); + HDassert(heap_size); + + /* Get the size of the local heap for EFL's file list */ + if(H5HL_heapsize(f, dxpl_id, efl->heap_addr, heap_size) < 0) + HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to retrieve local heap info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_chunk_bh_info() */ diff --git a/src/H5Doh.c b/src/H5Doh.c index d2649f7..f2f0c01 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -53,6 +53,8 @@ static hid_t H5O_dset_open(const H5G_loc_t *obj_loc, hid_t lapl_id, static void *H5O_dset_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id); static H5O_loc_t *H5O_dset_get_oloc(hid_t obj_id); +static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5_ih_info_t *bh_info); /*********************/ @@ -78,7 +80,8 @@ const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{ H5O_dset_isa, /* "isa" message */ H5O_dset_open, /* open an object of this class */ H5O_dset_create, /* create an object of this class */ - H5O_dset_get_oloc /* get an object header location for an object */ + H5O_dset_get_oloc, /* get an object header location for an object */ + H5O_dset_bh_info /* get the index & heap info for an object */ }}; /* Declare a free list to manage the H5D_copy_file_ud_t struct */ @@ -358,13 +361,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { H5O_layout_t layout; /* Data storage layout message */ - herr_t ret_value = SUCCEED; /* Return value */ + htri_t exists; /* Flag if header message of interest exists */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_dset_bh_info, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_bh_info) /* Sanity check */ HDassert(f); @@ -378,7 +382,6 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) /* Check for chunked dataset storage */ if(layout.type == H5D_CHUNKED && H5D_chunk_is_space_alloc(&layout.storage)) { H5O_pline_t pline; /* I/O pipeline message */ - htri_t exists; /* Flag if header message of interest exists */ /* Check for I/O pipeline message */ if((exists = H5O_msg_exists_oh(oh, H5O_PLINE_ID)) < 0) @@ -394,6 +397,25 @@ H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine chunked dataset btree info") } /* end if */ + /* Check for External File List message in the object header */ + if((exists = H5O_msg_exists_oh(oh, H5O_EFL_ID)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "unable to check for EFL message") + + if(exists && H5D_efl_is_space_alloc(&layout)) { + H5O_efl_t efl; /* External File List message */ + + /* Start with clean EFL info */ + HDmemset(&efl, 0, sizeof(efl)); + + /* Get External File List message from the object header */ + if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_EFL_ID, &efl)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't find EFL message") + + /* Get size of local heap for EFL message's file list */ + if(H5D_efl_bh_info(f, dxpl_id, &efl, &(bh_info->heap_size)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't determine EFL heap info") + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dset_bh_info() */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index aa5a359..9fde879 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -633,6 +633,11 @@ H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst, H5O_storage_compact_t *storage_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id); +/* Functions that operate on EFL (External File List)*/ +H5_DLL hbool_t H5D_efl_is_space_alloc(const H5O_storage_t *storage); +H5_DLL herr_t H5D_efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, + hsize_t *heap_size); + /* Functions that perform fill value operations on datasets */ H5_DLL herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id); @@ -1084,7 +1084,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list") /* Only truncate the file on an orderly close, with write-access */ - if(f->closing && (H5F_ACC_RDWR & f->shared->flags)) { + if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { /* Truncate the file to the current allocated size */ if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) /* Push error, but keep going*/ @@ -1616,7 +1616,7 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * calling H5Fflush() with the read-only handle, still causes data * to be flushed. */ - if(H5F_ACC_RDWR & f->shared->flags) { + if(H5F_ACC_RDWR & H5F_INTENT(f)) { /* Flush other files, depending on scope */ if(H5F_SCOPE_GLOBAL == scope) { /* Call the flush routine for mounted file hierarchies */ @@ -1894,7 +1894,7 @@ H5F_try_close(H5F_t *f) * copy of the cache needs to be clean. * Only try to flush the file if it was opened with write access. */ - if(f->intent&H5F_ACC_RDWR) { + if(f->intent & H5F_ACC_RDWR) { /* Flush all caches */ if(H5F_flush(f, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index e85c980..9c12f15 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -670,8 +670,8 @@ H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_ /* Set the superblock extension size */ if(super_ext_size) { if(H5F_addr_defined(f->shared->sblock->ext_addr)) { - H5O_loc_t ext_loc; /* "Object location" for superblock extension */ - H5O_info_t oinfo; /* Object info for superblock extension */ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + H5O_hdr_info_t hdr_info; /* Object info for superblock extension */ /* Set up "fake" object location for superblock extension */ H5O_loc_reset(&ext_loc); @@ -679,11 +679,11 @@ H5F_super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_ ext_loc.addr = f->shared->sblock->ext_addr; /* Get object header info for superblock extension */ - if(H5O_get_info(&ext_loc, dxpl_id, FALSE, &oinfo) < 0) + if(H5O_get_hdr_info(&ext_loc, dxpl_id, &hdr_info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve superblock extension info") /* Set the superblock extension size */ - *super_ext_size = oinfo.hdr.space.total; + *super_ext_size = hdr_info.space.total; } /* end if */ else /* Set the superblock extension size to zero */ diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index c3be020..4dd3c0d 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -572,7 +572,6 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1 ret_value = sblock; done: - FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_sblock_load() */ diff --git a/src/H5Goh.c b/src/H5Goh.c index d727cb7..0827285 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -51,6 +51,8 @@ static hid_t H5O_group_open(const H5G_loc_t *obj_loc, hid_t lapl_id, static void *H5O_group_create(H5F_t *f, void *_crt_info, H5G_loc_t *obj_loc, hid_t dxpl_id); static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id); +static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, + H5_ih_info_t *bh_info); /*********************/ @@ -76,7 +78,8 @@ const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ H5O_group_isa, /* "isa" message */ H5O_group_open, /* open an object of this class */ H5O_group_create, /* create an object of this class */ - H5O_group_get_oloc /* get an object header location for an object */ + H5O_group_get_oloc, /* get an object header location for an object */ + H5O_group_bh_info /* get the index & heap info for an object */ }}; @@ -257,14 +260,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { htri_t exists; /* Flag if header message of interest exists */ H5HF_t *fheap = NULL; /* Fractal heap handle */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5O_group_bh_info, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5O_group_bh_info) /* Sanity check */ HDassert(f); @@ -84,6 +84,7 @@ static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type); static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); +static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr); /*********************/ @@ -127,18 +128,6 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { H5O_MSG_UNKNOWN, /*0x0017 Placeholder for unknown message */ }; -/* Header object ID to class mapping */ -/* - * Initialize the object class info table. Begin with the most general types - * and end with the most specific. For instance, any object that has a - * datatype message is a datatype but only some of them are datasets. - */ -const H5O_obj_class_t *const H5O_obj_class_g[] = { - H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */ - H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */ - H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */ -}; - /* Declare a free list to manage the H5O_t struct */ H5FL_DEFINE(H5O_t); @@ -167,6 +156,18 @@ H5FL_EXTERN(H5_obj_t); /* Local Variables */ /*******************/ +/* Header object ID to class mapping */ +/* + * Initialize the object class info table. Begin with the most general types + * and end with the most specific. For instance, any object that has a + * datatype message is a datatype but only some of them are datasets. + */ +static const H5O_obj_class_t *const H5O_obj_class_g[] = { + H5O_OBJ_DATATYPE, /* Datatype object (H5O_TYPE_NAMED_DATATYPE - 2) */ + H5O_OBJ_DATASET, /* Dataset object (H5O_TYPE_DATASET - 1) */ + H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */ +}; + /*------------------------------------------------------------------------- @@ -2296,6 +2297,131 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_get_hdr_info + * + * Purpose: Retrieve the object header information for an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * September 22 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr) +{ + H5O_t *oh = NULL; /* Object header */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_get_hdr_info, FAIL) + + /* Check args */ + HDassert(oloc); + HDassert(hdr); + + /* Reset the object header info structure */ + HDmemset(hdr, 0, sizeof(*hdr)); + + /* Get the object header */ + if(NULL == (oh = (H5O_t *)H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + + /* Get the information for the object header */ + if(H5O_get_hdr_info_real(oh, hdr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") + +done: + if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_get_hdr_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_get_hdr_info_real + * + * Purpose: Internal routine to retrieve the object header information for an object + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * September 22 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr) +{ + const H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + const H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_get_hdr_info_real) + + /* Check args */ + HDassert(oh); + HDassert(hdr); + + /* Set the version for the object header */ + hdr->version = oh->version; + + /* Set the number of messages & chunks */ + hdr->nmesgs = oh->nmesgs; + hdr->nchunks = oh->nchunks; + + /* Set the status flags */ + hdr->flags = oh->flags; + + /* Iterate over all the messages, accumulating message size & type information */ + hdr->space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); + hdr->space.mesg = 0; + hdr->space.free = 0; + hdr->mesg.present = 0; + hdr->mesg.shared = 0; + for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + uint64_t type_flag; /* Flag for message type */ + + /* Accumulate space usage information, based on the type of message */ + if(H5O_NULL_ID == curr_msg->type->id) + hdr->space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else if(H5O_CONT_ID == curr_msg->type->id) + hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else { + hdr->space.meta += H5O_SIZEOF_MSGHDR_OH(oh); + hdr->space.mesg += curr_msg->raw_size; + } /* end else */ + + /* Set flag to indicate presence of message type */ + type_flag = ((uint64_t)1) << curr_msg->type->id; + hdr->mesg.present |= type_flag; + + /* Set flag if the message is shared in some way */ + if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \ + hdr->mesg.shared |= type_flag; + } /* end for */ + + /* Iterate over all the chunks, adding any gaps to the free space */ + hdr->space.total = 0; + for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) { + /* Accumulate the size of the header on disk */ + hdr->space.total += curr_chunk->size; + + /* If the chunk has a gap, add it to the free space */ + hdr->space.free += curr_chunk->gap; + } /* end for */ + + /* Sanity check that all the bytes are accounted for */ + HDassert(hdr->space.total == (hdr->space.free + hdr->space.meta + hdr->space.mesg)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_get_hdr_info_real() */ + + +/*------------------------------------------------------------------------- * Function: H5O_get_info * * Purpose: Retrieve the information for an object @@ -2309,12 +2435,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo) +H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, + H5O_info_t *oinfo) { + const H5O_obj_class_t *obj_class; /* Class of object for header */ H5O_t *oh = NULL; /* Object header */ - H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */ - H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_get_info, FAIL) @@ -2336,20 +2461,12 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o /* Set the object's address */ oinfo->addr = oloc->addr; - /* Retrieve the type of the object */ - if(H5O_obj_type_real(oh, &oinfo->type) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") + /* Get class for object */ + if(NULL == (obj_class = H5O_obj_class_real(oh))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class") - /* Retrieve btree and heap storage info, if requested */ - if(want_ih_info) { - if(oinfo->type == H5O_TYPE_GROUP) { - if(H5O_group_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve group btree & heap info") - } else if(oinfo->type == H5O_TYPE_DATASET) { - if(H5O_dset_bh_info(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj)/*out*/) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve chunked dataset btree info") - } - } /* end if */ + /* Retrieve the type of the object */ + oinfo->type = obj_class->type; /* Set the object's reference count */ oinfo->rc = oh->nlink; @@ -2395,66 +2512,29 @@ H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *o } /* end else */ } /* end else */ - /* Set the version for the object header */ - oinfo->hdr.version = oh->version; - - /* Set the number of messages & chunks */ - oinfo->hdr.nmesgs = oh->nmesgs; - oinfo->hdr.nchunks = oh->nchunks; - - /* Set the status flags */ - oinfo->hdr.flags = oh->flags; - - /* Iterate over all the messages, accumulating message size & type information */ - oinfo->hdr.space.meta = H5O_SIZEOF_HDR(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); - oinfo->hdr.space.mesg = 0; - oinfo->hdr.space.free = 0; - oinfo->hdr.mesg.present = 0; - oinfo->hdr.mesg.shared = 0; - for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { - uint64_t type_flag; /* Flag for message type */ - - /* Accumulate space usage information, based on the type of message */ - if(H5O_NULL_ID == curr_msg->type->id) - oinfo->hdr.space.free += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - else if(H5O_CONT_ID == curr_msg->type->id) - oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - else { - oinfo->hdr.space.meta += H5O_SIZEOF_MSGHDR_OH(oh); - oinfo->hdr.space.mesg += curr_msg->raw_size; - } /* end else */ - - /* Set flag to indicate presence of message type */ - type_flag = ((uint64_t)1) << curr_msg->type->id; - oinfo->hdr.mesg.present |= type_flag; - - /* Set flag if the message is shared in some way */ - if(curr_msg->flags & H5O_MSG_FLAG_SHARED) \ - oinfo->hdr.mesg.shared |= type_flag; - } /* end for */ + /* Get the information for the object header */ + if(H5O_get_hdr_info_real(oh, &oinfo->hdr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object header info") /* Retrieve # of attributes */ if(H5O_attr_count_real(oloc->file, dxpl_id, oh, &oinfo->num_attrs) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute count") /* Get B-tree & heap metadata storage size, if requested */ if(want_ih_info) { - if((oinfo->num_attrs > 0) && (H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") - } /* end if */ - - /* Iterate over all the chunks, adding any gaps to the free space */ - oinfo->hdr.space.total = 0; - for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) { - /* Accumulate the size of the header on disk */ - oinfo->hdr.space.total += curr_chunk->size; - - /* If the chunk has a gap, add it to the free space */ - oinfo->hdr.space.free += curr_chunk->gap; - } /* end for */ + /* Check for 'bh_info' callback for this type of object */ + if(obj_class->bh_info) { + /* Call the object's class 'bh_info' routine */ + if((obj_class->bh_info)(oloc->file, dxpl_id, oh, &(oinfo->meta_size.obj) /* out */) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object's btree & heap info") + } /* end if */ - /* Sanity check that all the bytes are accounted for */ - HDassert(oinfo->hdr.space.total == (oinfo->hdr.space.free + oinfo->hdr.space.meta + oinfo->hdr.space.mesg)); + /* Get B-tree & heap info for any attributes */ + if(oinfo->num_attrs > 0) { + if(H5O_attr_bh_info(oloc->file, dxpl_id, oh, &oinfo->meta_size.attr/*out*/) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve attribute btree & heap info") + } /* end if */ + } /* end if */ done: if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5Opkg.h b/src/H5Opkg.h index c2e58dd..e0a0971 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -320,6 +320,7 @@ typedef struct H5O_obj_class_t { hid_t (*open)(const H5G_loc_t *, hid_t, hid_t, hbool_t ); /*open an object of this class */ void *(*create)(H5F_t *, void *, H5G_loc_t *, hid_t ); /*create an object of this class */ H5O_loc_t *(*get_oloc)(hid_t ); /*get the object header location for an object */ + herr_t (*bh_info)(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); /*get the index & heap info for an object */ } H5O_obj_class_t; /* Node in skip list to map addresses from one file to another during object header copy */ @@ -337,9 +338,6 @@ H5_DLLVAR const H5AC_class_t H5AC_OHDR[1]; /* Header message ID to class mapping */ H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[H5O_MSG_TYPES]; -/* Header object ID to class mapping */ -H5_DLLVAR const H5O_obj_class_t *const H5O_obj_class_g[3]; - /* Declare external the free list for H5O_t's */ H5FL_EXTERN(H5O_t); @@ -497,10 +495,6 @@ 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); /* Collect storage info for btree and heap */ -H5_DLL herr_t H5O_group_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, - H5_ih_info_t *bh_info); -H5_DLL herr_t H5O_dset_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, - H5_ih_info_t *bh_info); H5_DLL herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 14c4a3a..0fd5942 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -595,7 +595,8 @@ H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned mesg_flags); #endif /* H5O_ENABLE_BOGUS */ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); -H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, +H5_DLL herr_t H5O_get_hdr_info(const H5O_loc_t *oloc, hid_t dxpl_id, H5O_hdr_info_t *hdr); +H5_DLL herr_t H5O_get_info(const H5O_loc_t *oloc, hid_t dxpl_id, hbool_t want_ih_info, H5O_info_t *oinfo); H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist); diff --git a/src/H5Opublic.h b/src/H5Opublic.h index ddf1a93..84fdecc 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -87,6 +87,24 @@ typedef enum H5O_type_t { H5O_TYPE_NTYPES /* Number of different object types (must be last!) */ } H5O_type_t; +/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ +typedef struct H5O_hdr_info_t { + unsigned version; /* Version number of header format in file */ + unsigned nmesgs; /* Number of object header messages */ + unsigned nchunks; /* Number of object header chunks */ + unsigned flags; /* Object header status flags */ + struct { + hsize_t total; /* Total space for storing object header in file */ + hsize_t meta; /* Space within header for object header metadata information */ + hsize_t mesg; /* Space within header for actual message information */ + hsize_t free; /* Free space within object header */ + } space; + struct { + uint64_t present; /* Flags to indicate presence of message type in header */ + uint64_t shared; /* Flags to indicate message type is shared in header */ + } mesg; +} H5O_hdr_info_t; + /* Information struct for object (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ typedef struct H5O_info_t { unsigned long fileno; /* File number that object is located in */ @@ -98,22 +116,7 @@ typedef struct H5O_info_t { time_t ctime; /* Change time */ time_t btime; /* Birth time */ hsize_t num_attrs; /* # of attributes attached to object */ - struct { - unsigned version; /* Version number of header format in file */ - unsigned nmesgs; /* Number of object header messages */ - unsigned nchunks; /* Number of object header chunks */ - unsigned flags; /* Object header status flags */ - struct { - hsize_t total; /* Total space for storing object header in file */ - hsize_t meta; /* Space within header for object header metadata information */ - hsize_t mesg; /* Space within header for actual message information */ - hsize_t free; /* Free space within object header */ - } space; - struct { - uint64_t present; /* Flags to indicate presence of message type in header */ - uint64_t shared; /* Flags to indicate message type is shared in header */ - } mesg; - } hdr; + H5O_hdr_info_t hdr; /* Object header information */ /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ diff --git a/src/H5Toh.c b/src/H5Toh.c index 24fc0f1..886acc1 100644 --- a/src/H5Toh.c +++ b/src/H5Toh.c @@ -76,7 +76,8 @@ const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{ H5O_dtype_isa, /* "isa" */ H5O_dtype_open, /* open an object of this class */ H5O_dtype_create, /* create an object of this class */ - H5O_dtype_get_oloc /* get an object header location for an object */ + H5O_dtype_get_oloc, /* get an object header location for an object */ + NULL /* get the index & heap info for an object */ }}; |