summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--src/H5Adense.c140
-rw-r--r--src/H5Atest.c4
-rw-r--r--src/H5F.c57
-rw-r--r--src/H5Fpkg.h6
-rw-r--r--src/H5Fsfile.c4
-rw-r--r--src/H5Ftest.c114
-rw-r--r--src/H5Oattribute.c28
-rwxr-xr-xsrc/H5SMpkg.h40
-rw-r--r--src/H5SMtest.c55
-rwxr-xr-xsrc/Makefile.am5
-rw-r--r--src/Makefile.in8
-rw-r--r--test/tattr.c327
13 files changed, 671 insertions, 118 deletions
diff --git a/MANIFEST b/MANIFEST
index 4189815..3e889c3 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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.
*
*-------------------------------------------------------------------------
*/
diff --git a/src/H5F.c b/src/H5F.c
index ce95665..847d912 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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 */