diff options
-rw-r--r-- | src/H5Adense.c | 229 | ||||
-rw-r--r-- | src/H5Oalloc.c | 6 | ||||
-rw-r--r-- | src/H5Oattribute.c | 7 | ||||
-rw-r--r-- | src/H5Omessage.c | 15 | ||||
-rwxr-xr-x | src/H5SM.c | 6 | ||||
-rw-r--r-- | test/tattr.c | 27 |
6 files changed, 207 insertions, 83 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c index d235512..c5de1a9 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -87,6 +87,7 @@ typedef struct { typedef struct H5A_bt2_od_wrt_t { /* downward */ H5HF_t *fheap; /* Fractal heap handle to operate on */ + H5HF_t *shared_fheap; /* Fractal heap handle for shared messages */ hid_t dxpl_id; /* DXPL for operation */ void *attr_buf; /* Pointer to encoded attribute to store */ size_t attr_size; /* Size of encode attribute */ @@ -101,6 +102,7 @@ typedef struct { H5F_t *f; /* Pointer to file that fractal heap is in */ hid_t dxpl_id; /* DXPL for operation */ H5HF_t *fheap; /* Fractal heap handle */ + H5HF_t *shared_fheap; /* Fractal heap handle for shared messages */ /* downward (from application) */ hid_t loc_id; /* Object ID for application callback */ @@ -115,7 +117,8 @@ typedef struct { /* * Data exchange structure to pass through the fractal heap layer for the - * H5HF_op function when iterating over densely stored attributes. + * H5HF_op function when copying an attribute stored in densely stored attributes. + * (or the shared object heap) */ typedef struct { /* downward (internal) */ @@ -124,7 +127,7 @@ typedef struct { /* upward */ H5A_t *attr; /* Copy of attribute */ -} H5A_fh_ud_it_t; +} H5A_fh_ud_cp_t; /* * Data exchange structure to pass through the fractal heap layer for the @@ -137,6 +140,7 @@ typedef struct { } H5A_fh_ud_rm_t; + /********************/ /* Package Typedefs */ /********************/ @@ -558,6 +562,8 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) { H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + htri_t attr_sharable; /* Flag indicating attributes are sharable */ H5A_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(H5A_dense_open, NULL) @@ -573,11 +579,28 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap") + /* Check if attributes are shared in this file */ + if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't determine if attributes are shared") + + /* Get handle for shared object heap, if attributes are sharable */ + if(attr_sharable) { + haddr_t shared_fheap_addr; /* Address of fractal heap to use */ + + /* Retrieve the address of the shared object's fractal heap */ + if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't get shared object heap address") + + /* Open the fractal heap for shared header messages */ + if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap") + } /* end if */ + /* Create the "udata" information for v2 B-tree record modify */ udata.f = f; udata.dxpl_id = dxpl_id; udata.fheap = fheap; - udata.shared_fheap = NULL; + udata.shared_fheap = shared_fheap; udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; @@ -591,6 +614,8 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) done: /* Release resources */ + if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, NULL, "can't close fractal heap") @@ -661,7 +686,6 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags, HDassert(attr_sharable); /* Get the shared information for the attribute */ - HDmemset(&sh_mesg, 0, sizeof(sh_mesg)); if(NULL == H5O_attr_get_share(attr, &sh_mesg)) HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message") @@ -728,7 +752,7 @@ done: /*------------------------------------------------------------------------- * Function: H5A_dense_write_cb * - * Purpose: v2 B-tree modify callback to update the data for an attribute + * Purpose: v2 B-tree 'find' callback to update the data for an attribute * * Return: Success: 0 * Failure: 1 @@ -739,10 +763,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5A_dense_write_cb(void *_record, void *_op_data, hbool_t *changed) +H5A_dense_write_cb(const void *_record, void *_op_data) { - H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */ + const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */ H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */ + H5HF_t *fheap; /* Fractal heap handle for attribute storage */ + hbool_t id_changed = FALSE; /* Whether the heap ID changed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_write_cb) @@ -752,39 +778,28 @@ H5A_dense_write_cb(void *_record, void *_op_data, hbool_t *changed) */ HDassert(record); HDassert(op_data); - HDassert(changed); /* Check for modifying shared attribute */ - if(record->flags & H5O_MSG_FLAG_SHARED) { -/* XXX: fix me */ -HDfprintf(stderr, "%s: modifying shared attributes in dense storage not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "modifying shared attributes in dense storage not supported yet") - } /* end if */ + if(record->flags & H5O_MSG_FLAG_SHARED) + fheap = op_data->shared_fheap; + else + fheap = op_data->fheap; -/* XXX: Add "write" routine (or allow "op" routine to modify values) to - * fractal heap code - */ /* Sanity check */ #ifndef NDEBUG { size_t obj_len; /* Length of existing encoded attribute */ - if(H5HF_get_obj_len(op_data->fheap, op_data->dxpl_id, record->id, &obj_len) < 0) + if(H5HF_get_obj_len(fheap, op_data->dxpl_id, record->id, &obj_len) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get object size") HDassert(obj_len == op_data->attr_size); } #endif /* NDEBUG */ - /* Remove existing attribute from heap */ - if(H5HF_remove(op_data->fheap, op_data->dxpl_id, record->id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from heap") - - /* Insert new encoded attribute into heap */ - if(H5HF_insert(op_data->fheap, op_data->dxpl_id, op_data->attr_size, op_data->attr_buf, record->id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to insert attribute in heap") - - /* Indicate that the B-tree record has changed */ -/* (XXX:We won't need this once we can write to an existing fractal heap object) */ - *changed = TRUE; + /* Update existing attribute in heap */ + /* (would be more efficient as fractal heap 'op' callback, but leave that for later -QAK) */ + /* (Casting away const OK - QAK) */ + if(H5HF_write(fheap, op_data->dxpl_id, (void *)record->id, &id_changed, op_data->attr_buf) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in heap") done: FUNC_LEAVE_NOAPI(ret_value) @@ -809,8 +824,8 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr) { H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5A_bt2_od_wrt_t op_data; /* "Op data" for v2 B-tree modify */ - H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ size_t attr_size; /* Size of serialized attribute in the heap */ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */ void *attr_ptr = NULL; /* Pointer to serialized attribute */ @@ -875,14 +890,15 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr) udata.found_op = NULL; udata.found_op_data = NULL; - /* Create the "op_data" for the v2 B-tree record modify */ + /* Create the "op_data" for the v2 B-tree record 'find' callback */ op_data.fheap = fheap; + op_data.shared_fheap = shared_fheap; op_data.dxpl_id = dxpl_id; op_data.attr_buf = attr_ptr; op_data.attr_size = attr_size; /* Modify attribute through 'name' tracking v2 B-tree */ - if(H5B2_modify(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_write_cb, &op_data) < 0) + if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_write_cb, &op_data) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree") done: @@ -899,10 +915,10 @@ done: /*------------------------------------------------------------------------- - * Function: H5A_dense_iterate_fh_cb + * Function: H5A_dense_copy_fh_cb * - * Purpose: Callback for fractal heap operator, to make user's callback - * when iterating over attributes + * Purpose: Callback for fractal heap operator, to make copy of attribute + * for calling routine * * Return: SUCCEED/FAIL * @@ -913,12 +929,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5A_dense_iterate_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) +H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) { - H5A_fh_ud_it_t *udata = (H5A_fh_ud_it_t *)_udata; /* User data for fractal heap 'op' callback */ + H5A_fh_ud_cp_t *udata = (H5A_fh_ud_cp_t *)_udata; /* User data for fractal heap 'op' callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5A_dense_iterate_fh_cb) + FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_fh_cb) /* Decode attribute information & keep a copy */ /* (we make a copy instead of calling the user/library callback directly in @@ -932,7 +948,7 @@ H5A_dense_iterate_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_dense_iterate_fh_cb() */ +} /* end H5A_dense_copy_fh_cb() */ /*------------------------------------------------------------------------- @@ -961,14 +977,14 @@ H5A_dense_iterate_bt2_cb(const void *_record, void *_bt2_udata) if(bt2_udata->skip > 0) --bt2_udata->skip; else { - H5A_fh_ud_it_t fh_udata; /* User data for fractal heap 'op' callback */ + H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */ + H5HF_t *fheap; /* Fractal heap handle for attribute storage */ /* Check for iterating over shared attribute */ - if(record->flags & H5O_MSG_FLAG_SHARED) { -/* XXX: fix me */ -HDfprintf(stderr, "%s: iterating over shared attributes in dense storage not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, H5_ITER_ERROR, "iterating over shared attributes in dense storage not supported yet") - } /* end if */ + if(record->flags & H5O_MSG_FLAG_SHARED) + fheap = bt2_udata->shared_fheap; + else + fheap = bt2_udata->fheap; /* Prepare user data for callback */ /* down */ @@ -976,8 +992,8 @@ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, H5_ITER_ERROR, "iterating over shared att fh_udata.dxpl_id = bt2_udata->dxpl_id; /* Call fractal heap 'op' routine, to copy the attribute information */ - if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id, - H5A_dense_iterate_fh_cb, &fh_udata) < 0) + if(H5HF_op(fheap, bt2_udata->dxpl_id, record->id, + H5A_dense_copy_fh_cb, &fh_udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, H5_ITER_ERROR, "heap op callback failed") /* Check which type of callback to make */ @@ -1029,6 +1045,8 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr { H5A_bt2_ud_it_t udata; /* User data for iterator callback */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + htri_t attr_sharable; /* Flag indicating attributes are sharable */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5A_dense_iterate, FAIL) @@ -1059,10 +1077,28 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr if(NULL == (fheap = H5HF_open(f, dxpl_id, attr_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Check if attributes are shared in this file */ + if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared") + + /* Get handle for shared object heap, if attributes are sharable */ + if(attr_sharable) { + haddr_t shared_fheap_addr; /* Address of fractal heap to use */ + + /* Retrieve the address of the shared object's fractal heap */ + if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address") + + /* Open the fractal heap for shared header messages */ + if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + } /* end if */ + /* Construct the user data for v2 B-tree iterator callback */ udata.f = f; udata.dxpl_id = dxpl_id; udata.fheap = fheap; + udata.shared_fheap = shared_fheap; udata.loc_id = loc_id; udata.skip = skip; udata.count = 0; @@ -1081,6 +1117,8 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr done: /* Release resources */ + if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") @@ -1146,30 +1184,52 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_bt2_udata) { const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; H5A_bt2_ud_common_t *bt2_udata = (H5A_bt2_ud_common_t *)_bt2_udata; /* User data for callback */ - H5A_fh_ud_rm_t fh_udata; /* User data for fractal heap 'op' callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_remove_bt2_cb) /* Check for inserting shared attribute */ if(record->flags & H5O_MSG_FLAG_SHARED) { -/* XXX: fix me */ -HDfprintf(stderr, "%s: removing shared attributes in dense storage not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "removing shared attributes in dense storage not supported yet") + H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */ + H5O_shared_t sh_mesg; /* Shared object header message */ + + /* Set up the user data for fractal heap 'op' callback */ + fh_udata.f = bt2_udata->f; + fh_udata.dxpl_id = bt2_udata->dxpl_id; + fh_udata.attr = NULL; + + /* Call fractal heap 'op' routine, to get copy of the attribute */ + if(H5HF_op(bt2_udata->shared_fheap, bt2_udata->dxpl_id, record->id, + H5A_dense_copy_fh_cb, &fh_udata) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "attribute removal callback failed") + + /* Get the shared information for the attribute */ + if(NULL == H5O_attr_get_share(fh_udata.attr, &sh_mesg)) + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message") + + /* Decrement the reference count on the shared attribute message */ + if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &sh_mesg) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute") + + /* Release the space allocated for the attribute */ + H5O_msg_free(H5O_ATTR_ID, fh_udata.attr); } /* end if */ + else { + H5A_fh_ud_rm_t fh_udata; /* User data for fractal heap 'op' callback */ - /* Set up the user data for fractal heap 'op' callback */ - fh_udata.f = bt2_udata->f; - fh_udata.dxpl_id = bt2_udata->dxpl_id; + /* Set up the user data for fractal heap 'op' callback */ + fh_udata.f = bt2_udata->f; + fh_udata.dxpl_id = bt2_udata->dxpl_id; - /* Call fractal heap 'op' routine, to perform user callback */ - if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id, - H5A_dense_remove_fh_cb, &fh_udata) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "attribute removal callback failed") + /* Call fractal heap 'op' routine, to perform user callback */ + if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id, + H5A_dense_remove_fh_cb, &fh_udata) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "attribute removal callback failed") - /* Remove record from fractal heap */ - if(H5HF_remove(bt2_udata->fheap, bt2_udata->dxpl_id, record->id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from fractal heap") + /* Remove record from fractal heap */ + if(H5HF_remove(bt2_udata->fheap, bt2_udata->dxpl_id, record->id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from fractal heap") + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1192,8 +1252,10 @@ done: herr_t H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) { - H5HF_t *fheap = NULL; /* Fractal heap handle */ H5A_bt2_ud_common_t udata; /* User data for v2 B-tree record removal */ + H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + htri_t attr_sharable; /* Flag indicating attributes are sharable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5A_dense_remove, FAIL) @@ -1209,11 +1271,28 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Check if attributes are shared in this file */ + if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared") + + /* Get handle for shared object heap, if attributes are sharable */ + if(attr_sharable) { + haddr_t shared_fheap_addr; /* Address of fractal heap to use */ + + /* Retrieve the address of the shared object's fractal heap */ + if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address") + + /* Open the fractal heap for shared header messages */ + if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + } /* end if */ + /* Set up the user data for the v2 B-tree 'record remove' callback */ udata.f = f; udata.dxpl_id = dxpl_id; udata.fheap = fheap; - udata.shared_fheap = NULL; + udata.shared_fheap = shared_fheap; udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; @@ -1227,6 +1306,8 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) done: /* Release resources */ + if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") @@ -1253,6 +1334,8 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) { H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ + htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI(H5A_dense_exists, NULL) @@ -1268,11 +1351,28 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + /* Check if attributes are shared in this file */ + if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared") + + /* Get handle for shared object heap, if attributes are sharable */ + if(attr_sharable) { + haddr_t shared_fheap_addr; /* Address of fractal heap to use */ + + /* Retrieve the address of the shared object's fractal heap */ + if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address") + + /* Open the fractal heap for shared header messages */ + if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + } /* end if */ + /* Create the "udata" information for v2 B-tree record 'find' */ udata.f = f; udata.dxpl_id = dxpl_id; udata.fheap = fheap; - udata.shared_fheap = NULL; + udata.shared_fheap = shared_fheap; udata.name = name; udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0); udata.flags = 0; @@ -1280,7 +1380,6 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) udata.found_op = NULL; /* v2 B-tree comparison callback */ udata.found_op_data = NULL; -/* XXX: test for shared attributes */ /* Find the attribute in the 'name' index */ if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, NULL, NULL) < 0) { /* Assume that the failure was just not finding the attribute & clear stack */ @@ -1291,6 +1390,8 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) done: /* Release resources */ + if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(fheap && H5HF_close(fheap, dxpl_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index 9e824d0..1368e84 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -940,11 +940,11 @@ H5O_release_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_mesg_t *mesg, /* Free any space referred to in the file from this message */ if(H5O_delete_mesg(f, dxpl_id, mesg, adj_link) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message") - - /* Free any native information */ - H5O_msg_free_mesg(mesg); } /* end if */ + /* Free any native information */ + H5O_msg_free_mesg(mesg); + /* Change message type to nil and zero it */ mesg->type = H5O_MSG_NULL; HDassert(mesg->raw + mesg->raw_size <= (oh->chunk[mesg->chunkno].image + oh->chunk[mesg->chunkno].size) - (H5O_SIZEOF_CHKSUM_OH(oh) + oh->chunk[mesg->chunkno].gap)); diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index aaf91f6..038bed1 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -188,7 +188,8 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage") /* Convert message into a null message in the header */ - if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE, FALSE) < 0) + /* (don't delete attribute's space in the file though) */ + if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, FALSE, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message") /* Indicate that the object header was modified */ @@ -225,6 +226,9 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_create) +#ifdef QAK +HDfprintf(stderr, "%s: adding attribute, attr->name = '%s'\n", FUNC, attr->name); +#endif /* QAK */ /* Check arguments */ HDassert(loc); @@ -242,7 +246,6 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, FAIL, "unable to load object header") #ifdef QAK -HDfprintf(stderr, "%s: adding attribute to new-style object header\n", FUNC); HDfprintf(stderr, "%s: oh->nattrs = %Hu\n", FUNC, oh->nattrs); HDfprintf(stderr, "%s: oh->max_compact = %u\n", FUNC, oh->max_compact); HDfprintf(stderr, "%s: oh->min_dense = %u\n", FUNC, oh->min_dense); diff --git a/src/H5Omessage.c b/src/H5Omessage.c index 0fafac7..3648d49 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -1801,13 +1801,13 @@ H5O_msg_copy_file(const H5O_msg_class_t *copy_type, const H5O_msg_class_t *mesg_ /* Check if this message is committed. We'll need to know this later. */ committed = FALSE; if(copy_type->id == H5O_SHARED_ID) { - H5O_shared_t *shared_mesg = (H5O_shared_t *) native_src; + H5O_shared_t *tmp_shared_mesg = (H5O_shared_t *) native_src; - if( shared_mesg->flags & H5O_COMMITTED_FLAG) { - HDassert(!(shared_mesg->flags & H5O_SHARED_IN_HEAP_FLAG)); + if( tmp_shared_mesg->flags & H5O_COMMITTED_FLAG) { + HDassert(!(tmp_shared_mesg->flags & H5O_SHARED_IN_HEAP_FLAG)); committed = TRUE; - } - } + } /* end if */ + } /* end if */ /* The copy_file callback will return an H5O_shared_t only if the message * to be copied is a committed datatype. @@ -1852,10 +1852,11 @@ H5O_msg_copy_file(const H5O_msg_class_t *copy_type, const H5O_msg_class_t *mesg_ } ret_value = native_mesg; + done: - if(NULL == ret_value) { + if(NULL == ret_value) H5O_msg_free(mesg_type->id, native_mesg); - } + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_msg_copy_file() */ @@ -892,7 +892,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg) +H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, + const H5O_shared_t *sh_mesg) { H5SM_master_table_t *table = NULL; unsigned cache_flags = H5AC__NO_FLAGS_SET; @@ -984,7 +985,8 @@ H5SM_find_in_list(H5F_t *f, H5SM_list_t *list, const H5SM_mesg_key_t *key) *------------------------------------------------------------------------- */ static herr_t -H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, unsigned type_id, const H5O_shared_t * mesg, unsigned *cache_flags) +H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header, + unsigned type_id, const H5O_shared_t * mesg, unsigned *cache_flags) { H5SM_list_t *list = NULL; H5SM_mesg_key_t key; diff --git a/test/tattr.c b/test/tattr.c index 04350a8..964773e 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -1706,7 +1706,7 @@ test_attr_dense_create(hid_t fcpl, hid_t fapl) MESSAGE(5, ("Testing Dense Attribute Storage Creation\n")); /* Create file */ - fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); CHECK(fid, FAIL, "H5Fcreate"); /* Create dataspace for dataset */ @@ -1812,7 +1812,7 @@ test_attr_dense_open(hid_t fcpl, hid_t fapl) MESSAGE(5, ("Testing Opening Attributes in Dense Storage\n")); /* Create file */ - fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); CHECK(fid, FAIL, "H5Fcreate"); /* Create dataspace for dataset */ @@ -1933,7 +1933,7 @@ test_attr_dense_delete(hid_t fcpl, hid_t fapl) MESSAGE(5, ("Testing Deleting Attributes in Dense Storage\n")); /* Create file */ - fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); CHECK(fid, FAIL, "H5Fcreate"); /* Create dataspace for dataset */ @@ -1983,6 +1983,23 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); + /* Close Dataset */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Open dataset */ + dataset = H5Dopen(fid, DSET1_NAME); + CHECK(dataset, FAIL, "H5Dopen"); + /* Delete attributes until the attributes revert to compact storage again */ for(u--; u >= min_dense; u--) { /* Delete attribute */ @@ -2099,12 +2116,12 @@ test_attr(void) hid_t my_fcpl; /* Set the FCPL for shared or not */ - if(new_format) { + if(use_shared) { MESSAGE(7, ("testing with shared attributes\n")); my_fcpl = fcpl2; } /* end if */ else { - MESSAGE(7, ("testing with shared attributes\n")); + MESSAGE(7, ("testing without shared attributes\n")); my_fcpl = fcpl; } /* end else */ |