diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Abtree2.c | 87 | ||||
-rw-r--r-- | src/H5Adense.c | 17 | ||||
-rw-r--r-- | src/H5Aint.c | 3 | ||||
-rw-r--r-- | src/H5Apkg.h | 5 | ||||
-rw-r--r-- | src/H5F.c | 29 | ||||
-rw-r--r-- | src/H5FD.c | 51 | ||||
-rw-r--r-- | src/H5Fpkg.h | 3 | ||||
-rw-r--r-- | src/H5Fprivate.h | 3 | ||||
-rw-r--r-- | src/H5Gobj.c | 27 | ||||
-rw-r--r-- | src/H5O.c | 17 | ||||
-rw-r--r-- | src/H5Oattribute.c | 6 | ||||
-rw-r--r-- | src/H5Ocache.c | 33 | ||||
-rw-r--r-- | src/H5Omessage.c | 80 | ||||
-rw-r--r-- | src/H5Opkg.h | 18 | ||||
-rw-r--r-- | src/H5Oprivate.h | 6 | ||||
-rwxr-xr-x | src/H5SM.c | 12 | ||||
-rw-r--r-- | src/H5Tcommit.c | 2 |
17 files changed, 338 insertions, 61 deletions
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c index 57e669e..02e1bed 100644 --- a/src/H5Abtree2.c +++ b/src/H5Abtree2.c @@ -44,11 +44,17 @@ /* Local Macros */ /****************/ +#ifndef QAK +/* Size of stack buffer for serialized attributes */ +#define H5A_ATTR_BUF_SIZE 128 +#endif /* QAK */ + /******************/ /* Local Typedefs */ /******************/ +#ifdef QAK /* * Data exchange structure for dense attribute storage. This structure is * passed through the fractal heap layer to compare attributes. @@ -59,12 +65,13 @@ typedef struct H5A_fh_ud_cmp_t { hid_t dxpl_id; /* DXPL for operation */ const char *name; /* Name of attribute to compare */ const H5A_dense_bt2_name_rec_t *record; /* v2 B-tree record for attribute */ - H5B2_found_t found_op; /* Callback when correct attribute is found */ + H5A_bt2_found_t found_op; /* Callback when correct attribute is found */ void *found_op_data; /* Callback data when correct attribute is found */ /* upward */ int cmp; /* Comparison of two attribute names */ } H5A_fh_ud_cmp_t; +#endif /* QAK */ /********************/ @@ -101,7 +108,9 @@ static herr_t H5A_dense_btree2_name_debug(FILE *stream, const H5F_t *f, hid_t dx int indent, int fwidth, const void *record, const void *_udata); /* Fractal heap function callbacks */ +#ifdef QAK static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_data); +#endif /* QAK */ /*********************/ @@ -136,6 +145,11 @@ const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */ /* Library Private Variables */ /*****************************/ +#ifndef QAK +/* Declare extern a free list to manage blocks of type conversion data */ +H5FL_BLK_EXTERN(ser_attr); +#endif /* QAK */ + /*******************/ /* Local Variables */ @@ -157,11 +171,13 @@ const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */ * *------------------------------------------------------------------------- */ +#ifdef QAK static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata) { H5A_fh_ud_cmp_t *udata = (H5A_fh_ud_cmp_t *)_udata; /* User data for 'op' callback */ H5A_t *attr = NULL; /* Pointer to attribute created from heap object */ + hbool_t took_ownership = FALSE; /* Whether the "found" operator took ownership of the attribute */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fh_name_cmp) @@ -183,17 +199,18 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata) attr->crt_idx = udata->record->corder; /* Make callback */ - if((udata->found_op)(attr, udata->found_op_data) < 0) + if((udata->found_op)(attr, &took_ownership, udata->found_op_data) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPERATE, FAIL, "attribute found callback failed") } /* end if */ done: /* Release the space allocated for the attrbute */ - if(attr) + if(attr && !took_ownership) H5O_msg_free(H5O_ATTR_ID, attr); FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_fh_name_cmp() */ +#endif /* QAK */ /*------------------------------------------------------------------------- @@ -284,13 +301,16 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec) else if(bt2_udata->name_hash > bt2_rec->hash) ret_value = 1; else { +#ifdef QAK H5A_fh_ud_cmp_t fh_udata; /* User data for fractal heap 'op' callback */ +#endif /* QAK */ H5HF_t *fheap; /* Fractal heap handle to use for finding object */ herr_t status; /* Status from fractal heap 'op' routine */ /* Sanity check */ HDassert(bt2_udata->name_hash == bt2_rec->hash); +#ifdef QAK /* Prepare user data for callback */ /* down */ fh_udata.f = bt2_udata->f; @@ -302,6 +322,7 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec) /* up */ fh_udata.cmp = 0; +#endif /* QAK */ /* Check for attribute in shared storage */ if(bt2_rec->flags) @@ -310,12 +331,72 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec) fheap = bt2_udata->fheap; HDassert(fheap); +#ifdef QAK /* Check if the user's attribute and the B-tree's attribute have the same name */ status = H5HF_op(fheap, bt2_udata->dxpl_id, &bt2_rec->id, H5A_dense_fh_name_cmp, &fh_udata); HDassert(status >= 0); /* Callback will set comparison value */ ret_value = fh_udata.cmp; +#else /* QAK */ +/* XXX: This hack is due to a shared attribute and one of its components + * ending up in the same fractal heap direct block. Once John's change + * to the metadata cache that allows re-entrant read "protects" is in + * place, the previous code can be uncommented. -QAK + */ + { + H5A_t *attr; /* Pointer to attribute created from heap object */ + uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */ + void *attr_ptr; /* Pointer to serialized message */ + hbool_t took_ownership = FALSE; /* Whether the "found" operator took ownership of the attribute */ + size_t attr_size; /* Length of existing encoded attribute */ + + /* Get length of encoded attribute */ + status = H5HF_get_obj_len(fheap, bt2_udata->dxpl_id, &bt2_rec->id, &attr_size); + HDassert(status >= 0); + + /* Allocate space for serialized message, if necessary */ + if(attr_size > sizeof(attr_buf)) { + attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size); + HDassert(attr_ptr); + } /* end if */ + else + attr_ptr = attr_buf; + + /* Read the encoded attribute */ + status = H5HF_read(fheap, bt2_udata->dxpl_id, &bt2_rec->id, attr_ptr); + HDassert(status >= 0); + + /* Decode attribute information */ + attr = (H5A_t *)H5O_msg_decode(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)attr_ptr); + HDassert(attr); + + /* Release space, if we allocated it */ + if(attr_ptr != attr_buf) + (void)H5FL_BLK_FREE(ser_attr, attr_ptr); + + /* Compare the string values */ + ret_value = HDstrcmp(bt2_udata->name, attr->name); + + /* Check for correct attribute & callback to make */ + if(ret_value == 0 && bt2_udata->found_op) { + /* Check whether we should "reconstitute" the shared message info */ + if(bt2_rec->flags & H5O_MSG_FLAG_SHARED) + H5SM_reconstitute(&(attr->sh_loc), bt2_rec->id); + + /* Set the creation order index for the attribute */ + attr->crt_idx = bt2_rec->corder; + + /* Make callback */ + status = (bt2_udata->found_op)(attr, &took_ownership, bt2_udata->found_op_data); + HDassert(status >= 0); + } /* end if */ + + /* Release the space allocated for the attrbute */ + if(!took_ownership) + H5O_msg_free(H5O_ATTR_ID, attr); + } +#endif /* QAK */ } /* end else */ FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Adense.c b/src/H5Adense.c index 1dc7ad9..a1f9587 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -289,13 +289,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5A_dense_fnd_cb(const void *_attr, void *_user_attr) +H5A_dense_fnd_cb(const H5A_t *attr, hbool_t *took_ownership, void *_user_attr) { - const H5A_t *attr = (const H5A_t *)_attr; /* Record from B-tree */ - H5A_t **user_attr = (H5A_t **)_user_attr; /* User data from v2 B-tree attribute lookup */ - herr_t ret_value = SUCCEED; /* Return value */ + H5A_t const **user_attr = (H5A_t const **)_user_attr; /* User data from v2 B-tree attribute lookup */ - FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fnd_cb) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_fnd_cb) /* * Check arguments. @@ -303,12 +301,11 @@ H5A_dense_fnd_cb(const void *_attr, void *_user_attr) HDassert(attr); HDassert(user_attr); - /* Copy attribute information */ - if(NULL == (*user_attr = H5A_copy(NULL, attr))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute") + /* Take over attribute ownership */ + *user_attr = attr; + *took_ownership = TRUE; -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5A_dense_fnd_cb() */ diff --git a/src/H5Aint.c b/src/H5Aint.c index a8bcedd..953dda2 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -194,7 +194,8 @@ H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_index_t idx_type, udata.dxpl_id = dxpl_id; udata.atable = atable; udata.curr_attr = 0; - udata.bogus_crt_idx = (oh->version == H5O_VERSION_1) ? TRUE : FALSE; + udata.bogus_crt_idx = (oh->version == H5O_VERSION_1 || + !(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) ? TRUE : FALSE; /* Iterate over existing attributes, checking for attribute with same name */ op.op_type = H5O_MESG_OP_LIB; diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 8d95ce9..f5d843b 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -95,6 +95,9 @@ typedef struct H5A_dense_bt2_corder_rec_t { H5O_msg_crt_idx_t corder; /* 'creation order' field value */ } H5A_dense_bt2_corder_rec_t; +/* Define the 'found' callback function pointer for matching an attribute record in a v2 B-tree */ +typedef herr_t (*H5A_bt2_found_t)(const H5A_t *attr, hbool_t *took_ownership, void *op_data); + /* * Common data exchange structure for dense attribute storage. This structure * is passed through the v2 B-tree layer to the methods for the objects @@ -110,7 +113,7 @@ typedef struct H5A_bt2_ud_common_t { uint32_t name_hash; /* Hash of name of attribute to compare */ uint8_t flags; /* Flags for attribute storage location */ H5O_msg_crt_idx_t corder; /* Creation order value of attribute to compare */ - H5B2_found_t found_op; /* Callback when correct attribute is found */ + H5A_bt2_found_t found_op; /* Callback when correct attribute is found */ void *found_op_data; /* Callback data when correct attribute is found */ } H5A_bt2_ud_common_t; @@ -850,7 +850,6 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) f->shared->extension_addr = HADDR_UNDEF; f->shared->sohm_addr = HADDR_UNDEF; f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; - f->shared->sohm_nindexes = 0; f->shared->driver_addr = HADDR_UNDEF; f->shared->lf = lf; @@ -2909,6 +2908,34 @@ H5F_decr_nopen_objs(H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_store_msg_crt_idx + * + * Purpose: Retrieve the 'store message creation index' flag for the file. + * + * Return: Success: Non-negative, the 'store message creation index' flag + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5F_store_msg_crt_idx(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_store_msg_crt_idx) + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->store_msg_crt_idx) +} /* end H5F_store_msg_crt_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5F_block_read * * Purpose: Reads some data from a file/server/etc into a buffer. @@ -2444,6 +2444,54 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type /* Check if we increased the size of the largest block on the list */ file->maxsize = MAX(file->maxsize, last->size); + /* Check if this free block adjoins the "metadata aggregator" */ + if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA && file->eoma != 0) { + hbool_t adjoins = FALSE; /* Whether the block adjoined the metadata aggregator */ + + /* Does the new block adjoin the end of the metadata aggregator */ + if((file->eoma + file->cur_meta_block_size) == last->addr) { + last->addr = file->eoma; + adjoins = TRUE; + } /* end if */ + /* Does the new block adjoin the beginning of the metadata aggregator */ + else if((last->addr + last->size) == file->eoma) + adjoins = TRUE; + + /* Reset metadata aggregator information, if adjoined */ + if(adjoins) { +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Adjoined metadata aggregator\n", FUNC); +#endif /* H5FD_ALLOC_DEBUG */ + last->size += file->cur_meta_block_size; + file->eoma = 0; + file->cur_meta_block_size = 0; + } /* end if */ + } /* end if */ + + /* Check if this free block adjoins the "small data aggregator" */ + if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA && file->eosda != 0) { + hbool_t adjoins = FALSE; /* Whether the block adjoined the small-data aggregator */ + + /* Does the new block adjoin the end of the small-data aggregator */ + if((file->eosda + file->cur_sdata_block_size) == last->addr) { + last->addr = file->eosda; + adjoins = TRUE; + } /* end if */ + /* Does the new block adjoin the beginning of the small-data aggregator */ + else if((last->addr + last->size) == file->eosda) + adjoins = TRUE; + + /* Reset small-data aggregator information, if adjoined */ + if(adjoins) { +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Adjoined small data aggregator\n", FUNC); +#endif /* H5FD_ALLOC_DEBUG */ + last->size += file->cur_sdata_block_size; + file->eosda = 0; + file->cur_sdata_block_size = 0; + } /* end if */ + } /* end if */ + /* Check if this free block is at the end of file allocated space. * Truncate it if this is true. */ if(file->cls->get_eoa) { @@ -2451,6 +2499,9 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type eoa = file->cls->get_eoa(file, type); if(eoa == (last->addr + last->size)) { +#ifdef H5FD_ALLOC_DEBUG +HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr); +#endif /* H5FD_ALLOC_DEBUG */ if(file->cls->set_eoa(file, type, last->addr) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed") diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 616bb81..10f219f 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -72,7 +72,7 @@ typedef struct H5F_file_t { uint8_t consist_flags; /* File Consistency Flags */ unsigned flags; /* Access Permissions for file */ - /* Cached values from FCPL */ + /* Cached values from FCPL/superblock */ unsigned sym_leaf_k; /* Size of leaves in symbol tables */ unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree key values for each type */ size_t sizeof_addr; /* Size of addresses in file */ @@ -102,6 +102,7 @@ typedef struct H5F_file_t { hsize_t alignment; /* Alignment */ unsigned gc_ref; /* Garbage-collect references? */ hbool_t latest_format; /* Always use the latest format? */ + hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */ int ncwfs; /* Num entries on cwfs list */ struct H5HG_heap_t **cwfs; /* Global heap cache */ struct H5G_t *root_grp; /* Open root group */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 264218f..14e3c85 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -266,6 +266,7 @@ typedef struct H5F_t H5F_t; #define H5F_USE_LATEST_FORMAT(F) ((F)->shared->latest_format) #define H5F_INTENT(F) ((F)->intent) #define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree) +#define H5F_STORE_MSG_CRT_IDX(F) ((F)->shared->store_msg_crt_idx) #else /* H5F_PACKAGE */ #define H5F_FCPL(F) (H5F_get_fcpl(F)) #define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F)) @@ -283,6 +284,7 @@ typedef struct H5F_t H5F_t; #define H5F_USE_LATEST_FORMAT(F) (H5F_use_latest_format(F)) #define H5F_INTENT(F) (H5F_get_intent(F)) #define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F)) +#define H5F_STORE_MSG_CRT_IDX(F) (H5F_store_msg_crt_idx(F)) #endif /* H5F_PACKAGE */ @@ -446,6 +448,7 @@ H5_DLL size_t H5F_sieve_buf_size(const H5F_t *f); H5_DLL unsigned H5F_gc_ref(const H5F_t *f); H5_DLL hbool_t H5F_use_latest_format(const H5F_t *f); H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f); +H5_DLL hbool_t H5F_store_msg_crt_idx(const H5F_t *f); /* Functions that operate on blocks of bytes wrt super block */ H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, diff --git a/src/H5Gobj.c b/src/H5Gobj.c index f8bc556..81dbf2d 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -163,17 +163,17 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, size_t link_size; /* Size of a link message */ /* Calculate message size infomation, for creating group's object header */ - linfo_size = H5O_msg_mesg_size(f, H5O_LINFO_ID, linfo, (size_t)0); + linfo_size = H5O_msg_size_f(f, gcpl_id, H5O_LINFO_ID, linfo, (size_t)0); HDassert(linfo_size); - ginfo_size = H5O_msg_mesg_size(f, H5O_GINFO_ID, ginfo, (size_t)0); + ginfo_size = H5O_msg_size_f(f, gcpl_id, H5O_GINFO_ID, ginfo, (size_t)0); HDassert(ginfo_size); lnk.type = H5L_TYPE_HARD; lnk.corder = 0; lnk.corder_valid = ginfo->track_corder; lnk.name = &null_char; - link_size = H5O_msg_mesg_size(f, H5O_LINK_ID, &lnk, (size_t)ginfo->est_name_len); + link_size = H5O_msg_size_f(f, gcpl_id, H5O_LINK_ID, &lnk, (size_t)ginfo->est_name_len); HDassert(link_size); /* Compute size of header to use for creation */ @@ -887,6 +887,7 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) /* Check if we should switch from dense storage back to link messages */ if(linfo->nlinks < ginfo.min_dense) { + struct H5O_t *oh = NULL; /* Pointer to group's object header */ H5G_link_table_t ltable; /* Table of links */ hbool_t can_convert = TRUE; /* Whether converting to link messages is possible */ size_t u; /* Local index */ @@ -895,24 +896,22 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) if(H5G_dense_build_table(oloc->file, dxpl_id, linfo, H5_INDEX_NAME, H5_ITER_NATIVE, <able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links") + /* Get a pointer to the object header itself */ + if((oh = H5O_protect(oloc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect dataset object header") + /* Inspect links in table for ones that can't be converted back * into link message form (currently only links which can't fit * into an object header message) */ for(u = 0; u < linfo->nlinks; u++) - if(H5O_msg_mesg_size(oloc->file, H5O_LINK_ID, &(ltable.lnks[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) { + if(H5O_msg_size_oh(oloc->file, oh, H5O_LINK_ID, &(ltable.lnks[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) { can_convert = FALSE; break; } /* end if */ /* If ok, insert links as link messages */ if(can_convert) { - struct H5O_t *oh = NULL; /* Pointer to group's object header */ - - /* Get a pointer to the object header itself */ - if((oh = H5O_protect(oloc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect dataset object header") - /* Insert link messages into group */ for(u = 0; u < linfo->nlinks; u++) if(H5O_msg_append(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) { @@ -923,15 +922,15 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message") } /* end if */ - /* Release object header */ - if(H5O_unprotect(oloc, oh) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") - /* Remove the dense storage */ if(H5G_dense_delete(oloc->file, dxpl_id, linfo, FALSE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete dense link storage") } /* end if */ + /* Release object header */ + if(H5O_unprotect(oloc, oh) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header") + /* Free link table information */ if(H5G_link_release_table(<able) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") @@ -634,9 +634,10 @@ herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, H5O_loc_t *loc/*out*/) { - H5O_t *oh = NULL; + 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 */ + hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(H5O_create, FAIL) @@ -653,8 +654,12 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, if(NULL == (oh = H5FL_CALLOC(H5O_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Initialize rudimentary information object object header */ - oh->version = H5F_USE_LATEST_FORMAT(f) ? H5O_VERSION_LATEST : H5O_VERSION_1; + /* Initialize file-specific information for object header */ + store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f); + if(H5F_USE_LATEST_FORMAT(f) || store_msg_crt_idx) + oh->version = H5O_VERSION_LATEST; + else + oh->version = H5O_VERSION_1; oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); @@ -676,7 +681,11 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, else oh->atime = oh->mtime = oh->ctime = oh->btime = 0; - /* Initialize attribute tracking fields */ + /* Make certain attribute creation order tracking is enabled if + * attributes can be shared in this file. + */ + if(store_msg_crt_idx) + 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) diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 9637055..3e97862 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -258,8 +258,8 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) /* Increment attribute count on object */ oh->nattrs++; - /* Later versions of the object header track the creation index on all messages */ - if(oh->version > H5O_VERSION_1) { + /* Later versions of the object header track the creation index on attributes */ + if(oh->version > H5O_VERSION_1 && (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) { /* Check for attribute creation order index on the object wrapping around */ if(oh->max_attr_crt_idx == H5O_MAX_CRT_ORDER_IDX) HGOTO_ERROR(H5E_ATTR, H5E_CANTINC, FAIL, "attribute creation index can't be incremented") @@ -1145,7 +1145,7 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, hid_t dxpl_id) * can't fit into an object header message) */ for(u = 0; u < oh->nattrs; u++) - if(H5O_msg_mesg_size(loc->file, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) { + if(H5O_msg_size_oh(loc->file, oh, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) { can_convert = FALSE; break; } /* end if */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index c4430e6..7000e9e 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -150,7 +150,9 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh) } /* end for */ /* Only encode creation index for version 2+ of format */ else { - UINT16ENCODE(p, curr_msg->crt_idx); + /* Only encode creation index if they are being tracked */ + if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) + UINT16ENCODE(p, curr_msg->crt_idx); } /* end else */ HDassert(p == curr_msg->raw); @@ -262,7 +264,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, if(NULL == (oh = H5FL_CALLOC(H5O_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Generic, non-stored information */ + /* File-specific, non-stored information */ oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); @@ -326,7 +328,12 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, H5F_addr_decode(f, &p, &(oh->attr_fheap_addr)); H5F_addr_decode(f, &p, &(oh->name_bt2_addr)); H5F_addr_decode(f, &p, &(oh->corder_bt2_addr)); - UINT16DECODE(p, oh->max_attr_crt_idx); + + /* Only encode max. creation index if they are being tracked */ + if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) + UINT16DECODE(p, oh->max_attr_crt_idx) + else + oh->max_attr_crt_idx = 0; } /* end if */ else { /* Reset unused time fields */ @@ -449,17 +456,28 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, H5O_msg_crt_idx_t crt_idx = H5O_MAX_CRT_ORDER_IDX; /* Creation index for current message */ /* Decode message prefix info */ + + /* Version # */ if(oh->version == H5O_VERSION_1) UINT16DECODE(p, id) else id = *p++; + + /* Message size */ UINT16DECODE(p, mesg_size); HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size)); + + /* Message flags */ flags = *p++; + + /* Reserved bytes/creation index */ if(oh->version == H5O_VERSION_1) p += 3; /*reserved*/ - else - UINT16DECODE(p, crt_idx); + else { + /* Only encode creation index if they are being tracked */ + if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) + UINT16DECODE(p, crt_idx); + } /* end else */ /* Try to detect invalidly formatted object header message that * extends past end of chunk. @@ -675,7 +693,10 @@ H5O_assert(oh); H5F_addr_encode(f, &p, oh->attr_fheap_addr); H5F_addr_encode(f, &p, oh->name_bt2_addr); H5F_addr_encode(f, &p, oh->corder_bt2_addr); - UINT16ENCODE(p, oh->max_attr_crt_idx); + + /* Only encode max. creation index if they are being tracked */ + if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) + UINT16ENCODE(p, oh->max_attr_crt_idx); /* Chunk size */ UINT32ENCODE(p, (oh->chunk[0].size - H5O_SIZEOF_HDR(oh))); diff --git a/src/H5Omessage.c b/src/H5Omessage.c index cccf8b8..bf0d0b0 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -37,6 +37,7 @@ #include "H5Aprivate.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ +#include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ @@ -1327,7 +1328,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_msg_mesg_size + * Function: H5O_msg_size_f * * Purpose: Calculate the final size of an encoded message in an object * header. @@ -1344,12 +1345,15 @@ done: *------------------------------------------------------------------------- */ size_t -H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t extra_raw) +H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id, + const void *mesg, size_t extra_raw) { - const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ - size_t ret_value; /* Return value */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ + H5P_genplist_t *ocpl; /* Object Creation Property list */ + uint8_t oh_flags; /* Object header status flags */ + size_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_msg_mesg_size, 0) + FUNC_ENTER_NOAPI(H5O_msg_size_f, 0) /* Check args */ HDassert(type_id < NELMTS(H5O_msg_class_g)); @@ -1359,6 +1363,15 @@ H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t ext HDassert(f); HDassert(mesg); + /* Get the property list */ + if(NULL == (ocpl = H5I_object(ocpl_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, 0, "not a property list") + + /* Get any object header status flags set by properties */ + if(H5P_get(ocpl, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "can't get object header flags") + + /* Compute the raw data size for the mesg */ if((ret_value = (type->raw_size)(f, FALSE, mesg)) == 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") @@ -1370,11 +1383,64 @@ H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t ext ret_value = H5O_ALIGN_F(f, ret_value); /* Add space for message header */ - ret_value += H5O_SIZEOF_MSGHDR_F(f); + ret_value += H5O_SIZEOF_MSGHDR_F(f, + (H5F_STORE_MSG_CRT_IDX(f) || oh_flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_msg_size_f() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_msg_size_oh + * + * Purpose: Calculate the final size of an encoded message in an object + * header. + * + * Note: This routine assumes that the message is already used in + * an object header. + * + * Return: Size of message on success, 0 on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 7 2007 + * + *------------------------------------------------------------------------- + */ +size_t +H5O_msg_size_oh(const H5F_t *f, const H5O_t *oh, unsigned type_id, + const void *mesg, size_t extra_raw) +{ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ + size_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_msg_size_oh, 0) + + /* Check args */ + 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); + HDassert(type->raw_size); + HDassert(f); + HDassert(mesg); + + /* Compute the raw data size for the mesg */ + if((ret_value = (type->raw_size)(f, FALSE, mesg)) == 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message") + + /* Add in "extra" raw space */ + ret_value += extra_raw; + + /* Adjust size for alignment, if necessary */ + ret_value = H5O_ALIGN_OH(oh, ret_value); + + /* Add space for message header */ + ret_value += H5O_SIZEOF_MSGHDR_OH(oh); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_msg_mesg_size() */ +} /* end H5O_msg_size_oh() */ /*------------------------------------------------------------------------- diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 716260e..68066cf 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -120,7 +120,9 @@ (O)->sizeof_addr + /*addr of attribute heap */ \ (O)->sizeof_addr + /*addr of attribute name index */ \ (O)->sizeof_addr + /*addr of attribute creation order index */ \ - 2 + /*max attr. creation index */ \ + (((O)->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? ( \ + 2 /*max attr. creation index */ \ + ) : 0) + \ 4 + /*chunk data size */ \ H5O_SIZEOF_CHKSUM) /*checksum size */ \ ) @@ -128,7 +130,7 @@ /* * Size of object header message prefix */ -#define H5O_SIZEOF_MSGHDR_VERS(V) \ +#define H5O_SIZEOF_MSGHDR_VERS(V,C) \ (((V) == H5O_VERSION_1) \ ? \ H5O_ALIGN_OLD(2 + /*message type */ \ @@ -139,12 +141,14 @@ (1 + /*message type */ \ 2 + /*sizeof message data */ \ 1 + /*flags */ \ - 2) /*creation index */ \ + ((C) ? ( \ + 2 /*creation index */ \ + ) : 0)) \ ) #define H5O_SIZEOF_MSGHDR_OH(O) \ - H5O_SIZEOF_MSGHDR_VERS((O)->version) -#define H5O_SIZEOF_MSGHDR_F(F) \ - H5O_SIZEOF_MSGHDR_VERS(H5F_USE_LATEST_FORMAT(F) ? H5O_VERSION_LATEST : H5O_VERSION_1) + H5O_SIZEOF_MSGHDR_VERS((O)->version, (O)->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) +#define H5O_SIZEOF_MSGHDR_F(F, C) \ + H5O_SIZEOF_MSGHDR_VERS((H5F_USE_LATEST_FORMAT(F) || H5F_STORE_MSG_CRT_IDX(F)) ? H5O_VERSION_LATEST : H5O_VERSION_1, (C)) /* * Size of chunk "header" for each chunk @@ -241,7 +245,7 @@ struct H5O_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ - /* General information (not stored) */ + /* File-specific information (not stored) */ size_t sizeof_size; /* Size of file sizes */ size_t sizeof_addr; /* Size of file addresses */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 0d1f918..5349827 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -477,8 +477,10 @@ H5_DLL herr_t H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operat void *op_data, hid_t dxpl_id); H5_DLL size_t H5O_msg_raw_size(const H5F_t *f, unsigned type_id, hbool_t disable_shared, const void *mesg); -H5_DLL size_t H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, - size_t extra_raw); +H5_DLL size_t H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id, + const void *mesg, size_t extra_raw); +H5_DLL size_t H5O_msg_size_oh(const H5F_t *f, const H5O_t *oh, unsigned type_id, + const void *mesg, size_t extra_raw); H5_DLL htri_t H5O_msg_is_shared(unsigned type_id, const void *mesg); H5_DLL htri_t H5O_msg_can_share(unsigned type_id, const void *mesg); H5_DLL herr_t H5O_msg_set_share(unsigned type_id, H5O_shared_t *share, void *mesg); @@ -197,6 +197,12 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Record the address of the master table in the file */ f->shared->sohm_addr = table_addr; + /* Check for sharing attributes in this file, which means that creation + * indices must be tracked on object header message in the file. + */ + if(type_flags_used & H5O_MESG_ATTR_FLAG) + f->shared->store_msg_crt_idx = TRUE; + /* Write shared message information to the superblock extension */ sohm_table.addr = f->shared->sohm_addr; sohm_table.version = f->shared->sohm_vers; @@ -1535,6 +1541,12 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Sanity check */ HDassert(sohm_l2b == table->indexes[u].list_max); HDassert(sohm_b2l == table->indexes[u].btree_min); + + /* Check for sharing attributes in this file, which means that creation + * indices must be tracked on object header message in the file. + */ + if(index_flags[u] & H5O_MESG_ATTR_FLAG) + shared->store_msg_crt_idx = TRUE; } /* end for */ /* Set values in the property list */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index b198a37..684b9ff 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -270,7 +270,7 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t dxpl_id, hid_t tcpl_id, hid_t UNUSED loc_init = TRUE; /* Calculate message size infomation, for creating object header */ - dtype_size = H5O_msg_mesg_size(file, H5O_DTYPE_ID, type, (size_t)0); + dtype_size = H5O_msg_size_f(file, tcpl_id, H5O_DTYPE_ID, type, (size_t)0); HDassert(dtype_size); /* |