diff options
author | Jacob Smith <jake.smith@hdfgroup.org> | 2018-09-11 21:37:14 (GMT) |
---|---|---|
committer | Jacob Smith <jake.smith@hdfgroup.org> | 2018-09-11 21:37:14 (GMT) |
commit | 602dd3ac15c9f5cd47fc78985266ce66a68a8789 (patch) | |
tree | 149023d5992abebe5a5a36e45e8132ab478a8c63 /src/H5Oint.c | |
parent | 5647dea421be9dc8429f08632aa72a8a22904292 (diff) | |
download | hdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.zip hdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.tar.gz hdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.tar.bz2 |
Stash work on object header reduction code and tests.
CMake stuff is not verified.
Diffstat (limited to 'src/H5Oint.c')
-rw-r--r-- | src/H5Oint.c | 382 |
1 files changed, 295 insertions, 87 deletions
diff --git a/src/H5Oint.c b/src/H5Oint.c index 2752a25..1d07415 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -83,7 +83,6 @@ static herr_t H5O__visit_cb(hid_t group, const char *name, const H5L_info_t *lin void *_udata); static const H5O_obj_class_t *H5O__obj_class_real(const H5O_t *oh); - /*********************/ /* Package Variables */ /*********************/ @@ -277,130 +276,276 @@ done: * matzke@llnl.gov * Aug 5 1997 * + * Changes: 17 August 2018 + * Jacob Smith + * Refactor out the operations into two separate steps -- + * preparation and application -- to facilitate overriding the + * library-default size allocated for the object header. This + * function is retained as a wrapper, to minimize changes to + * unaffected calling functions. + * *------------------------------------------------------------------------- */ herr_t -H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, - H5O_loc_t *loc/*out*/) +H5O_create( \ + H5F_t *f, \ + size_t size_hint, \ + size_t initial_rc, \ + hid_t ocpl_id, \ + H5O_loc_t *loc) /*out*/ { - H5P_genplist_t *oc_plist; /* Object creation property list */ - H5O_t *oh = NULL; /* Object header created */ - haddr_t oh_addr; /* Address of initial object header */ - size_t oh_size; /* Size of initial object header */ - uint8_t oh_flags; /* Object header's initial status flags */ - unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */ - hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ - herr_t ret_value = SUCCEED; /* return value */ + H5O_t *oh = NULL; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) - /* check args */ HDassert(f); HDassert(loc); HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + /* create object header in freelist + * header version is set internally + */ + oh = H5O__create_ohdr(f, ocpl_id); + if (NULL == oh) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, + "Can't instantiate object header") + + /* apply object header information to file + */ + if (0 > H5O__apply_ohdr( + f, + oh, + ocpl_id, + size_hint, + initial_rc, + loc)) + { + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, + "Can't apply object header to file") + } + +done: + if (FAIL == ret_value && + NULL != oh && + 0 > H5O__free(oh)) + { + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, + "can't delete object header") + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_create() */ + + +/*----------------------------------------------------------------------------- + * Function: H5O__create_ohdr + * + * Purpose: Create the object header, set version and flags. + * + * Return: Success: Pointer to the newly-crated header object. + * Failure: NULL + * + * Programmer: Jacob Smith + * 17 August 2018 + * + *----------------------------------------------------------------------------- + */ +H5O_t * +H5O__create_ohdr( \ + H5F_t *f, \ + hid_t ocpl_id) +{ + H5P_genplist_t *oc_plist; + H5O_t *oh = NULL; /* Object header in Freelist */ + uint8_t oh_flags; /* Initial status flags */ + H5O_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + HDassert(f); + HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + /* Check for invalid access request */ - if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "no write intent on file") + if (0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, + "no write intent on file") - /* Make certain we allocate at least a reasonable size for the object header */ - size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint)); + oh = H5FL_CALLOC(H5O_t); + if (NULL == oh) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed") - /* Get the property list */ - if(NULL == (oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list") + oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id); + if (NULL == oc_plist) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, + "not a property list") /* Get any object header status flags set by properties */ - if(H5P_get(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags") + if (0 > H5P_get(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, + "can't get object header flags") - /* Allocate the object header and zero out header fields */ - if(NULL == (oh = H5FL_CALLOC(H5O_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if (0 > H5O_set_version(f, oh, oh_flags, H5F_STORE_MSG_CRT_IDX(f))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL, + "can't set version of object header") - /* Initialize file-specific information for object header */ - store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f); + oh->flags = oh_flags; - if(H5O_set_version(f, oh, oh_flags, store_msg_crt_idx) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set version of objecdt header") + ret_value = oh; + +done: + if (NULL == ret_value && + NULL != oh && + 0 > H5O__free(oh)) + { + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, + "can't delete object header") + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__create_ohdr */ + + +/*----------------------------------------------------------------------------- + * Function: H5O__apply_ohdr + * + * Purpose: Initialize and set the object header in the file. + * Record some information at `loc_out`. + * + * Return: Success: SUCCEED (0) (non-negative value) + * Failure: FAI (-1) (negative value) + * + * Programmer: Jacob Smith + * 17 August 2018 + * + *----------------------------------------------------------------------------- + */ +herr_t +H5O__apply_ohdr( \ + H5F_t *f, \ + H5O_t *oh, \ + hid_t ocpl_id, \ + size_t size_hint, \ + size_t initial_rc, \ + H5O_loc_t *loc_out) +{ + haddr_t oh_addr; + size_t oh_size; + H5P_genplist_t *oc_plist = NULL; + unsigned insert_flags = H5AC__NO_FLAGS_SET; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(f); + HDassert(loc_out); + HDassert(oh); + HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + + /* Allocate at least a reasonable size for the object header */ + size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint)); oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); - oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); + oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); /* funky cast */ + #ifdef H5O_ENABLE_BAD_MESG_COUNT - /* Check whether the "bad message count" property is set */ - if(H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME) > 0) { - /* Retrieve bad message count flag */ - if(H5P_get(oc_plist, H5O_BAD_MESG_COUNT_NAME, &oh->store_bad_mesg_count) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get bad message count flag") + if (0 < H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME)) { + /* Set bad message count flag -- from property list */ + if (0 > H5P_get(oc_plist, + H5O_BAD_MESG_COUNT_NAME, + &oh->store_bad_mesg_count)) + { + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, + "can't get bad message count flag") + } } #endif /* H5O_ENABLE_BAD_MESG_COUNT */ /* Create object header proxy if doing SWMR writes */ - if(oh->swmr_write) { - /* Create virtual entry, for use as proxy */ - if(NULL == (oh->proxy = H5AC_proxy_entry_create())) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create object header proxy") - } - else + if (oh->swmr_write) { + oh->proxy = H5AC_proxy_entry_create(); + if (NULL == oh->proxy) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, + "can't create object header proxy") + } else { oh->proxy = NULL; + } - /* Set initial status flags */ - oh->flags = oh_flags; + oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id); + if (NULL == oc_plist) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, + "not a property list") /* Initialize version-specific fields */ - if(oh->version > H5O_VERSION_1) { - /* Initialize all time fields with current time, if we are storing them */ - if(oh->flags & H5O_HDR_STORE_TIMES) + if (oh->version > H5O_VERSION_1) { + /* Initialize all time fields */ + if (oh->flags & H5O_HDR_STORE_TIMES) oh->atime = oh->mtime = oh->ctime = oh->btime = H5_now(); else oh->atime = oh->mtime = oh->ctime = oh->btime = 0; - /* Make certain attribute creation order tracking is enabled if - * attributes can be shared in this file. - */ - if(store_msg_crt_idx) + if (H5F_STORE_MSG_CRT_IDX(f)) + /* flag to record message creation indices */ oh->flags |= H5O_HDR_ATTR_CRT_ORDER_TRACKED; - /* Retrieve attribute storage phase change values from property list */ - if(H5P_get(oc_plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &oh->max_compact) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get max. # of compact attributes") - if(H5P_get(oc_plist, H5O_CRT_ATTR_MIN_DENSE_NAME, &oh->min_dense) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get min. # of dense attributes") + /* Set attribute storage phase change values -- from property list */ + if (0 > H5P_get(oc_plist, + H5O_CRT_ATTR_MAX_COMPACT_NAME, + &oh->max_compact)) + { + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, + "can't get max. # of compact attributes") + } + if (0 > H5P_get(oc_plist, + H5O_CRT_ATTR_MIN_DENSE_NAME, + &oh->min_dense)) + { + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, + "can't get min. # of dense attributes") + } /* Check for non-default attribute storage phase change values */ - if(oh->max_compact != H5O_CRT_ATTR_MAX_COMPACT_DEF || oh->min_dense != H5O_CRT_ATTR_MIN_DENSE_DEF) + if (H5O_CRT_ATTR_MAX_COMPACT_DEF != oh->max_compact || \ + H5O_CRT_ATTR_MIN_DENSE_DEF != oh->min_dense ) + { oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE; + } /* Determine correct value for chunk #0 size bits */ /* Avoid compiler warning on 32-bit machines */ #if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T - if(size_hint > 4294967295UL) + if (size_hint > 4294967295UL) oh->flags |= H5O_HDR_CHUNK0_8; else #endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ - if(size_hint > 65535) + if (size_hint > 65535) oh->flags |= H5O_HDR_CHUNK0_4; - else if(size_hint > 255) + else if (size_hint > 255) oh->flags |= H5O_HDR_CHUNK0_2; - } /* end if */ - else { + } else { /* Reset unused time fields */ oh->atime = oh->mtime = oh->ctime = oh->btime = 0; - } /* end else */ + } /* end if/else header version >1 */ /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ oh_size = (size_t)H5O_SIZEOF_HDR(oh) + size_hint; /* Allocate disk space for header and first chunk */ - if(HADDR_UNDEF == (oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header") + oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size); + if (HADDR_UNDEF == oh_addr) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "file allocation failed for object header") /* Create the chunk list */ - oh->nchunks = oh->alloc_nchunks = 1; - if(NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + oh->nchunks = 1; + oh->alloc_nchunks = 1; + oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks); + if (NULL == oh->chunk) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed") /* Initialize the first chunk */ oh->chunk[0].addr = oh_addr; @@ -409,30 +554,37 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, /* Allocate enough space for the first chunk */ /* (including space for serializing the object header prefix */ - if(NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size); + if(NULL == oh->chunk[0].image) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed") oh->chunk[0].chunk_proxy = NULL; /* Put magic # for object header in first chunk */ - if(oh->version > H5O_VERSION_1) + if (H5O_VERSION_1 < oh->version) HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); /* Create the message list */ oh->nmesgs = 1; oh->alloc_nmesgs = H5O_NMESGS; - if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs); + if (NULL == oh->mesg) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed") - /* Initialize the initial "null" message, covering the entire first chunk */ + /* Initialize the initial "null" message; covers the entire first chunk */ oh->mesg[0].type = H5O_MSG_NULL; oh->mesg[0].dirty = TRUE; oh->mesg[0].native = NULL; - oh->mesg[0].raw = oh->chunk[0].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)) + H5O_SIZEOF_MSGHDR_OH(oh); + oh->mesg[0].raw = oh->chunk[0].image \ + + H5O_SIZEOF_HDR(oh) \ + - H5O_SIZEOF_CHKSUM_OH(oh) \ + + H5O_SIZEOF_MSGHDR_OH(oh); oh->mesg[0].raw_size = size_hint - (size_t)H5O_SIZEOF_MSGHDR_OH(oh); oh->mesg[0].chunkno = 0; /* Check for non-zero initial refcount on the object header */ - if(initial_rc > 0) { + if (initial_rc > 0) { /* Set the initial refcount & pin the header when its inserted */ oh->rc = initial_rc; insert_flags |= H5AC__PIN_ENTRY_FLAG; @@ -442,9 +594,11 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5_BEGIN_TAG(oh_addr); /* Cache object header */ - if(H5AC_insert_entry(f, H5AC_OHDR, oh_addr, oh, insert_flags) < 0) - HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header") + if (0 > H5AC_insert_entry(f, H5AC_OHDR, oh_addr, oh, insert_flags)) + HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL, + "unable to cache object header") + /* TODO: is this relevant to the BEGIN/END TAG region? if not, delete */ /* Reset object header pointer, now that it's been inserted into the cache */ oh = NULL; @@ -452,20 +606,16 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5_END_TAG /* Set up object location */ - loc->file = f; - loc->addr = oh_addr; + loc_out->file = f; + loc_out->addr = oh_addr; - /* Open it */ - if(H5O_open(loc) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header") + if (0 > H5O_open(loc_out)) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, + "unable to open object header") done: - if(ret_value < 0 && oh) - if(H5O__free(oh) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_create() */ + FUNC_LEAVE_NOAPI(ret_value); +} /* H5O__apply_ohdr */ /*------------------------------------------------------------------------- @@ -2686,6 +2836,64 @@ H5O_get_oh_addr(const H5O_t *oh) /*------------------------------------------------------------------------- + * Function: H5O_get_oh_flags + * + * Programmer: Jacob Smith + * 17 August 2018 + * + *------------------------------------------------------------------------- + */ +uint8_t +H5O_get_oh_flags(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + HDassert(oh->flags); + FUNC_LEAVE_NOAPI(oh->flags); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_get_oh_mtime + * + * Purpose: Retrieve an object's modification time. Assumes that the + * caller has verified that accessing this variable is appropriate + * to the header in question. + * + * Programmer: Jacob Smith + * 17 August 2018 + * + *------------------------------------------------------------------------- + */ +time_t +H5O_get_oh_mtime(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + HDassert(oh->mtime); + FUNC_LEAVE_NOAPI(oh->mtime); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_get_oh_version + * + * Programmer: Jacob Smith + * 17 August 2018 + * + *------------------------------------------------------------------------- + */ +uint8_t +H5O_get_oh_version(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + HDassert(oh->version); + FUNC_LEAVE_NOAPI(oh->version); +} + + +/*------------------------------------------------------------------------- * Function: H5O_get_rc_and_type * * Purpose: Retrieve an object's reference count and type |