diff options
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | src/H5Adense.c | 140 | ||||
-rw-r--r-- | src/H5Atest.c | 4 | ||||
-rw-r--r-- | src/H5F.c | 57 | ||||
-rw-r--r-- | src/H5Fpkg.h | 6 | ||||
-rw-r--r-- | src/H5Fsfile.c | 4 | ||||
-rw-r--r-- | src/H5Ftest.c | 114 | ||||
-rw-r--r-- | src/H5Oattribute.c | 28 | ||||
-rwxr-xr-x | src/H5SMpkg.h | 40 | ||||
-rw-r--r-- | src/H5SMtest.c | 55 | ||||
-rwxr-xr-x | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/Makefile.in | 8 | ||||
-rw-r--r-- | test/tattr.c | 327 |
13 files changed, 671 insertions, 118 deletions
@@ -472,6 +472,7 @@ ./src/H5Fpkg.h ./src/H5Fprivate.h ./src/H5Fpublic.h +./src/H5Ftest.c ./src/H5FD.c ./src/H5FDcore.c ./src/H5FDcore.h diff --git a/src/H5Adense.c b/src/H5Adense.c index 9d9746a..6c0a907 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -38,6 +38,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Apkg.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ @@ -123,16 +124,6 @@ typedef struct { H5A_t *attr; /* Copy of attribute */ } H5A_fh_ud_cp_t; -/* - * Data exchange structure to pass through the fractal heap layer for the - * H5HF_op function when removing an attribute from densely stored attributes. - */ -typedef struct { - /* downward */ - H5F_t *f; /* Pointer to file that fractal heap is in */ - hid_t dxpl_id; /* DXPL for operation */ -} H5A_fh_ud_rm_t; - /********************/ /* Package Typedefs */ @@ -1055,14 +1046,8 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_bt2_udata) /* Check for inserting shared attribute */ if(record->flags & H5O_MSG_FLAG_SHARED) { - H5O_shared_t sh_mesg; /* Shared object header message */ - - /* Get the shared information for the attribute */ - if(NULL == H5O_attr_get_share(*(H5A_t **)bt2_udata->found_op_data, &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) + if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &((*(H5A_t **)bt2_udata->found_op_data)->sh_loc)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute") } /* end if */ else { @@ -1159,7 +1144,6 @@ done: if(attr_copy) H5O_msg_free_real(H5O_MSG_ATTR, attr_copy); - FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_remove() */ @@ -1249,6 +1233,70 @@ done: /*------------------------------------------------------------------------- + * Function: H5A_dense_delete_bt2_cb + * + * Purpose: v2 B-tree callback for dense attribute storage deletion + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jan 3 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5A_dense_delete_bt2_cb(const void *_record, void *_bt2_udata) +{ + const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */ + H5A_bt2_ud_common_t *bt2_udata = (H5A_bt2_ud_common_t *)_bt2_udata; /* User data for callback */ + H5HF_t *fheap; /* Fractal heap handle for attribute storage */ + H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5A_dense_delete_bt2_cb) + + /* Check for shared attribute */ + if(record->flags & H5O_MSG_FLAG_SHARED) + fheap = bt2_udata->shared_fheap; + else + fheap = bt2_udata->fheap; + + /* Prepare user data for callback */ + /* down */ + fh_udata.f = bt2_udata->f; + fh_udata.dxpl_id = bt2_udata->dxpl_id; + fh_udata.record = record; + /* up */ + fh_udata.attr = NULL; + + /* Call fractal heap 'op' routine, to copy the attribute information */ + if(H5HF_op(fheap, bt2_udata->dxpl_id, record->id, H5A_dense_copy_fh_cb, &fh_udata) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "heap op callback failed") + + /* Check for shared attribute */ + if(record->flags & H5O_MSG_FLAG_SHARED) { + /* Decrement the reference count on the shared attribute message */ + if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &(fh_udata.attr->sh_loc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute") + } /* end if */ + else { + /* Perform the deletion action on the attribute */ + /* (takes care of shared & committed datatype/dataspace components) */ + if(H5O_attr_delete(bt2_udata->f, bt2_udata->dxpl_id, fh_udata.attr, TRUE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end else */ + +done: + /* Release resources */ + if(fh_udata.attr) + H5O_msg_free_real(H5O_MSG_ATTR, fh_udata.attr); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_dense_delete_bt2_cb() */ + + +/*------------------------------------------------------------------------- * Function: H5A_dense_delete * * Purpose: Delete all dense storage structures for attributes on an object @@ -1264,6 +1312,10 @@ done: herr_t H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh) { + H5A_bt2_ud_common_t udata; /* v2 B-tree user data for deleting attributes */ + 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_delete, FAIL) @@ -1274,20 +1326,66 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh) HDassert(f); HDassert(oh); -/* XXX: iterate through name index v2 B-tree and delete shared attributes */ -/* XXX: we need to delete shared & unshared attributes that use shared & committed components also */ + /* Open the fractal heap */ + 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 'delete' */ + udata.f = f; + udata.dxpl_id = dxpl_id; + udata.fheap = fheap; + udata.shared_fheap = shared_fheap; + udata.name = NULL; + udata.name_hash = 0; + udata.flags = 0; + udata.corder = -1; /* XXX: None yet */ + udata.found_op = NULL; /* v2 B-tree comparison callback */ + udata.found_op_data = NULL; /* Delete name index v2 B-tree */ - if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, NULL, NULL) < 0) + if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, H5A_dense_delete_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index") oh->name_bt2_addr = HADDR_UNDEF; + /* Release resources */ + if(shared_fheap) { + if(H5HF_close(shared_fheap, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + shared_fheap = NULL; + } /* end if */ + if(H5HF_close(fheap, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + fheap = NULL; + /* Delete fractal heap */ if(H5HF_delete(f, dxpl_id, oh->attr_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete fractal heap") oh->attr_fheap_addr = HADDR_UNDEF; 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") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_delete() */ diff --git a/src/H5Atest.c b/src/H5Atest.c index 80348e8..b2ee0d5 100644 --- a/src/H5Atest.c +++ b/src/H5Atest.c @@ -14,11 +14,11 @@ /*------------------------------------------------------------------------- * - * Created: H5Aint.c + * Created: H5Atest.c * Dec 18 2006 * Quincey Koziol <koziol@hdfgroup.org> * - * Purpose: Internal routines for managing attributes. + * Purpose: Attribute testing routines. * *------------------------------------------------------------------------- */ @@ -150,8 +150,6 @@ done: * Programmer: Robb Matzke * Friday, February 19, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ int @@ -161,8 +159,8 @@ H5F_term_interface(void) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_term_interface) - if (H5_interface_initialize_g) { - if ((n=H5I_nmembers(H5I_FILE))!=0) { + if(H5_interface_initialize_g) { + if((n = H5I_nmembers(H5I_FILE)) != 0) { H5I_clear_type(H5I_FILE, FALSE); } else { /* Make certain we've cleaned up all the shared file objects */ @@ -171,10 +169,11 @@ H5F_term_interface(void) H5I_dec_type_ref(H5I_FILE); H5_interface_initialize_g = 0; n = 1; /*H5I*/ - } - } + } /* end else */ + } /* end if */ + FUNC_LEAVE_NOAPI(n) -} +} /* H5F_term_interface() */ /*------------------------------------------------------------------------- @@ -190,40 +189,31 @@ H5F_term_interface(void) * * Programmer: Unknown * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Calls H5P_copy_plist() to copy the property list and H5P_close() to free - * that property list if an error occurs. - * - * Raymond Lu, Oct 14, 2001 - * Changed to generic property list. - * *------------------------------------------------------------------------- */ hid_t H5Fget_create_plist(hid_t file_id) { - H5F_t *file = NULL; - H5P_genplist_t *plist; /* Property list */ - hid_t ret_value; + H5F_t *file; /* File info */ + H5P_genplist_t *plist; /* Property list */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_create_plist, FAIL) H5TRACE1("i", "i", file_id); /* check args */ - if (NULL==(file=H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") if(NULL == (plist = H5I_object(file->shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the property list object to return */ - if((ret_value=H5P_copy_plist(plist)) < 0) + if((ret_value = H5P_copy_plist(plist)) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties") done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Fget_create_plist() */ /*------------------------------------------------------------------------- @@ -245,36 +235,19 @@ done: * Programmer: Robb Matzke * Wednesday, February 18, 1998 * - * Modifications: - * Raymond Lu, Oct 23, 2001 - * Changed file access property list to the new generic - * property list. - * - * Bill Wendling, Apr 21, 2003 - * Fixed bug where the driver ID and info in the property - * list were being overwritten but the original ID and info - * weren't being close. - * - * J Mainzer, Mar 10, 2005 - * Updated function for changes in the property list entries - * used by the new metadata cache. - * - * Quincey Koziol, May 25, 2005 - * Extracted guts into new internal routine. - * *------------------------------------------------------------------------- */ hid_t H5Fget_access_plist(hid_t file_id) { - H5F_t *f = NULL; - hid_t ret_value = SUCCEED; + H5F_t *f; /* File info */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_access_plist, FAIL) H5TRACE1("i", "i", file_id); /* Check args */ - if (NULL==(f=H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (f = H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* Retrieve the file's access property list */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index a58c413..957ec0a 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -195,5 +195,11 @@ H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared); H5_DLL H5F_file_t * H5F_sfile_search(H5FD_t *lf); H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared); +/* Testing functions */ +#ifdef H5F_TESTING +H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id, + size_t *mesg_count); +#endif /* H5F_TESTING */ + #endif /* _H5Fpkg_H */ diff --git a/src/H5Fsfile.c b/src/H5Fsfile.c index e269776..85df5f6 100644 --- a/src/H5Fsfile.c +++ b/src/H5Fsfile.c @@ -41,7 +41,7 @@ H5F_sfile_node_t *H5F_sfile_head_g = NULL; /*------------------------------------------------------------------------- - * Function: H5F_sfile_assert_empty + * Function: H5F_sfile_assert_num * * Purpose: Sanity checking that shared file list is empty * @@ -82,7 +82,7 @@ H5F_sfile_assert_num(unsigned n) HDassert(count == n); } /* end else */ - FUNC_LEAVE_NOAPI(SUCCEED); + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_sfile_assert_num() */ diff --git a/src/H5Ftest.c b/src/H5Ftest.c new file mode 100644 index 0000000..5fbb737 --- /dev/null +++ b/src/H5Ftest.c @@ -0,0 +1,114 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ftest.c + * Jan 3 2007 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: File testing routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5F_TESTING /*suppress warning about H5F testing funcs*/ +#define H5SM_PACKAGE /*suppress error about including H5SMpkg */ +#define H5SM_TESTING /*suppress warning about H5SM testing funcs*/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5Iprivate.h" /* IDs */ +#include "H5SMpkg.h" /* Shared object header messages */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_sohm_mesg_count_test + * + * Purpose: Retrieve the number of shared messages of a given type in a file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Jan 3, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_sohm_mesg_count_test(hid_t file_id, unsigned type_id, + size_t *mesg_count) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_get_sohm_mesg_count_test) + + /* Check arguments */ + if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + + /* Retrieve count for message type */ + if(H5SM_get_mesg_count_test(file, H5AC_ind_dxpl_id, type_id, mesg_count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve shared message count") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_sohm_mesg_count_test() */ + diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index b3b19d4..287f5c6 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -1142,10 +1142,6 @@ H5O_attr_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") -/* XXX: fix me */ -HDfprintf(stderr, "%s: removing a shared attribute not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "deleting a shared attribute not supported yet") -#ifdef NOT_YET /* Check for correct attribute message to modify */ if(HDstrcmp(shared_attr.name, udata->name) == 0) /* Indicate that this message is the attribute to be deleted */ @@ -1153,7 +1149,6 @@ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "deleting a shared attribute not su /* Release copy of shared attribute */ H5O_attr_reset(&shared_attr); -#endif /* NOT_YET */ } /* end if */ else { /* Check for correct attribute message to modify */ @@ -1275,15 +1270,22 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* If ok, insert attributes as object header messages */ if(can_convert) { - /* Insert attribute messages into object header */ - /* (Set the "shared" message flag for all attributes added - - * attributes that are actually shared will be converted - * to shared messages and attributes that are not shared - * will have the flag turned off -QAK) - */ - for(u = 0; u < oh->nattrs; u++) - if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, H5O_MSG_FLAG_SHARED, H5O_UPDATE_TIME, &(atable.attrs[u]), &oh_flags) < 0) + /* Iterate over attributes, to put them into header */ + for(u = 0; u < oh->nattrs; u++) { + htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ + unsigned mesg_flags = 0; /* Message flags for attribute */ + + /* Should this message be written as a SOHM? */ + if((shared_mesg = H5SM_try_share(loc->file, dxpl_id, H5O_ATTR_ID, &(atable.attrs[u]))) > 0) + /* Mark the message as shared */ + mesg_flags |= H5O_MSG_FLAG_SHARED; + else if(shared_mesg < 0) + HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") + + /* Insert attribute message into object header */ + if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, mesg_flags, H5O_UPDATE_TIME, &(atable.attrs[u]), &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message") + } /* end for */ /* Remove the dense storage */ if(H5A_dense_delete(loc->file, dxpl_id, oh) < 0) diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index 760f6a2..1f790fe 100755 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -97,36 +97,36 @@ /* Typedef for a SOHM index node */ typedef struct { - uint32_t hash; /* Hash value for OHM */ - H5SM_fheap_id_t fheap_id; /* ID of the OHM in the fractal heap */ - hsize_t ref_count; /* Number of times this message is used */ + uint32_t hash; /* Hash value for OHM */ + H5SM_fheap_id_t fheap_id; /* ID of the OHM in the fractal heap */ + hsize_t ref_count; /* Number of times this message is used */ } H5SM_sohm_t; typedef enum { - H5SM_BADTYPE = -1, - H5SM_LIST, /* Index is an unsorted list */ - H5SM_BTREE /* Index is a sorted B-tree */ + H5SM_BADTYPE = -1, + H5SM_LIST, /* Index is an unsorted list */ + H5SM_BTREE /* Index is a sorted B-tree */ } H5SM_index_type_t; /* Typedef for searching an index (list or B-tree) */ typedef struct { - uint32_t hash; /* The hash value for this message */ - const void *encoding; /* The message encoded */ - size_t encoding_size; /* Size of the encoding */ - H5HF_t *fheap; /* The heap for this message type, open. */ - H5SM_fheap_id_t mesg_heap_id; /* The heap_id for this message */ + uint32_t hash; /* The hash value for this message */ + const void *encoding; /* The message encoded */ + size_t encoding_size; /* Size of the encoding */ + H5HF_t *fheap; /* The heap for this message type, open. */ + H5SM_fheap_id_t mesg_heap_id; /* The heap_id for this message */ } H5SM_mesg_key_t; /* Typedef for a SOHM index header */ typedef struct { - unsigned mesg_types; /* Bit flag vector of message types */ - size_t min_mesg_size; /* number of messages being tracked */ - size_t list_max; /* >= this many messages, index with a B-tree */ - size_t btree_min; /* <= this many messages, index with a list again */ - size_t num_messages; /* number of messages being tracked */ - H5SM_index_type_t index_type; /* Is the index a list or a B-tree? */ - haddr_t index_addr; /* Address of the actual index (list or B-tree) */ - haddr_t heap_addr; /* Address of the fheap used to store shared messages */ + unsigned mesg_types; /* Bit flag vector of message types */ + size_t min_mesg_size; /* number of messages being tracked */ + size_t list_max; /* >= this many messages, index with a B-tree */ + size_t btree_min; /* <= this many messages, index with a list again */ + size_t num_messages; /* number of messages being tracked */ + H5SM_index_type_t index_type; /* Is the index a list or a B-tree? */ + haddr_t index_addr; /* Address of the actual index (list or B-tree) */ + haddr_t heap_addr; /* Address of the fheap used to store shared messages */ } H5SM_index_header_t; /* Typedef for a SOHM list */ @@ -209,6 +209,8 @@ H5_DLL herr_t H5SM_get_hash_fh_cb(const void *obj, size_t obj_len, void *_udata) #ifdef H5SM_TESTING H5_DLL herr_t H5SM_get_refcount_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, const H5O_shared_t *sh_mesg, hsize_t *ref_count); +H5_DLL herr_t H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, + size_t *mesg_count); #endif /* H5SM_TESTING */ #endif /* _H5SMpkg_H */ diff --git a/src/H5SMtest.c b/src/H5SMtest.c index d2ca5d3..20a23e9 100644 --- a/src/H5SMtest.c +++ b/src/H5SMtest.c @@ -194,3 +194,58 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM_get_refcount_test() */ + +/*------------------------------------------------------------------------- + * Function: H5SM_get_mesg_count_test + * + * Purpose: Retrieve the number of messages tracked of a certain type + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, January 3, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, + size_t *mesg_count) +{ + H5SM_master_table_t *table = NULL; /* SOHM master table */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5SM_get_mesg_count_test) + + /* Sanity check */ + HDassert(f); + HDassert(mesg_count); + + /* Check for shared messages being enabled */ + if(H5F_addr_defined(f->shared->sohm_addr)) { + H5SM_index_header_t *header; /* Index header for message type */ + ssize_t index_num; /* Table index for message type */ + + /* Look up the master SOHM table */ + if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + + /* Find the correct index and try to delete from it */ + if((index_num = H5SM_get_index(table, type_id)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") + header = &(table->indexes[index_num]); + + /* Set the message count for the type */ + *mesg_count = header->num_messages; + } /* end if */ + else + /* No shared messages of any type */ + *mesg_count = 0; + +done: + /* Release resources */ + if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5SM_get_mesg_count_test() */ + diff --git a/src/Makefile.am b/src/Makefile.am index 099f76a..4976735 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,8 +46,9 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c H5D.c H5Dcompact.c H5Dcontig.c \ H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ - H5E.c H5F.c \ - H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ + H5E.c \ + H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \ + H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 879d560..3f66871 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -87,7 +87,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5B2test.lo H5C.lo H5CS.lo H5D.lo H5Dcompact.lo H5Dcontig.lo \ H5Defl.lo H5Dio.lo H5Distore.lo H5Dmpio.lo H5Doh.lo \ H5Dselect.lo H5Dtest.lo H5E.lo H5F.lo H5Fdbg.lo H5Ffake.lo \ - H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo \ + H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5Ftest.lo H5FD.lo H5FDcore.lo \ H5FDdirect.lo H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \ H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ @@ -404,8 +404,9 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c H5D.c H5Dcompact.c H5Dcontig.c \ H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ - H5E.c H5F.c \ - H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ + H5E.c \ + H5F.c H5Fdbg.c H5Ffake.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5Ftest.c \ + H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \ @@ -621,6 +622,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ftest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5G.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gbtree2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gcompact.Plo@am__quote@ diff --git a/test/tattr.c b/test/tattr.c index 92f0c56..cc0200d 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -40,6 +40,14 @@ #define H5A_TESTING #include "H5Apkg.h" /* Attributes */ +/* + * This file needs to access private information from the H5F package. + * This file also needs to access the file testing code. + */ +#define H5F_PACKAGE +#define H5F_TESTING +#include "H5Fpkg.h" /* File access */ + #define FILENAME "tattr.h5" #define NAME_BUF_SIZE 1024 #define ATTR_NAME_LEN 16 @@ -1581,8 +1589,7 @@ test_attr_dtype_shared(hid_t fapl) /* Check reference count on named datatype */ ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf); CHECK(ret, FAIL, "H5Gget_objinfo"); -/* JAMES: this becomes 2 VERIFY(statbuf.nlink, 3, "H5Acreate"); -*/ + VERIFY(statbuf.nlink, 3, "H5Acreate"); /* Close attribute */ ret=H5Aclose(attr_id); CHECK(ret, FAIL, "H5Aclose"); @@ -1603,8 +1610,8 @@ test_attr_dtype_shared(hid_t fapl) /* Check reference count on named datatype */ ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf); CHECK(ret, FAIL, "H5Gget_objinfo"); -/* JAMES: this becomes 2 VERIFY(statbuf.nlink, 3, "H5Acreate"); -*/ + VERIFY(statbuf.nlink, 3, "H5Acreate"); + /* Write data into the attribute */ ret=H5Awrite(attr_id,H5T_NATIVE_INT,&data); CHECK(ret, FAIL, "H5Awrite"); @@ -1866,14 +1873,10 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); +/* XXX: Add similar check to other tests that use new storage */ /* Check size of file */ filesize = h5_get_file_size(FILENAME); -#ifdef LATER VERIFY(filesize, empty_filesize, "h5_get_file_size"); -#else /* LATER */ -/* XXX: Add similar check to other tests that use new storage */ -HDfprintf(stderr, "Check skipped - fix after ISOHM code deletes empty indices\n"); -#endif /* LATER */ } /* test_attr_dense_create() */ /**************************************************************** @@ -2109,6 +2112,18 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); /* Verify attributes still left */ test_attr_dense_verify(dataset, (u - 1)); + /* Delete another attribute, to verify deletion in compact storage */ + sprintf(attrname, "attr %02u", (u - 1)); + ret = H5Adelete(dataset, attrname); + CHECK(ret, FAIL, "H5Adelete"); + + /* Check on dataset's attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Verify attributes still left */ + test_attr_dense_verify(dataset, (u - 2)); + /* Close Dataset */ ret = H5Dclose(dataset); CHECK(ret, FAIL, "H5Dclose"); @@ -2254,6 +2269,115 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); /**************************************************************** ** +** test_attr_dense_unlink(): Test basic H5A (attribute) code. +** Tests unlinking object with attributes in "dense" storage +** +****************************************************************/ +static void +test_attr_dense_unlink(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* HDF5 File ID */ + hid_t dataset; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hid_t attr; /* Attribute ID */ + hid_t dcpl; /* Dataset creation property list ID */ + char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned max_compact; /* Maximum # of attributes to store compactly */ + unsigned min_dense; /* Minimum # of attributes to store "densely" */ + htri_t is_dense; /* Are attributes stored densely? */ + unsigned u; /* Local index variable */ + int attr_count; /* # of attributes */ + size_t mesg_count; /* # of shared messages */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Unlinking Object with Attributes in Dense Storage\n")); + + /* Create file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataspace for dataset */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Query the group creation properties */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + + /* Create a dataset */ + dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dataset, FAIL, "H5Dcreate"); + + /* Retrieve limits for compact/dense attribute storage */ + ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); + CHECK(ret, FAIL, "H5Pget_attr_phase_change"); +#ifdef QAK +HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); +#endif /* QAK */ + + /* Check on dataset's attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Add attributes, until well into dense storage */ + for(u = 0; u < (max_compact * 2); u++) { + /* Create attribute */ + sprintf(attrname, "attr %02u", u); + attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Write data into the attribute */ + ret = H5Awrite(attr, H5T_NATIVE_UINT, &u); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Check # of attributes */ + attr_count = H5Aget_num_attrs(dataset); + CHECK(attr_count, FAIL, "H5Aget_num_attrs"); + VERIFY(attr_count, (int)(u + 1), "H5Aget_num_attrs"); + } /* end for */ + + /* Check on dataset's attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset); + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + /* Close dataspace */ + 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"); + + /* Unlink dataset */ + ret = H5Gunlink(fid, DSET1_NAME); + CHECK(ret, FAIL, "H5Gunlink"); + + /* Check on dataset's attribute storage status */ + ret = H5F_get_sohm_mesg_count_test(fid, H5O_ATTR_ID, &mesg_count); + CHECK(ret, FAIL, "H5F_get_sohm_mesg_count_test"); + VERIFY(mesg_count, 0, "H5F_get_sohm_mesg_count_test"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_dense_unlink() */ + +/**************************************************************** +** ** test_attr_shared_write(): Test basic H5A (attribute) code. ** Tests writing to shared attributes in "compact" & "dense" storage ** @@ -2395,7 +2519,6 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* test_attr_shared_write() */ -#endif /* QAK */ /**************************************************************** ** @@ -2628,6 +2751,182 @@ HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); } /* test_attr_shared_rename() */ +#endif /* QAK */ + +/**************************************************************** +** +** test_attr_shared_delete(): Test basic H5A (attribute) code. +** Tests deleting shared attributes in "compact" & "dense" storage +** +****************************************************************/ +static void +test_attr_shared_delete(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* HDF5 File ID */ + hid_t dataset, dataset2; /* Dataset ID2 */ + hid_t sid; /* Dataspace ID */ + hid_t attr; /* Attribute ID */ + hid_t dcpl; /* Dataset creation property list ID */ + char attrname[NAME_BUF_SIZE]; /* Name of attribute on first dataset */ + unsigned max_compact; /* Maximum # of attributes to store compactly */ + unsigned min_dense; /* Minimum # of attributes to store "densely" */ + htri_t is_dense; /* Are attributes stored densely? */ + htri_t is_shared; /* Is attributes shared? */ + hsize_t shared_refcount; /* Reference count of shared attribute */ + unsigned attr_value; /* Attribute value */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Deleting Shared Attributes in Compact & Dense Storage\n")); + + /* Create file */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataspace for dataset */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Set up to query the object creation properties */ + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + + /* Create datasets */ + dataset = H5Dcreate(fid, DSET1_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dataset, FAIL, "H5Dcreate"); + dataset2 = H5Dcreate(fid, DSET2_NAME, H5T_NATIVE_UCHAR, sid, dcpl); + CHECK(dataset2, FAIL, "H5Dcreate"); + + /* Retrieve limits for compact/dense attribute storage */ + ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense); + CHECK(ret, FAIL, "H5Pget_attr_phase_change"); +#ifdef QAK +HDfprintf(stderr, "max_compact = %u, min_dense = %u\n", max_compact, min_dense); +#endif /* QAK */ + + /* Check on datasets' attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + is_dense = H5O_is_attr_dense_test(dataset2); + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + + /* Add attributes to each dataset, until after converting to dense storage */ +/* XXX: Test with shared & committed datatype/dataspace also */ + for(u = 0; u < max_compact * 2; u++) { + /* Create attribute name */ + sprintf(attrname, "attr %02u", u); + + /* Create attribute on first dataset */ + attr = H5Acreate(dataset, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Check that attribute is shared */ + is_shared = H5A_is_shared_test(attr); + VERIFY(is_shared, TRUE, "H5A_is_shared_test"); + + /* Check refcount for attribute */ + ret = H5A_get_shared_rc_test(attr, &shared_refcount); + CHECK(ret, FAIL, "H5A_get_shared_rc_test"); + VERIFY(shared_refcount, 1, "H5A_get_shared_rc_test"); + + /* Write data into the attribute */ + attr_value = u + 1; + ret = H5Awrite(attr, H5T_NATIVE_UINT, &attr_value); + CHECK(ret, FAIL, "H5Awrite"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Check on dataset's attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset); + if(u < max_compact) + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + else + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + + + /* Create attribute on second dataset */ + attr = H5Acreate(dataset2, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT); + CHECK(attr, FAIL, "H5Acreate"); + + /* Check that attribute is shared */ + is_shared = H5A_is_shared_test(attr); + VERIFY(is_shared, TRUE, "H5A_is_shared_test"); + + /* Check refcount for attribute */ + ret = H5A_get_shared_rc_test(attr, &shared_refcount); + CHECK(ret, FAIL, "H5A_get_shared_rc_test"); + VERIFY(shared_refcount, 1, "H5A_get_shared_rc_test"); + + /* Write data into the attribute */ + attr_value = u + 1; + ret = H5Awrite(attr, H5T_NATIVE_UINT, &attr_value); + CHECK(ret, FAIL, "H5Awrite"); + + /* Check refcount for attribute */ + ret = H5A_get_shared_rc_test(attr, &shared_refcount); + CHECK(ret, FAIL, "H5A_get_shared_rc_test"); + VERIFY(shared_refcount, 2, "H5A_get_shared_rc_test"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + + /* Check on dataset's attribute storage status */ + is_dense = H5O_is_attr_dense_test(dataset2); + if(u < max_compact) + VERIFY(is_dense, FALSE, "H5O_is_attr_dense_test"); + else + VERIFY(is_dense, TRUE, "H5O_is_attr_dense_test"); + } /* end for */ + + /* Delete attributes from second dataset */ + for(u = 0; u < max_compact * 2; u++) { + /* Create attribute name */ + sprintf(attrname, "attr %02u", u); + + /* Delete second dataset's attribute */ + ret = H5Adelete(dataset2, attrname); + CHECK(ret, FAIL, "H5Adelete"); + + + /* Check refcount on attributes now */ + + /* Check refcount on first dataset's attribute */ + attr = H5Aopen_name(dataset, attrname); + CHECK(attr, FAIL, "H5Aopen_name"); + + /* Check that attribute is shared */ + is_shared = H5A_is_shared_test(attr); + VERIFY(is_shared, TRUE, "H5A_is_shared_test"); + + /* Check refcount for attribute */ + ret = H5A_get_shared_rc_test(attr, &shared_refcount); + CHECK(ret, FAIL, "H5A_get_shared_rc_test"); + VERIFY(shared_refcount, 1, "H5A_get_shared_rc_test"); + + /* Close attribute */ + ret = H5Aclose(attr); + CHECK(ret, FAIL, "H5Aclose"); + } /* end for */ + + + /* Close dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close Datasets */ + ret = H5Dclose(dataset); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(dataset2); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_attr_shared_delete() */ /**************************************************************** ** @@ -2732,14 +3031,14 @@ test_attr(void) test_attr_dense_open(my_fcpl, fapl2); /* Test opening attributes in dense storage */ test_attr_dense_delete(my_fcpl, fapl2); /* Test deleting attributes in dense storage */ test_attr_dense_rename(my_fcpl, fapl2); /* Test renaming attributes in dense storage */ -/* XXX: Remove attribute */ -/* XXX: Unlink object */ + test_attr_dense_unlink(my_fcpl, fapl2); /* Test unlinking object with attributes in dense storage */ } /* end for */ /* Tests with both "new format" and "shared" attributes */ test_attr_shared_write(fcpl2, fapl2); /* Test writing to shared attributes in compact & dense storage */ - test_attr_shared_rename(fcpl2, fapl2); /* Test writing to shared attributes in compact & dense storage */ -/* XXX: Removing attribute */ + test_attr_shared_rename(fcpl2, fapl2); /* Test renaming shared attributes in compact & dense storage */ + test_attr_shared_delete(fcpl2, fapl2); /* Test deleting shared attributes in compact & dense storage */ +/* XXX: Unlinking object */ #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ |