summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
commita1708eb023f2c8f8ac6c2c17bf1e598c8dff956e (patch)
tree34c87a3753b36c4c8d689d58bf456eaf261cd235 /src/H5O.c
parentbea1e576c5ef5500678f7ce913d835341b625e8f (diff)
downloadhdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.zip
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.gz
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.bz2
[svn-r11712] Purpose:
New feature Description: Check in baseline for compact group revisions, which radically revises the source code for managing groups and object headers. WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! This initiates the "unstable" phase of the 1.7.x branch, leading up to the 1.8.0 release. Please test this code, but do _NOT_ keep files created with it - the format will change again before the release and you will not be able to read your old files!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! Solution: There's too many changes to really describe them all, but some of them include: - Stop abusing the H5G_entry_t structure and split it into two separate structures for non-symbol table node use within the library: H5O_loc_t for object locations in a file and H5G_name_t to store the path to an opened object. H5G_entry_t is now only used for storing symbol table entries on disk. - Retire H5G_namei() in favor of a more general mechanism for traversing group paths and issuing callbacks on objects located. This gets us out of the business of hacking H5G_namei() for new features, generally. - Revised H5O* routines to take a H5O_loc_t instead of H5G_entry_t - Lots more... Platforms tested: h5committested and maybe another dozen configurations.... :-)
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c3172
1 files changed, 1634 insertions, 1538 deletions
diff --git a/src/H5O.c b/src/H5O.c
index 7522b4a..0f2ae87 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -20,8 +20,6 @@
*
* Purpose: Object header virtual functions.
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
@@ -33,20 +31,38 @@
#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
-#include "H5Iprivate.h" /* IDs */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
-#include "H5Pprivate.h" /* Property lists */
#ifdef H5_HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif /* H5_HAVE_GETTIMEOFDAY */
+/* Local macros */
+
+/* Load native information for a message, if it's not already present */
+/* (Only works for messages with decode callback) */
+#define LOAD_NATIVE(F, DXPL, MSG) \
+ if(NULL == (MSG)->native) { \
+ const H5O_class_t *decode_type; \
+ \
+ /* Check for shared message */ \
+ if ((MSG)->flags & H5O_FLAG_SHARED) \
+ decode_type = H5O_SHARED; \
+ else \
+ decode_type = (MSG)->type; \
+ \
+ /* Decode the message */ \
+ HDassert(decode_type->decode); \
+ if(NULL == ((MSG)->native = (decode_type->decode)((F), (DXPL), (MSG)->raw))) \
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") \
+ } /* end if */
+
/* Private typedefs */
/* User data for iteration while removing a message */
@@ -64,39 +80,114 @@ typedef struct {
typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx,
unsigned * oh_flags_ptr, void *operator_data/*in,out*/);
+/*
+ * This table contains a list of object types, descriptions, and the
+ * functions that determine if some object is a particular type. The table
+ * is allocated dynamically.
+ */
+typedef struct H5O_typeinfo_t {
+ H5G_obj_t type; /*one of the public H5G_* types */
+ htri_t (*isa)(H5O_loc_t*, hid_t); /*function to determine type */
+ char *desc; /*description of object type */
+} H5O_typeinfo_t;
+
/* Node in skip list to map addresses from one file to another during object header copy */
typedef struct H5O_addr_map_t {
haddr_t src_addr; /* Address of object in source file */
haddr_t dst_addr; /* Address of object in destination file */
+ hbool_t is_locked; /* Indicate that the destination object is locked currently */
+ hsize_t inc_ref_count; /* Number of deferred increments to reference count */
} H5O_addr_map_t;
+/* Package variables */
+
+/* ID to type mapping */
+const H5O_class_t *const message_type_g[] = {
+ H5O_NULL, /*0x0000 Null */
+ H5O_SDSPACE, /*0x0001 Simple Dimensionality */
+ H5O_LINFO, /*0x0002 Link information */
+ H5O_DTYPE, /*0x0003 Data Type */
+ H5O_FILL, /*0x0004 Old data storage -- fill value */
+ H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */
+ H5O_LINK, /*0x0006 Link */
+ H5O_EFL, /*0x0007 Data storage -- external data files */
+ H5O_LAYOUT, /*0x0008 Data Layout */
+#ifdef H5O_ENABLE_BOGUS
+ H5O_BOGUS, /*0x0009 "Bogus" */
+#else /* H5O_ENABLE_BOGUS */
+ NULL, /*0x0009 "Bogus" */
+#endif /* H5O_ENABLE_BOGUS */
+ H5O_GINFO, /*0x000A Group Information */
+ H5O_PLINE, /*0x000B Data storage -- filter pipeline */
+ H5O_ATTR, /*0x000C Attribute list */
+ H5O_NAME, /*0x000D Object name */
+ H5O_MTIME, /*0x000E Object modification date and time */
+ H5O_SHARED, /*0x000F Shared header message */
+ H5O_CONT, /*0x0010 Object header continuation */
+ H5O_STAB, /*0x0011 Symbol table */
+ H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
+};
+
+/* Declare a free list to manage the H5O_t struct */
+H5FL_DEFINE(H5O_t);
+
+/* Declare a free list to manage the H5O_mesg_t sequence information */
+H5FL_SEQ_DEFINE(H5O_mesg_t);
+
+/* Declare a free list to manage the H5O_chunk_t sequence information */
+H5FL_SEQ_DEFINE(H5O_chunk_t);
+
+/* Declare a free list to manage the chunk image information */
+H5FL_BLK_DEFINE(chunk_image);
+
+/* Library private variables */
+
+/* Local variables */
+static H5O_typeinfo_t *H5O_type_g = NULL; /*object typing info */
+static size_t H5O_ntypes_g = 0; /*entries in type table */
+static size_t H5O_atypes_g = 0; /*entries allocated */
+
+/* Declare external the free list for time_t's */
+H5FL_EXTERN(time_t);
+
+/* Declare extern the free list for H5O_cont_t's */
+H5FL_EXTERN(H5O_cont_t);
+
+/* Declare a free list to manage the H5O_addr_map_t struct */
+H5FL_DEFINE_STATIC(H5O_addr_map_t);
+
/* PRIVATE PROTOTYPES */
-static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
- H5G_entry_t *ent/*out*/, haddr_t header);
+static herr_t H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t),
+ const char *_desc);
+static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint,
+ H5O_loc_t *loc/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_class_t *type, void *native);
-static herr_t H5O_free_mesg(H5O_mesg_t *mesg);
static void * H5O_copy_real(const H5O_class_t *type, const void *mesg,
void *dst);
-static int H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type,
+static int H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type,
hid_t dxpl_id);
-static htri_t H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type,
- int sequence, hid_t dxpl_id);
+static htri_t H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type,
+ int sequence, hid_t dxpl_id);
#ifdef NOT_YET
static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
H5HG_t *hobj/*out*/);
#endif /* NOT_YET */
static unsigned H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t **type_p, int sequence);
-static int H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type,
+static int H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type,
int overwrite, unsigned flags, unsigned update_flags, const void *mesg,
hid_t dxpl_id);
static int H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t *type, unsigned flags, const void *mesg,
unsigned * oh_flags_ptr);
-static herr_t H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type,
+static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type,
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
static unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t *type, size_t size, hbool_t * oh_dirtied_ptr);
+static htri_t H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static htri_t H5O_merge_null(H5F_t *f, H5O_t *oh);
+static htri_t H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
static htri_t H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh,
unsigned chunkno, size_t size, unsigned * msg_idx);
static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
@@ -111,121 +202,185 @@ static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags,
static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
const void *mesg, unsigned flags, unsigned update_flags,
unsigned * oh_flags_ptr);
-static herr_t H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type,
+static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type,
H5AC_protect_t prot, hbool_t internal, void *op, void *op_data, hid_t dxpl_id);
static void * H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
-static herr_t H5O_post_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
- const void *mesg_src, H5G_entry_t *loc_dst,
- hid_t dxpl_id, H5SL_t *map_list);
-static herr_t H5O_copy_header_real(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
+static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
-/* Metadata cache callbacks */
-static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
- void *_udata2);
-static herr_t H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh);
-static herr_t H5O_dest(H5F_t *f, H5O_t *oh);
-static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy);
-static herr_t H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr);
-
-/* H5O inherits cache-like properties from H5AC */
-static const H5AC_class_t H5AC_OHDR[1] = {{
- H5AC_OHDR_ID,
- (H5AC_load_func_t)H5O_load,
- (H5AC_flush_func_t)H5O_flush,
- (H5AC_dest_func_t)H5O_dest,
- (H5AC_clear_func_t)H5O_clear,
- (H5AC_size_func_t)H5O_compute_size,
-}};
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, September 28, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_init(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
-/* ID to type mapping */
-static const H5O_class_t *const message_type_g[] = {
- H5O_NULL, /*0x0000 Null */
- H5O_SDSPACE, /*0x0001 Simple Dimensionality */
- NULL, /*0x0002 Data space (fiber bundle?) */
- H5O_DTYPE, /*0x0003 Data Type */
- H5O_FILL, /*0x0004 Old data storage -- fill value */
- H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */
- NULL, /*0x0006 Data storage -- compact object */
- H5O_EFL, /*0x0007 Data storage -- external data files */
- H5O_LAYOUT, /*0x0008 Data Layout */
-#ifdef H5O_ENABLE_BOGUS
- H5O_BOGUS, /*0x0009 "Bogus" */
-#else /* H5O_ENABLE_BOGUS */
- NULL, /*0x0009 "Bogus" */
-#endif /* H5O_ENABLE_BOGUS */
- NULL, /*0x000A Not assigned */
- H5O_PLINE, /*0x000B Data storage -- filter pipeline */
- H5O_ATTR, /*0x000C Attribute list */
- H5O_NAME, /*0x000D Object name */
- H5O_MTIME, /*0x000E Object modification date and time */
- H5O_SHARED, /*0x000F Shared header message */
- H5O_CONT, /*0x0010 Object header continuation */
- H5O_STAB, /*0x0011 Symbol table */
- H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
-};
+ FUNC_ENTER_NOAPI(H5O_init, FAIL)
+ /* FUNC_ENTER() does all the work */
-/* Library private variables */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_init() */
-/*
- * An array of functions indexed by symbol table entry cache type
- * (H5G_type_t) that are called to retrieve constant messages cached in the
- * symbol table entry.
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_init_interface
+ *
+ * Purpose: Initialize the H5O interface.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
*/
-static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *,
- const H5O_class_t *,
- void *);
+static herr_t
+H5O_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_interface)
-/* Declare a free list to manage the H5O_t struct */
-H5FL_DEFINE_STATIC(H5O_t);
+ /*
+ * Initialize the type info table. Begin with the most general types and
+ * end with the most specific. For instance, any object that has a data
+ * type message is a datatype but only some of them are datasets.
+ */
+ H5O_register_type(H5G_TYPE, H5T_isa, "datatype");
+ H5O_register_type(H5G_GROUP, H5G_isa, "group");
+ H5O_register_type(H5G_DATASET, H5D_isa, "dataset");
-/* Declare a free list to manage the H5O_mesg_t sequence information */
-H5FL_SEQ_DEFINE_STATIC(H5O_mesg_t);
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_init_interface() */
-/* Declare a free list to manage the H5O_chunk_t sequence information */
-H5FL_SEQ_DEFINE_STATIC(H5O_chunk_t);
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_term_interface
+ *
+ * Purpose: Terminates the H5O interface
+ *
+ * Return: Success: Positive if anything is done that might
+ * affect other interfaces; zero otherwise.
+ *
+ * Failure: Negative.
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5O_term_interface(void)
+{
+ int n = 0;
-/* Declare a free list to manage the chunk image information */
-H5FL_BLK_DEFINE_STATIC(chunk_image);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_term_interface)
-/* Declare external the free list for time_t's */
-H5FL_EXTERN(time_t);
+ if(H5_interface_initialize_g) {
+ size_t u;
-/* Declare extern the free list for H5O_cont_t's */
-H5FL_EXTERN(H5O_cont_t);
+ /* Empty the object type table */
+ for(u = 0; u < H5O_ntypes_g; u++)
+ H5MM_xfree(H5O_type_g[u].desc);
+ H5O_ntypes_g = H5O_atypes_g = 0;
+ H5O_type_g = H5MM_xfree(H5O_type_g);
-/* Declare a free list to manage the H5O_addr_map_t struct */
-H5FL_DEFINE_STATIC(H5O_addr_map_t);
+ /* Mark closed */
+ H5_interface_initialize_g = 0;
+ n = 1; /*H5O*/
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* H5O_term_interface() */
/*-------------------------------------------------------------------------
- * Function: H5O_init_interface
+ * Function: H5O_register_type
*
- * Purpose: Initialize the H5O interface.
+ * Purpose: Register a new object type so H5O_get_type() can detect it.
+ * One should always register a general type before a more
+ * specific type. For instance, any object that has a datatype
+ * message is a datatype, but only some of those objects are
+ * datasets.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Success: Non-negative
*
- * Programmer: Robb Matzke
- * Tuesday, January 6, 1998
+ * Failure: Negative
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_init_interface(void)
+H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t), const char *_desc)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_interface);
+ char *desc = NULL;
+ size_t i;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_register_type)
+
+ HDassert(type >= 0);
+ HDassert(isa);
+ HDassert(_desc);
+
+ /* Copy the description */
+ if(NULL == (desc = H5MM_strdup(_desc)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for object type description")
/*
- * Initialize functions that decode messages from symbol table entries.
+ * If the type is already registered then just update its entry without
+ * moving it to the end
*/
- H5O_fast_g[H5G_CACHED_STAB] = H5O_stab_fast;
+ for(i = 0; i < H5O_ntypes_g; i++) {
+ if (H5O_type_g[i].type == type) {
+ H5O_type_g[i].isa = isa;
+ H5MM_xfree(H5O_type_g[i].desc);
+ H5O_type_g[i].desc = desc;
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+ } /* end for */
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ /* Increase table size */
+ if(H5O_ntypes_g >= H5O_atypes_g) {
+ size_t n = MAX(32, 2 * H5O_atypes_g);
+ H5O_typeinfo_t *x = H5MM_realloc(H5O_type_g, n * sizeof(H5O_typeinfo_t));
+
+ if (!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for objec type table")
+ H5O_atypes_g = n;
+ H5O_type_g = x;
+ } /* end if */
+
+ /* Add a new entry */
+ H5O_type_g[H5O_ntypes_g].type = type;
+ H5O_type_g[H5O_ntypes_g].isa = isa;
+ H5O_type_g[H5O_ntypes_g].desc = desc; /*already copied*/
+ H5O_ntypes_g++;
+
+done:
+ if(ret_value < 0)
+ H5MM_xfree(desc);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_register_type() */
/*-------------------------------------------------------------------------
@@ -246,47 +401,38 @@ H5O_init_interface(void)
* matzke@llnl.gov
* Aug 5 1997
*
- * Modifications:
- *
- * Bill Wendling, 1. November 2002
- * Separated the create function into two different functions. One
- * which allocates space and an initialization function which
- * does the rest of the work (initializes, caches, and opens the
- * object header).
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/)
+H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/)
{
haddr_t header;
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI(H5O_create, FAIL);
+ FUNC_ENTER_NOAPI(H5O_create, FAIL)
/* check args */
- assert(f);
- assert(ent);
+ HDassert(f);
+ HDassert(loc);
- size_hint = H5O_ALIGN (MAX (H5O_MIN_SIZE, size_hint));
+ size_hint = H5O_ALIGN(MAX(H5O_MIN_SIZE, size_hint));
/* allocate disk space for header and first chunk */
- if (HADDR_UNDEF == (header = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id,
- (hsize_t)H5O_SIZEOF_HDR(f) + size_hint)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "file allocation failed for object header header");
+ if(HADDR_UNDEF == (header = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id,
+ (hsize_t)H5O_SIZEOF_HDR(f) + size_hint)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header header")
/* initialize the object header */
- if (H5O_init(f, dxpl_id, size_hint, ent, header) != SUCCEED)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header");
+ if(H5O_new(f, dxpl_id, size_hint, loc, header) != SUCCEED)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_create() */
/*-------------------------------------------------------------------------
- * Function: H5O_init
+ * Function: H5O_new
*
* Purpose: Initialize a new object header, sets the link count to 0,
* and caches the header. The object header is opened for
@@ -301,35 +447,28 @@ done:
* Programmer: Bill Wendling
* 1, November 2002
*
- * Modifications:
- *
- * JRM -- 6/6/05
- * Removed code modifying the is_dirty field of the
- * cache_info. This field is now managed by the cache
- * proper.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header)
+H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/, haddr_t header)
{
H5O_t *oh = NULL;
haddr_t tmp_addr;
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_init);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_new)
/* check args */
- assert(f);
- assert(ent);
+ HDassert(f);
+ HDassert(loc);
size_hint = H5O_ALIGN(MAX(H5O_MIN_SIZE, size_hint));
- ent->file = f;
- ent->header = header;
+ loc->file = f;
+ loc->addr = header;
/* allocate the object header and fill in header fields */
- if (NULL == (oh = H5FL_MALLOC(H5O_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh = H5FL_MALLOC(H5O_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
oh->version = H5O_VERSION;
oh->nlink = 0;
@@ -338,23 +477,23 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->nchunks = 1;
oh->alloc_nchunks = H5O_NCHUNKS;
- if (NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- tmp_addr = ent->header + (hsize_t)H5O_SIZEOF_HDR(f);
+ tmp_addr = loc->addr + (hsize_t)H5O_SIZEOF_HDR(f);
oh->chunk[0].dirty = TRUE;
oh->chunk[0].addr = tmp_addr;
oh->chunk[0].size = size_hint;
- if (NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, size_hint)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, size_hint)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* create the message list and initialize the first message */
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
- if (NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
oh->mesg[0].type = H5O_NULL;
oh->mesg[0].dirty = TRUE;
@@ -364,21 +503,21 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->mesg[0].chunkno = 0;
/* cache it */
- if (H5AC_set(f, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header");
+ if(H5AC_set(f, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header")
/* open it */
- if (H5O_open(ent) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header");
+ if(H5O_open(loc) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header")
done:
- if(ret_value<0 && oh) {
- if(H5O_dest(f,oh)<0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
+ if(ret_value < 0 && oh) {
+ if(H5O_dest(f, oh) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_new() */
/*-------------------------------------------------------------------------
@@ -392,32 +531,30 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_open(const H5G_entry_t *obj_ent)
+H5O_open(const H5O_loc_t *loc)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_open, FAIL);
+ FUNC_ENTER_NOAPI(H5O_open, FAIL)
/* Check args */
- assert(obj_ent);
- assert(obj_ent->file);
+ HDassert(loc);
+ HDassert(loc->file);
#ifdef H5O_DEBUG
if (H5DEBUG(O))
- HDfprintf(H5DEBUG(O), "> %a\n", obj_ent->header);
+ HDfprintf(H5DEBUG(O), "> %a\n", loc->addr);
#endif
/* Increment open-lock counters */
- obj_ent->file->nopen_objs++;
+ loc->file->nopen_objs++;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_open() */
/*-------------------------------------------------------------------------
@@ -430,565 +567,51 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_close(H5G_entry_t *obj_ent)
+H5O_close(H5O_loc_t *loc)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_close, FAIL);
+ FUNC_ENTER_NOAPI(H5O_close, FAIL)
/* Check args */
- assert(obj_ent);
- assert(obj_ent->file);
- assert(obj_ent->file->nopen_objs > 0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(loc->file->nopen_objs > 0);
/* Decrement open-lock counters */
- --obj_ent->file->nopen_objs;
+ --loc->file->nopen_objs;
#ifdef H5O_DEBUG
if (H5DEBUG(O)) {
- if (obj_ent->file->file_id < 0 && 1==obj_ent->file->shared->nrefs) {
+ if(loc->file->file_id < 0 && 1 == loc->file->shared->nrefs) {
HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n",
- obj_ent->header,
- (unsigned long)(obj_ent->file->nopen_objs));
+ loc->addr,
+ (unsigned long)(loc->file->nopen_objs));
} else {
- HDfprintf(H5DEBUG(O), "< %a\n", obj_ent->header);
+ HDfprintf(H5DEBUG(O), "< %a\n", loc->addr);
}
- }
+ } /* end if */
#endif
/*
* If the file open object count has reached the number of open mount points
* (each of which has a group open in the file) attempt to close the file.
*/
- if(obj_ent->file->nopen_objs == obj_ent->file->mtab.nmounts) {
+ if(loc->file->nopen_objs == loc->file->mtab.nmounts) {
/* Attempt to close down the file hierarchy */
- if(H5F_try_close(obj_ent->file) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
+ if(H5F_try_close(loc->file) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
} /* end if */
- /* Free the ID to name buffers */
- H5G_free_ent_name(obj_ent);
-
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_close() */
/*-------------------------------------------------------------------------
- * Function: H5O_load
- *
- * Purpose: Loads an object header from disk.
- *
- * Return: Success: Pointer to the new object header.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 5 1997
- *
- * Modifications:
- *
- * Robb Matzke, 1997-08-30
- * Plugged memory leaks that occur during error handling.
- *
- * Robb Matzke, 1998-01-07
- * Able to distinguish between constant and variable messages.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static H5O_t *
-H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
- void UNUSED * _udata2)
-{
- H5O_t *oh = NULL;
- H5O_t *ret_value;
- uint8_t buf[16], *p;
- size_t mesg_size;
- size_t hdr_size;
- unsigned id;
- int mesgno;
- unsigned curmesg = 0, nmesgs;
- unsigned chunkno;
- haddr_t chunk_addr;
- size_t chunk_size;
- uint8_t flags;
-
- FUNC_ENTER_NOAPI(H5O_load, NULL);
-
- /* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(!_udata1);
- assert(!_udata2);
-
- /* allocate ohdr and init chunk list */
- if (NULL==(oh = H5FL_CALLOC(H5O_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* read fixed-lenth part of object header */
- hdr_size = H5O_SIZEOF_HDR(f);
- assert(hdr_size<=sizeof(buf));
- if (H5F_block_read(f, H5FD_MEM_OHDR, addr, hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header");
- p = buf;
-
- /* decode version */
- oh->version = *p++;
- if (H5O_VERSION != oh->version)
- HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number");
-
- /* reserved */
- p++;
-
- /* decode number of messages */
- UINT16DECODE(p, nmesgs);
-
- /* decode link count */
- UINT32DECODE(p, oh->nlink);
-
- /* decode first chunk info */
- chunk_addr = addr + (hsize_t)hdr_size;
- UINT32DECODE(p, chunk_size);
-
- /* build the message array */
- oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
- if (NULL==(oh->mesg=H5FL_SEQ_CALLOC(H5O_mesg_t,(size_t)oh->alloc_nmesgs)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* read each chunk from disk */
- while (H5F_addr_defined(chunk_addr)) {
- /* increase chunk array size */
- if (oh->nchunks >= oh->alloc_nchunks) {
- unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
- H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
-
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- oh->alloc_nchunks = na;
- oh->chunk = x;
- }
-
- /* read the chunk raw data */
- chunkno = oh->nchunks++;
- oh->chunk[chunkno].dirty = FALSE;
- oh->chunk[chunkno].addr = chunk_addr;
- oh->chunk[chunkno].size = chunk_size;
- if (NULL==(oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, dxpl_id,
- oh->chunk[chunkno].image) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data");
-
- /* load messages from this chunk */
- for (p = oh->chunk[chunkno].image; p < oh->chunk[chunkno].image + chunk_size; p += mesg_size) {
- UINT16DECODE(p, id);
- UINT16DECODE(p, mesg_size);
- assert (mesg_size==H5O_ALIGN (mesg_size));
- flags = *p++;
- p += 3; /*reserved*/
-
- /* Try to detect invalidly formatted object header messages */
- if (p + mesg_size > oh->chunk[chunkno].image + chunk_size)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header");
-
- /* Skip header messages we don't know about */
- /* (Usually from future versions of the library */
- if (id >= NELMTS(message_type_g) || NULL == message_type_g[id])
- continue;
-
- if (H5O_NULL_ID == id && oh->nmesgs > 0 &&
- H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id &&
- oh->mesg[oh->nmesgs - 1].chunkno == chunkno) {
- /* combine adjacent null messages */
- mesgno = oh->nmesgs - 1;
- oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR(f) + mesg_size;
- } else {
- /* new message */
- if (oh->nmesgs >= nmesgs)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header");
- mesgno = oh->nmesgs++;
- oh->mesg[mesgno].type = message_type_g[id];
- oh->mesg[mesgno].dirty = FALSE;
- oh->mesg[mesgno].flags = flags;
- oh->mesg[mesgno].native = NULL;
- oh->mesg[mesgno].raw = p;
- oh->mesg[mesgno].raw_size = mesg_size;
- oh->mesg[mesgno].chunkno = chunkno;
- }
- }
-
- assert(p == oh->chunk[chunkno].image + chunk_size);
-
- /* decode next object header continuation message */
- for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
- if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
- H5O_cont_t *cont;
-
- cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL);
- oh->mesg[curmesg].native = cont;
- chunk_addr = cont->addr;
- chunk_size = cont->size;
- cont->chunkno = oh->nchunks; /*the next chunk to allocate */
- }
- }
- }
-
- /* Set return value */
- ret_value = oh;
-
-done:
- if (!ret_value && oh) {
- if(H5O_dest(f,oh)<0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to destroy object header data");
- }
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_flush
- *
- * Purpose: Flushes (and destroys) an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 5 1997
- *
- * Modifications:
- *
- * Robb Matzke, 1998-01-07
- * Handles constant vs non-constant messages.
- *
- * rky, 1998-08-28
- * Only p0 writes metadata to disk.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
-{
- uint8_t buf[16], *p;
- int id;
- unsigned u;
- H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL;
- unsigned combine=0; /* Whether to combine the object header prefix & the first chunk */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5O_flush, FAIL);
-
- /* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(oh);
-
- /* flush */
- if (oh->cache_info.is_dirty) {
- p = buf;
-
- /* encode version */
- *p++ = oh->version;
-
- /* reserved */
- *p++ = 0;
-
- /* encode number of messages */
- UINT16ENCODE(p, oh->nmesgs);
-
- /* encode link count */
- UINT32ENCODE(p, oh->nlink);
-
- /* encode body size */
- UINT32ENCODE(p, oh->chunk[0].size);
-
- /* zero to alignment */
- HDmemset (p, 0, (size_t)(H5O_SIZEOF_HDR(f)-12));
-
- /* write the object header prefix */
-
- /* Check if we can combine the object header prefix & the first chunk into one I/O operation */
- if(oh->chunk[0].dirty && (addr+H5O_SIZEOF_HDR(f))==oh->chunk[0].addr) {
- combine=1;
- } /* end if */
- else {
- if (H5F_block_write(f, H5FD_MEM_OHDR, addr, (size_t)H5O_SIZEOF_HDR(f),
- dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk");
- } /* end else */
-
- /* encode messages */
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
- if (curr_msg->dirty) {
- p = curr_msg->raw - H5O_SIZEOF_MSGHDR(f);
-
- id = curr_msg->type->id;
- UINT16ENCODE(p, id);
- assert (curr_msg->raw_size<H5O_MAX_SIZE);
- UINT16ENCODE(p, curr_msg->raw_size);
- *p++ = curr_msg->flags;
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
-
- if (curr_msg->native) {
- assert(curr_msg->type->encode);
-
- /* allocate file space for chunks that have none yet */
- if (H5O_CONT_ID == curr_msg->type->id &&
- !H5F_addr_defined(((H5O_cont_t *)(curr_msg->native))->addr)) {
- /* We now allocate disk space on insertion, instead
- * of on flush from the cache, so this case is now an
- * error. -- JRM
- */
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL,
- "File space for message not allocated!?!");
- }
-
- /*
- * Encode the message. If the message is shared then we
- * encode a Shared Object message instead of the object
- * which is being shared.
- */
- assert(curr_msg->raw >=
- oh->chunk[curr_msg->chunkno].image);
- assert (curr_msg->raw_size ==
- H5O_ALIGN (curr_msg->raw_size));
- assert(curr_msg->raw + curr_msg->raw_size <=
- oh->chunk[curr_msg->chunkno].image +
- oh->chunk[curr_msg->chunkno].size);
- if (curr_msg->flags & H5O_FLAG_SHARED) {
- encode = H5O_SHARED->encode;
- } else {
- encode = curr_msg->type->encode;
- }
- if ((encode)(f, curr_msg->raw, curr_msg->native)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message");
- }
- curr_msg->dirty = FALSE;
- oh->chunk[curr_msg->chunkno].dirty = TRUE;
- }
- }
-
- /* write each chunk to disk */
- for (u = 0; u < oh->nchunks; u++) {
- if (oh->chunk[u].dirty) {
- assert(H5F_addr_defined(oh->chunk[u].addr));
- if(u==0 && combine) {
- /* Allocate space for the combined prefix and first chunk */
- if((p=H5FL_BLK_MALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size)))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
-
- /* Copy in the prefix */
- HDmemcpy(p,buf,(size_t)H5O_SIZEOF_HDR(f));
-
- /* Copy in the first chunk */
- HDmemcpy(p+H5O_SIZEOF_HDR(f),oh->chunk[u].image,oh->chunk[u].size);
-
- /* Write the combined prefix/chunk out */
- if (H5F_block_write(f, H5FD_MEM_OHDR, addr,
- (H5O_SIZEOF_HDR(f)+oh->chunk[u].size),
- dxpl_id, p) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk");
-
- /* Release the memory for the combined prefix/chunk */
- p = H5FL_BLK_FREE(chunk_image,p);
- } /* end if */
- else {
- if (H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[u].addr,
- (oh->chunk[u].size),
- dxpl_id, oh->chunk[u].image) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk");
- } /* end else */
- oh->chunk[u].dirty = FALSE;
- } /* end if */
- } /* end for */
- oh->cache_info.is_dirty = FALSE;
- }
-
- if (destroy) {
- if(H5O_dest(f,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_dest
- *
- * Purpose: Destroys an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jan 15 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_dest(H5F_t UNUSED *f, H5O_t *oh)
-{
- unsigned i;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest);
-
- /* check args */
- assert(oh);
-
- /* Verify that node is clean */
- assert (oh->cache_info.is_dirty==FALSE);
-
- /* destroy chunks */
- for (i = 0; i < oh->nchunks; i++) {
- /* Verify that chunk is clean */
- assert (oh->chunk[i].dirty==0);
-
- oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image);
- }
- if(oh->chunk)
- oh->chunk = H5FL_SEQ_FREE(H5O_chunk_t,oh->chunk);
-
- /* destroy messages */
- for (i = 0; i < oh->nmesgs; i++) {
- /* Verify that message is clean */
- assert (oh->mesg[i].dirty==0);
-
- H5O_free_mesg(&oh->mesg[i]);
- }
- if(oh->mesg)
- oh->mesg = H5FL_SEQ_FREE(H5O_mesg_t,oh->mesg);
-
- /* destroy object header */
- H5FL_FREE(H5O_t,oh);
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* end H5O_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_clear
- *
- * Purpose: Mark a object header in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 20 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
-{
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_clear);
-
- /* check args */
- assert(oh);
-
- /* Mark chunks as clean */
- for (u = 0; u < oh->nchunks; u++)
- oh->chunk[u].dirty=FALSE;
-
- /* Mark messages as clean */
- for (u = 0; u < oh->nmesgs; u++)
- oh->mesg[u].dirty=FALSE;
-
- /* Mark whole header as clean */
- oh->cache_info.is_dirty=FALSE;
-
- if (destroy)
- if (H5O_dest(f, oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5O_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_compute_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5O_t on disk, and return it in *len_ptr. On failure,
- * the value of *len_ptr is undefined.
- *
- * The value returned will probably be low unless the object
- * has just been flushed, as we simply total up the size of
- * the header with the sizes of the chunks. Thus any message
- * that has been added since the last flush will not be
- * reflected in the total.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr)
-{
- unsigned u;
- size_t size;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_compute_size);
-
- /* check args */
- HDassert(f);
- HDassert(oh);
- HDassert(size_ptr);
-
- size = H5O_SIZEOF_HDR(f);
-
- for (u = 0; u < oh->nchunks; u++)
- size += oh->chunk[u].size;
-
- HDassert(size >= H5O_SIZEOF_HDR(f));
-
- *size_ptr = size;
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5O_compute_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_reset
*
* Purpose: Some message data structures have internal fields that
@@ -1018,12 +641,12 @@ H5O_reset(unsigned type_id, void *native)
FUNC_ENTER_NOAPI(H5O_reset,FAIL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Call the "real" reset routine */
- if((ret_value=H5O_reset_real(type, native))<0)
+ if((ret_value=H5O_reset_real(type, native)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to reset object header");
done:
@@ -1098,7 +721,7 @@ H5O_free (unsigned type_id, void *mesg)
FUNC_ENTER_NOAPI(H5O_free, NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
@@ -1122,7 +745,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_free_mesg(H5O_mesg_t *mesg)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_mesg)
@@ -1153,8 +776,6 @@ H5O_free_mesg(H5O_mesg_t *mesg)
* Programmer: Robb Matzke
* Thursday, May 21, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
void *
@@ -1163,15 +784,15 @@ H5O_free_real(const H5O_class_t *type, void *msg_native)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_real)
/* check args */
- assert(type);
+ HDassert(type);
- if (msg_native) {
+ if(msg_native) {
H5O_reset_real(type, msg_native);
if (NULL!=(type->free))
(type->free)(msg_native);
else
H5MM_xfree (msg_native);
- }
+ } /* end if */
FUNC_LEAVE_NOAPI(NULL)
} /* end H5O_free_real() */
@@ -1207,7 +828,7 @@ H5O_copy (unsigned type_id, const void *mesg, void *dst)
FUNC_ENTER_NOAPI(H5O_copy, NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
@@ -1273,91 +894,80 @@ done:
* matzke@llnl.gov
* Aug 5 1997
*
- * Modifications:
- *
- * Robb Matzke, 1998-08-27
- * This function can also be used to obtain the current number of links
- * if zero is passed for ADJUST. If that's the case then we don't check
- * for write access on the file.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
int
-H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
+H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
{
H5O_t *oh = NULL;
- unsigned oh_flags=H5AC__NO_FLAGS_SET; /* used to indicate whether the
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether the
* object was deleted as a result
* of this action.
*/
int ret_value = FAIL;
- FUNC_ENTER_NOAPI(H5O_link, FAIL);
+ FUNC_ENTER_NOAPI(H5O_link, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- if (adjust!=0 && 0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ if(adjust != 0 && 0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* get header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header,
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr,
NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* adjust link count */
- if (adjust<0) {
- if (oh->nlink + adjust < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative");
+ if(adjust < 0) {
+ if(oh->nlink + adjust < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative")
oh->nlink += adjust;
oh_flags |= H5AC__DIRTIED_FLAG;
/* Check if the object should be deleted */
- if(oh->nlink==0) {
+ if(oh->nlink == 0) {
/* Check if the object is still open by the user */
- if(H5FO_opened(ent->file,ent->header)!=NULL) {
+ if(H5FO_opened(loc->file, loc->addr) != NULL) {
/* Flag the object to be deleted when it's closed */
- if(H5FO_mark(ent->file,ent->header,TRUE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
+ if(H5FO_mark(loc->file, loc->addr, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
else {
/* Delete object right now */
- if(H5O_delete_oh(ent->file,dxpl_id,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
+ if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
/* Mark the object header as deleted */
oh_flags = H5C__DELETED_FLAG;
} /* end else */
} /* end if */
- } else if (adjust>0) {
+ } else if (adjust > 0) {
/* A new object, or one that will be deleted */
- if(oh->nlink==0) {
+ if(oh->nlink == 0) {
/* Check if the object is current open, but marked for deletion */
- if(H5FO_marked(ent->file,ent->header)>0) {
+ if(H5FO_marked(loc->file, loc->addr) > 0) {
/* Remove "delete me" flag on the object */
- if(H5FO_mark(ent->file,ent->header,FALSE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
+ if(H5FO_mark(loc->file, loc->addr, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
} /* end if */
oh->nlink += adjust;
oh_flags |= H5AC__DIRTIED_FLAG;
- }
+ } /* end if */
/* Set return value */
ret_value = oh->nlink;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if (oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link() */
/*-------------------------------------------------------------------------
@@ -1373,36 +983,30 @@ done:
* Programmer: Robb Matzke
* Tuesday, April 21, 1998
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
int
-H5O_count (H5G_entry_t *ent, unsigned type_id, hid_t dxpl_id)
+H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_count, FAIL);
+ FUNC_ENTER_NOAPI(H5O_count, FAIL)
/* Check args */
- assert (ent);
- assert (ent->file);
- assert (H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert (type);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
/* Call the "real" count routine */
- if((ret_value=H5O_count_real(ent, type, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to count object header messages");
+ if((ret_value = H5O_count_real(loc, type, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to count object header messages")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_count() */
@@ -1419,43 +1023,41 @@ done:
* Programmer: Robb Matzke
* Tuesday, April 21, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static int
-H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type, hid_t dxpl_id)
+H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int acc;
unsigned u;
int ret_value;
- FUNC_ENTER_NOAPI(H5O_count_real, FAIL);
+ FUNC_ENTER_NOAPI(H5O_count_real, FAIL)
/* Check args */
- assert (ent);
- assert (ent->file);
- assert (H5F_addr_defined(ent->header));
- assert (type);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
/* Load the object header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Loop over all messages, counting the ones of the type looked for */
- for (u=acc=0; u<oh->nmesgs; u++)
- if (oh->mesg[u].type==type)
+ for(u = acc = 0; u < oh->nmesgs; u++)
+ if(oh->mesg[u].type == type)
acc++;
/* Set return value */
- ret_value=acc;
+ ret_value = acc;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if (oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_count_real() */
@@ -1475,35 +1077,29 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
htri_t
-H5O_exists(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id)
+H5O_exists(H5O_loc_t *loc, unsigned type_id, int sequence, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_exists, FAIL);
+ FUNC_ENTER_NOAPI(H5O_exists, FAIL)
- assert(ent);
- assert(ent->file);
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(sequence>=0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Call the "real" exists routine */
- if((ret_value=H5O_exists_real(ent, type, sequence, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message");
+ if((ret_value = H5O_exists_real(loc, type, sequence, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_exists() */
@@ -1523,48 +1119,42 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
static htri_t
-H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id)
+H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxpl_id)
{
- H5O_t *oh=NULL;
+ H5O_t *oh = NULL;
unsigned u;
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real)
- assert(ent);
- assert(ent->file);
- assert(type);
- assert(sequence>=0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Load the object header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Scan through the messages looking for the right one */
- for (u=0; u<oh->nmesgs; u++) {
- if (type->id!=oh->mesg[u].type->id)
+ for(u = 0; u < oh->nmesgs; u++) {
+ if(type->id != oh->mesg[u].type->id)
continue;
- if (--sequence<0)
+ if(--sequence < 0)
break;
- }
+ } /* end for */
/* Set return value */
- ret_value=(sequence<0);
+ ret_value = (sequence < 0);
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_exists_real() */
@@ -1589,37 +1179,31 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
void *
-H5O_read(const H5G_entry_t *ent, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id)
+H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_read, NULL);
+ FUNC_ENTER_NOAPI(H5O_read, NULL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(sequence >= 0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Call the "real" read routine */
- if((ret_value=H5O_read_real(ent, type, sequence, mesg, dxpl_id))==NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header");
+ if((ret_value = H5O_read_real(loc, type, sequence, mesg, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_read() */
@@ -1644,58 +1228,33 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Bill Wendling, 2003-09-30
- * Protect the object header and pass it into the H5O_find_in_ohdr
- * function. This is done because the H5O_find_in_ohdr used to
- * protect the ohdr, find the message, and then unprotect it. This
- * saves time and also helps the FPHDF5 stuff, where unprotecting
- * actually destroys the object in the cache.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
void *
-H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
+H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int idx;
- const H5G_cache_t *cache = NULL;
- H5G_type_t cache_type;
void *ret_value = NULL;
- FUNC_ENTER_NOAPI_NOINIT(H5O_read_real);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_read_real)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type);
- assert(sequence >= 0);
-
- /* can we get it from the symbol table entry? */
- cache = H5G_ent_cache(ent, &cache_type);
-
- if (H5O_fast_g[cache_type]) {
- ret_value = (H5O_fast_g[cache_type]) (cache, type, mesg);
- if (ret_value)
- HGOTO_DONE(ret_value);
- H5E_clear_stack(NULL); /*don't care, try reading from header */
- }
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
+ HDassert(sequence >= 0);
/* copy the message to the user-supplied buffer */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
/* can we get it from the object header? */
- if ((idx = H5O_find_in_ohdr(ent->file, dxpl_id, oh, &type, sequence)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "unable to find message in object header");
+ if((idx = H5O_find_in_ohdr(loc->file, dxpl_id, oh, &type, sequence)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "unable to find message in object header")
- if (oh->mesg[idx].flags & H5O_FLAG_SHARED) {
+ if(oh->mesg[idx].flags & H5O_FLAG_SHARED) {
/*
* If the message is shared then then the native pointer points to an
* H5O_SHARED message. We use that information to look up the real
@@ -1704,7 +1263,7 @@ H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, voi
H5O_shared_t *shared;
shared = (H5O_shared_t *)(oh->mesg[idx].native);
- ret_value=H5O_shared_read(ent->file,dxpl_id,shared,type,mesg);
+ ret_value = H5O_shared_read(loc->file, dxpl_id, shared, type, mesg);
} else {
/*
* The message is not shared, but rather exists in the object
@@ -1712,15 +1271,15 @@ H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, voi
* the raw message) so we must copy the native message before
* returning.
*/
- if (NULL==(ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space");
- }
+ if(NULL==(ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0)))
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space")
+ } /* end else */
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_read_real() */
@@ -1750,7 +1309,6 @@ static unsigned
H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, int sequence)
{
unsigned u;
- const H5O_class_t *type = NULL;
unsigned ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5O_find_in_ohdr);
@@ -1775,17 +1333,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- if (oh->mesg[u].flags & H5O_FLAG_SHARED)
- type = H5O_SHARED;
- else
- type = oh->mesg[u].type;
-
- if (NULL == oh->mesg[u].native) {
- assert(type->decode);
- oh->mesg[u].native = (type->decode) (f, dxpl_id, oh->mesg[u].raw, NULL);
- if (NULL == oh->mesg[u].native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, UFAIL, "unable to decode message");
- }
+ LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u]))
/*
* Return the message type. If this is a shared message then return the
@@ -1833,45 +1381,33 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Handles constant vs non-constant messages. Once a message is made
- * constant it can never become non-constant. Constant messages cannot
- * be modified.
- *
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
int
-H5O_modify(H5G_entry_t *ent, unsigned type_id, int overwrite,
+H5O_modify(H5O_loc_t *loc, unsigned type_id, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_modify, FAIL);
+ FUNC_ENTER_NOAPI(H5O_modify, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(mesg);
- assert (0==(flags & ~H5O_FLAG_BITS));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(mesg);
+ HDassert(0 == (flags & ~H5O_FLAG_BITS));
/* Call the "real" modify routine */
- if((ret_value= H5O_modify_real(ent, type, overwrite, flags, update_flags, mesg, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header");
+ if((ret_value = H5O_modify_real(loc, type, overwrite, flags, update_flags, mesg, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header message")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_modify() */
@@ -1907,25 +1443,13 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Handles constant vs non-constant messages. Once a message is made
- * constant it can never become non-constant. Constant messages cannot
- * be modified.
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * field of the cache info directly.
- *
*-------------------------------------------------------------------------
*/
static int
-H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
+H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
- H5O_t *oh=NULL;
+ H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
int sequence;
unsigned idx; /* Index of message to modify */
@@ -1936,67 +1460,67 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
FUNC_ENTER_NOAPI_NOINIT(H5O_modify_real)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type);
- assert(mesg);
- assert (0==(flags & ~H5O_FLAG_BITS));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
+ HDassert(mesg);
+ HDassert(0 == (flags & ~H5O_FLAG_BITS));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Count similar messages */
- for (idx = 0, sequence = -1, idx_msg=&oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
- if (type->id != idx_msg->type->id)
+ for(idx = 0, sequence = -1, idx_msg=&oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
+ if(type->id != idx_msg->type->id)
continue;
- if (++sequence == overwrite)
+ if(++sequence == overwrite)
break;
} /* end for */
/* Was the right message found? */
- if (overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
+ if(overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
/* But can we insert a new one with this sequence number? */
- if (overwrite == sequence + 1)
+ if(overwrite == sequence + 1)
overwrite = -1;
else
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found")
} /* end if */
/* Check for creating new message */
- if (overwrite < 0) {
+ if(overwrite < 0) {
/* Create a new message */
- if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id,&oh_flags))==UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+ if((idx = H5O_new_mesg(loc->file, oh, &flags, type, mesg, &sh_mesg, &type, &mesg, dxpl_id, &oh_flags)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message")
/* Set the correct sequence number for the message created */
sequence++;
- } else if (oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message");
- } else if (oh->mesg[idx].flags & H5O_FLAG_SHARED) {
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message");
+ } else if(oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message")
+ } else if(oh->mesg[idx].flags & H5O_FLAG_SHARED) {
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message")
}
/* Write the information to the message */
- if(H5O_write_mesg(oh,idx,type,mesg,flags,update_flags,&oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
+ if(H5O_write_mesg(oh, idx, type, mesg, flags, update_flags, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message")
/* Update the modification time message if any */
- if(update_flags&H5O_UPDATE_TIME)
- H5O_touch_oh(ent->file, dxpl_id, oh, FALSE, &oh_flags);
+ if(update_flags & H5O_UPDATE_TIME)
+ H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags);
/* Set return value */
ret_value = sequence;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_modify_real() */
@@ -2016,30 +1540,28 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
H5O_t *
-H5O_protect(H5G_entry_t *ent, hid_t dxpl_id)
+H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
{
H5O_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_protect, NULL);
+ FUNC_ENTER_NOAPI(H5O_protect, NULL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file")
- if (NULL == (ret_value = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header");
+ if(NULL == (ret_value = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_protect() */
@@ -2058,33 +1580,26 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * field of the cache info directly.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_unprotect(H5G_entry_t *ent, H5O_t *oh, hid_t dxpl_id, unsigned oh_flags)
+H5O_unprotect(H5O_loc_t *loc, H5O_t *oh, hid_t dxpl_id, unsigned oh_flags)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_unprotect, FAIL);
+ FUNC_ENTER_NOAPI(H5O_unprotect, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(oh);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(oh);
- if (H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_unprotect() */
@@ -2128,7 +1643,7 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
/* check args */
assert(f);
assert(oh);
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(0==(flags & ~H5O_FLAG_BITS));
@@ -2136,7 +1651,7 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
assert(oh_flags_ptr);
/* Call the "real" append routine */
- if((ret_value=H5O_append_real( f, dxpl_id, oh, type, flags, mesg, oh_flags_ptr))<0)
+ if((ret_value=H5O_append_real( f, dxpl_id, oh, type, flags, mesg, oh_flags_ptr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to append to object header");
done:
@@ -2159,13 +1674,6 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * of the cache info.
- *
*-------------------------------------------------------------------------
*/
static int
@@ -2191,7 +1699,7 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
/* Write the information to the message */
- if(H5O_write_mesg(oh,idx,type,mesg,flags,0,oh_flags_ptr)<0)
+ if(H5O_write_mesg(oh,idx,type,mesg,flags,0,oh_flags_ptr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
/* Set return value */
@@ -2213,14 +1721,6 @@ done:
* Programmer: Quincey Koziol
* Friday, September 3, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/7/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -2250,7 +1750,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
if (NULL==orig_type->get_share)
HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable");
- if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/)<0) {
+ if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/) < 0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
@@ -2270,14 +1770,14 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
/* Compute the size needed to store the message on disk */
if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)");
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large");
/* Allocate space in the object headed for the message */
if ((ret_value = H5O_alloc(f, dxpl_id, oh, orig_type, size, oh_flags_ptr)) == UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message");
/* Increment any links in message */
- if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg))<0)
+ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
done:
@@ -2353,18 +1853,6 @@ done:
* Programmer: Robb Matzke
* Monday, July 27, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/20/05
- * Added dxpl_id parameter needed by the revised version of
- * H5O_alloc().
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -2375,9 +1863,6 @@ H5O_touch_oh(H5F_t *f,
unsigned * oh_flags_ptr)
{
unsigned idx;
-#ifdef H5_HAVE_GETTIMEOFDAY
- struct timeval now_tv;
-#endif /* H5_HAVE_GETTIMEOFDAY */
time_t now;
size_t size;
herr_t ret_value=SUCCEED; /* Return value */
@@ -2388,14 +1873,18 @@ H5O_touch_oh(H5F_t *f,
assert(oh_flags_ptr);
/* Look for existing message */
- for (idx=0; idx<oh->nmesgs; idx++) {
+ for (idx=0; idx < oh->nmesgs; idx++) {
if (H5O_MTIME==oh->mesg[idx].type || H5O_MTIME_NEW==oh->mesg[idx].type)
break;
}
#ifdef H5_HAVE_GETTIMEOFDAY
- HDgettimeofday(&now_tv,NULL);
- now=now_tv.tv_sec;
+ {
+ struct timeval now_tv;
+
+ HDgettimeofday(&now_tv, NULL);
+ now = now_tv.tv_sec;
+ }
#else /* H5_HAVE_GETTIMEOFDAY */
now = HDtime(NULL);
#endif /* H5_HAVE_GETTIMEOFDAY */
@@ -2447,35 +1936,35 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_touch(H5G_entry_t *ent, hbool_t force, hid_t dxpl_id)
+H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id)
{
H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_touch, FAIL);
+ FUNC_ENTER_NOAPI(H5O_touch, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if (NULL==(oh=H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Create/Update the modification time message */
- if (H5O_touch_oh(ent->file, dxpl_id, oh, force, &oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object modificaton time");
+ if(H5O_touch_oh(loc->file, dxpl_id, oh, force, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object modificaton time")
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_touch() */
#ifdef H5O_ENABLE_BOGUS
@@ -2490,46 +1979,35 @@ done:
* <koziol@ncsa.uiuc.edu>
* Tuesday, January 21, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/20/05
- * Added dxpl_id parameter needed by call to H5O_alloc().
- *
*-------------------------------------------------------------------------
*/
herr_t
H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr)
{
int idx;
- size_t size;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER(H5O_bogus_oh, FAIL);
+ FUNC_ENTER(H5O_bogus_oh, FAIL)
- assert(f);
- assert(oh);
- assert(oh_flags_ptr);
+ HDassert(f);
+ HDassert(oh);
+ HDassert(oh_flags_ptr);
/* Look for existing message */
- for (idx=0; idx<oh->nmesgs; idx++)
- if (H5O_BOGUS==oh->mesg[idx].type)
+ for(idx = 0; idx < oh->nmesgs; idx++)
+ if(H5O_BOGUS == oh->mesg[idx].type)
break;
/* Create a new message */
- if (idx==oh->nmesgs) {
- size = (H5O_BOGUS->raw_size)(f, NULL);
- if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message");
+ if(idx == oh->nmesgs) {
+ size_t size = (H5O_BOGUS->raw_size)(f, NULL);
+
+ if((idx = H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message")
/* Allocate the native message in memory */
- if (NULL==(oh->mesg[idx].native = H5MM_malloc(sizeof(H5O_bogus_t))))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for 'bogus' message");
+ if(NULL == (oh->mesg[idx].native = H5MM_malloc(sizeof(H5O_bogus_t))))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for 'bogus' message")
/* Update the native part */
((H5O_bogus_t *)(oh->mesg[idx].native))->u = H5O_BOGUS_VALUE;
@@ -2541,7 +2019,7 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr)
} /* end if */
done:
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(ret_value)
} /* end H5O_bogus_oh() */
@@ -2556,45 +2034,39 @@ done:
* <koziol@ncsa.uiuc.edu>
* Tuesday, January 21, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_bogus(H5G_entry_t *ent, hid_t dxpl_id)
+H5O_bogus(H5O_loc_t *loc, hid_t dxpl_id)
{
H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
herr_t ret_value = SUCCEED;
- FUNC_ENTER(H5O_bogus, FAIL);
+ FUNC_ENTER(H5O_bogus, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
/* Verify write access to the file */
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if (NULL==(oh=H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Create the "bogus" message */
- if (H5O_bogus_oh(ent->file, dxpl_id, oh, &oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message");
+ if(H5O_bogus_oh(ent->file, dxpl_id, oh, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message")
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(ret_value)
} /* end H5O_bogus() */
#endif /* H5O_ENABLE_BOGUS */
@@ -2630,7 +2102,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hbool_t adj_link, hid_t dxpl_id)
+H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj_link, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
@@ -2638,15 +2110,15 @@ H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hbool_t adj_link, h
FUNC_ENTER_NOAPI(H5O_remove, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(message_type_g));
type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" remove routine */
- if((ret_value = H5O_remove_real(ent, type, sequence, NULL, NULL, adj_link, dxpl_id))<0)
+ if((ret_value = H5O_remove_real(loc, type, sequence, NULL, NULL, adj_link, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message")
done:
@@ -2672,7 +2144,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_remove_op(H5G_entry_t *ent, unsigned type_id,
+H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
@@ -2681,15 +2153,15 @@ H5O_remove_op(H5G_entry_t *ent, unsigned type_id,
FUNC_ENTER_NOAPI(H5O_remove_op, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(message_type_g));
type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" remove routine */
- if((ret_value = H5O_remove_real(ent, type, H5O_ALL, op, op_data, adj_link, dxpl_id))<0)
+ if((ret_value = H5O_remove_real(loc, type, sequence, op, op_data, adj_link, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message")
done:
@@ -2710,8 +2182,6 @@ done:
* koziol@ncsa.uiuc.edu
* Sep 6 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -2731,12 +2201,12 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
if(udata->op) {
/* Call the iterator callback */
if((try_remove = (udata->op)(mesg->native, idx, udata->op_data)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "object header message deletion callback failed")
} /* end if */
else {
/* If there's no callback routine, does the sequence # match? */
- if ((int)idx == udata->sequence || H5O_ALL == udata->sequence)
- try_remove = TRUE;
+ if((int)idx == udata->sequence || H5O_ALL == udata->sequence)
+ try_remove = H5O_ITER_STOP;
} /* end else */
/* Try removing the message, if indicated */
@@ -2745,12 +2215,12 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
* Keep track of how many times we failed trying to remove constant
* messages.
*/
- if (mesg->flags & H5O_FLAG_CONSTANT) {
+ if(mesg->flags & H5O_FLAG_CONSTANT) {
udata->nfailed++;
} /* end if */
else {
/* Free any space referred to in the file from this message */
- if(H5O_delete_mesg(udata->f, udata->dxpl_id, mesg, udata->adj_link)<0)
+ if(H5O_delete_mesg(udata->f, udata->dxpl_id, mesg, udata->adj_link) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
/* Free any native information */
@@ -2768,7 +2238,7 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
} /* end else */
/* Break out now, if we've found the correct message */
- if(udata->sequence != H5O_ALL)
+ if(udata->sequence == H5O_FIRST || udata->sequence != H5O_ALL)
HGOTO_DONE(H5O_ITER_STOP)
} /* end if */
@@ -2795,19 +2265,10 @@ done:
* matzke@llnl.gov
* Aug 28 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Does not remove constant messages.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
+H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id)
{
H5O_iter_ud1_t udata; /* User data for iterator */
@@ -2816,15 +2277,15 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
FUNC_ENTER_NOAPI_NOINIT(H5O_remove_real)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
+ HDassert(loc);
+ HDassert(loc->file);
HDassert(type);
- if (0==(ent->file->intent & H5F_ACC_RDWR))
+ if (0==(loc->file->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Set up iterator operator data */
- udata.f = ent->file;
+ udata.f = loc->file;
udata.dxpl_id = dxpl_id;
udata.sequence = sequence;
udata.nfailed = 0;
@@ -2833,11 +2294,11 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
udata.adj_link = adj_link;
/* Iterate over the messages, deleting appropriate one(s) */
- if(H5O_iterate_real(ent, type, H5AC_WRITE, TRUE, (void *)H5O_remove_cb, &udata, dxpl_id) < 0)
+ if(H5O_iterate_real(loc, type, H5AC_WRITE, TRUE, (void *)H5O_remove_cb, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over messages")
/* Fail if we tried to remove any constant messages */
- if (udata.nfailed)
+ if(udata.nfailed)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to remove constant message(s)")
done:
@@ -2847,6 +2308,517 @@ done:
/*-------------------------------------------------------------------------
*
+ * Function: H5O_move_msgs_forward
+ *
+ * Purpose: Move messages toward first chunk
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 17 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t packed_msg; /* Flag to indicate that messages were packed */
+ hbool_t did_packing = FALSE; /* Whether any messages were packed */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_move_msgs_forward)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no messages packed */
+ /* (Double loop is not very efficient, but it would be some extra work to add
+ * a list of messages to each chunk -QAK)
+ */
+ do {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned u; /* Local index variable */
+
+ /* Reset packed messages flag */
+ packed_msg = FALSE;
+
+ /* Scan through messages for messages that can be moved earlier in chunks */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if(H5O_NULL_ID == curr_msg->type->id) {
+ H5O_chunk_t *chunk; /* Pointer to chunk that null message is in */
+
+ /* Check if null message is not last in chunk */
+ chunk = &(oh->chunk[curr_msg->chunkno]);
+ if((curr_msg->raw + curr_msg->raw_size) != (chunk->image + chunk->size)) {
+ H5O_mesg_t *nonnull_msg; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for the message in the chunk after the null message */
+ for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++) {
+ /* Locate message that is immediately after the null message */
+ if((curr_msg->chunkno == nonnull_msg->chunkno) &&
+ ((curr_msg->raw + curr_msg->raw_size) == (nonnull_msg->raw - H5O_SIZEOF_MSGHDR(f)))) {
+ /* Don't swap messages if the second message is also a null message */
+ /* (We'll merge them together later, in another routine) */
+ if(H5O_NULL_ID != nonnull_msg->type->id) {
+ /* Make certain non-null message has been translated into native form */
+ /* (So that when we mark it dirty, it will get copied back into raw chunk image) */
+ LOAD_NATIVE(f, dxpl_id, nonnull_msg)
+
+ /* Adjust non-null message's offset in chunk */
+ nonnull_msg->raw = curr_msg->raw;
+
+ /* Adjust null message's offset in chunk */
+ curr_msg->raw = nonnull_msg->raw +
+ nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+
+ /* Mark messages dirty */
+ curr_msg->dirty = TRUE;
+ nonnull_msg->dirty = TRUE;
+
+ /* Set the flag to indicate that the null message
+ * was packed - if its not at the end its chunk,
+ * we'll move it again on the next pass.
+ */
+ packed_msg = TRUE;
+ } /* end if */
+
+ /* Break out of loop */
+ break;
+ } /* end if */
+ } /* end for */
+ /* Should have been message after null message */
+ HDassert(v < oh->nmesgs);
+ } /* end if */
+ } /* end if */
+ else {
+ H5O_mesg_t *null_msg; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for large enough null message in earlier chunk */
+ for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
+ if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
+ && curr_msg->raw_size <= null_msg->raw_size) {
+ unsigned old_chunkno; /* Old message information */
+ uint8_t *old_raw;
+ size_t old_raw_size;
+
+ /* Keep old information about non-null message */
+ old_chunkno = curr_msg->chunkno;
+ old_raw = curr_msg->raw;
+ old_raw_size = curr_msg->raw_size;
+
+ /* Make certain non-null message has been translated into native form */
+ /* (So that when we mark it dirty, it will get copied back into raw chunk image) */
+ LOAD_NATIVE(f, dxpl_id, curr_msg)
+
+ /* Change information for non-null message */
+ if(curr_msg->raw_size == null_msg->raw_size) {
+ /* Point non-null message at null message's space */
+ curr_msg->chunkno = null_msg->chunkno;
+ curr_msg->raw = null_msg->raw;
+
+ /* Mark non-null message dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Point null message at old non-null space */
+ /* (Instead of freeing it and allocating new message) */
+ null_msg->chunkno = old_chunkno;
+ null_msg->raw = old_raw;
+
+ /* Mark null message dirty */
+ null_msg->dirty = TRUE;
+ } /* end if */
+ else {
+ unsigned new_null_msg; /* Message index for new null message */
+
+ /* Point non-null message at null message's space */
+ curr_msg->chunkno = null_msg->chunkno;
+ curr_msg->raw = null_msg->raw;
+
+ /* Mark non-null message dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Adjust null message's size & offset */
+ null_msg->raw += curr_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+ null_msg->raw_size -= curr_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+
+ /* Mark null message dirty */
+ null_msg->dirty = TRUE;
+
+ /* Create new null message for previous location of non-null message */
+ if(oh->nmesgs >= oh->alloc_nmesgs) {
+ unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
+ H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
+
+ if(NULL == x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ oh->alloc_nmesgs = na;
+ oh->mesg = x;
+ } /* end if */
+
+ /* Get message # for new message */
+ new_null_msg = oh->nmesgs++;
+
+ /* Initialize new null message */
+ oh->mesg[new_null_msg].type = H5O_NULL;
+ oh->mesg[new_null_msg].dirty = TRUE;
+ oh->mesg[new_null_msg].native = NULL;
+ oh->mesg[new_null_msg].raw = old_raw;
+ oh->mesg[new_null_msg].raw_size = old_raw_size;
+ oh->mesg[new_null_msg].chunkno = old_chunkno;
+ } /* end else */
+
+ /* Indicate that we packed messages */
+ packed_msg = TRUE;
+
+ /* Break out of loop */
+ /* (If it's possible to move messge to even ealier chunk
+ * we'll get it on the next pass - QAK)
+ */
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we packed messages, get out of loop and start over */
+ /* (Don't know if this has any benefit one way or the other -QAK) */
+ if(packed_msg)
+ break;
+ } /* end else */
+ } /* end for */
+
+ /* If we did any packing, remember that */
+ if(packed_msg)
+ did_packing = TRUE;
+ } while(packed_msg);
+
+ /* Set return value */
+ ret_value = did_packing;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_move_msgs_forward() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_merge_null
+ *
+ * Purpose: Merge neighboring null messages in an object header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 10 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_merge_null(H5F_t *f, H5O_t *oh)
+{
+ hbool_t merged_msg; /* Flag to indicate that messages were merged */
+ hbool_t did_merging = FALSE; /* Whether any messages were merged */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_merge_null)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no messages merged */
+ /* (Double loop is not very efficient, but it would be some extra work to add
+ * a list of messages to each chunk -QAK)
+ */
+ do {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned u; /* Local index variable */
+
+ /* Reset merged messages flag */
+ merged_msg = FALSE;
+
+ /* Scan messages for adjacent null messages & merge them */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if(H5O_NULL_ID == curr_msg->type->id) {
+ H5O_mesg_t *curr_msg2; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for null message in same chunk */
+ for(v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) {
+ if(u != v && H5O_NULL_ID == curr_msg2->type->id && curr_msg->chunkno == curr_msg2->chunkno) {
+
+ /* Check for second message after first message */
+ if((curr_msg->raw + curr_msg->raw_size) == (curr_msg2->raw - H5O_SIZEOF_MSGHDR(f))) {
+ /* Extend first null message length to cover second null message */
+ curr_msg->raw_size += (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+
+ /* Message has been merged */
+ merged_msg = TRUE;
+ } /* end if */
+ /* Check for second message befre first message */
+ else if((curr_msg->raw - H5O_SIZEOF_MSGHDR(f)) == (curr_msg2->raw + curr_msg2->raw_size)) {
+ /* Adjust first message address and extend length to cover second message */
+ curr_msg->raw -= (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+ curr_msg->raw_size += (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+
+ /* Message has been merged */
+ merged_msg = TRUE;
+ } /* end if */
+
+ /* Second message has been merged, delete it */
+ if(merged_msg) {
+ /* Release any information/memory for second message */
+ H5O_free_mesg(curr_msg2);
+
+ /* Mark first message as dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Remove second message from list of messages */
+ if(v < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t));
+
+ /* Decrement # of messages */
+ /* (Don't bother reducing size of message array for now -QAK) */
+ oh->nmesgs--;
+
+ /* Get out of loop */
+ break;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ /* Get out of loop if we merged messages */
+ if(merged_msg)
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we did any merging, remember that */
+ if(merged_msg)
+ did_merging = TRUE;
+ } while(merged_msg);
+
+ /* Set return value */
+ ret_value = did_merging;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_merge_null() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_remove_empty_chunks
+ *
+ * Purpose: Attempt to eliminate empty chunks from object header.
+ *
+ * This examines a chunk to see if it's empty
+ * and removes it (and the continuation message that points to it)
+ * from the object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 17 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t deleted_chunk; /* Whether to a chunk was deleted */
+ hbool_t did_deleting = FALSE; /* Whether any chunks were deleted */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_remove_empty_chunks)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no chunks are freed */
+ do {
+ H5O_mesg_t *null_msg; /* Pointer to null message found */
+ H5O_mesg_t *cont_msg; /* Pointer to continuation message found */
+ unsigned u, v; /* Local index variables */
+
+ /* Reset 'chunk deleted' flag */
+ deleted_chunk = FALSE;
+
+ /* Scan messages for null messages that fill an entire chunk */
+ for(u = 0, null_msg = &oh->mesg[0]; u < oh->nmesgs; u++, null_msg++) {
+ /* If a null message takes up an entire object header chunk (and
+ * its not the "base" chunk), delete that chunk from object header
+ */
+ if(H5O_NULL_ID == null_msg->type->id && null_msg->chunkno > 0 &&
+ (H5O_SIZEOF_MSGHDR(f) + null_msg->raw_size) == oh->chunk[null_msg->chunkno].size) {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned null_msg_no; /* Message # for null message */
+ unsigned deleted_chunkno; /* Chunk # to delete */
+
+ /* Locate continuation message that points to chunk */
+ for(v = 0, cont_msg = &oh->mesg[0]; v < oh->nmesgs; v++, cont_msg++) {
+ if(H5O_CONT_ID == cont_msg->type->id) {
+ /* Decode current continuation message if necessary */
+ if(NULL == cont_msg->native) {
+ HDassert(H5O_CONT->decode);
+ cont_msg->native = (H5O_CONT->decode) (f, dxpl_id, cont_msg->raw);
+ if(NULL == cont_msg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
+ } /* end if */
+
+ /* Check for correct chunk to delete */
+ if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr)
+ break;
+ } /* end if */
+ } /* end for */
+ /* Must be a continuation message that points to chunk containing null message */
+ HDassert(v < oh->nmesgs);
+ HDassert(cont_msg);
+
+ /* Initialize information about null message */
+ null_msg_no = u;
+ deleted_chunkno = null_msg->chunkno;
+
+ /*
+ * Convert continuation message into a null message
+ */
+
+ /* Free space for chunk referred to in the file from the continuation message */
+ if(H5O_delete_mesg(f, dxpl_id, cont_msg, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
+
+ /* Free any native information */
+ H5O_free_mesg(cont_msg);
+
+ /* Change message type to nil and zero it */
+ cont_msg->type = H5O_NULL;
+ HDmemset(cont_msg->raw, 0, cont_msg->raw_size);
+
+ /* Indicate that the continuation message was modified */
+ cont_msg->dirty = TRUE;
+
+ /*
+ * Remove chunk from object header's data structure
+ */
+
+ /* Free memory for chunk image */
+ H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image);
+
+ /* Remove chunk from list of chunks */
+ if(null_msg->chunkno < (oh->nchunks - 1))
+ HDmemmove(&oh->chunk[null_msg->chunkno], &oh->chunk[null_msg->chunkno + 1], ((oh->nchunks - 1) - null_msg->chunkno) * sizeof(H5O_chunk_t));
+
+ /* Decrement # of chunks */
+ /* (Don't bother reducing size of chunk array for now -QAK) */
+ oh->nchunks--;
+
+ /*
+ * Delete null message (in empty chunk that was be freed) from list of messages
+ */
+
+ /* Release any information/memory for message */
+ H5O_free_mesg(null_msg);
+
+ /* Remove null message from list of messages */
+ if(null_msg_no < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[null_msg_no], &oh->mesg[null_msg_no + 1], ((oh->nmesgs - 1) - null_msg_no) * sizeof(H5O_mesg_t));
+
+ /* Decrement # of messages */
+ /* (Don't bother reducing size of message array for now -QAK) */
+ oh->nmesgs--;
+
+ /* Adjust chunk # for messages in chunks after deleted chunk */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ HDassert(curr_msg->chunkno != deleted_chunkno);
+ if(curr_msg->chunkno > deleted_chunkno)
+ curr_msg->chunkno--;
+ } /* end for */
+
+ /* Found chunk to delete */
+ deleted_chunk = TRUE;
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we deleted any chunks, remember that */
+ if(deleted_chunk)
+ did_deleting = TRUE;
+ } while(deleted_chunk);
+
+ /* Set return value */
+ ret_value = did_deleting;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_remove_empty_chunks() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_condense_header
+ *
+ * Purpose: Attempt to eliminate empty chunks from object header.
+ *
+ * Currently, this just examines a chunk to see if it's empty
+ * and removes it from the object header. It's possible that
+ * a more sophiticated algorithm would repack messages from
+ * one chunk to another.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 4 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t rescan_header; /* Whether to rescan header */
+ htri_t result; /* Result from packing/merging/etc */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_condense_header)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no changed to the object header messages & chunks */
+ do {
+ /* Reset 'rescan chunks' flag */
+ rescan_header = FALSE;
+
+ /* Scan for messages that can be moved earlier in chunks */
+ result = H5O_move_msgs_forward(f, oh, dxpl_id);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't move header messages forward")
+ if(result > 0)
+ rescan_header = TRUE;
+
+ /* Scan for adjacent null messages & merge them */
+ result = H5O_merge_null(f, oh);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack null header messages")
+ if(result > 0)
+ rescan_header = TRUE;
+
+ /* Scan for empty chunks to remove */
+ result = H5O_remove_empty_chunks(f, oh, dxpl_id);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't remove empty chunk")
+ if(result > 0)
+ rescan_header = TRUE;
+ } while(rescan_header);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_condense_header() */
+
+
+/*-------------------------------------------------------------------------
+ *
* Function: H5O_alloc_extend_chunk
*
* Purpose: Attempt to extend a chunk that is allocated on disk.
@@ -2993,9 +2965,8 @@ H5O_alloc_extend_chunk(H5F_t *f,
HDassert(((H5O_cont_t *)(oh->mesg[u].native))->size == old_size);
((H5O_cont_t *)(oh->mesg[u].native))->size = oh->chunk[chunkno].size;
- /* Flag continuation message & it's chunk as dirty */
+ /* Flag continuation message as dirty */
oh->mesg[u].dirty = TRUE;
- oh->chunk[oh->mesg[u].chunkno].dirty = TRUE;
} /* end if */
} /* end for */
@@ -3031,17 +3002,6 @@ done:
* matzke@llnl.gov
* Aug 7 1997
*
- * Modifications:
- *
- * John Mainzer, 8/17/05
- * Reworked function to allocate file space immediately,
- * instead of just allocating core space (as it used to).
- * This change was necessary, as we were allocating file
- * space on metadata cache eviction, which need not be
- * synchronized across all processes. As a result,
- * different processes were allocating different file
- * locations to the same chunk.
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -3051,8 +3011,10 @@ H5O_alloc_new_chunk(H5F_t *f,
size_t size)
{
size_t cont_size; /*continuation message size */
- int found_null = (-1); /*best fit null message */
- int found_other = (-1); /*best fit other message */
+ int found_null = (-1); /*best fit null message */
+ int found_attr = (-1); /*best fit attribute message */
+ int found_link = (-1); /*best fit link message */
+ int found_other = (-1); /*best fit other message */
unsigned idx; /*message number */
uint8_t *p = NULL; /*ptr into new chunk */
H5O_cont_t *cont = NULL; /*native continuation message */
@@ -3061,11 +3023,11 @@ H5O_alloc_new_chunk(H5F_t *f,
haddr_t new_chunk_addr;
unsigned ret_value; /*return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk)
/* check args */
- HDassert (oh);
- HDassert (size > 0);
+ HDassert(oh);
+ HDassert(size > 0);
size = H5O_ALIGN(size);
/*
@@ -3073,36 +3035,60 @@ H5O_alloc_new_chunk(H5F_t *f,
* continuation message. Failing that, find the smallest message
* that could be moved to make room for the continuation message.
* Don't ever move continuation message from one chunk to another.
+ * Prioritize attribute and link messages moving to later chunks,
+ * instead of more "important" messages.
*/
cont_size = H5O_ALIGN (H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f));
- for (u=0; u<oh->nmesgs; u++) {
- if (H5O_NULL_ID == oh->mesg[u].type->id) {
- if (cont_size == oh->mesg[u].raw_size) {
- found_null = u;
- break;
- } else if (oh->mesg[u].raw_size >= cont_size &&
- (found_null < 0 ||
- (oh->mesg[u].raw_size <
- oh->mesg[found_null].raw_size))) {
- found_null = u;
- }
- } else if (H5O_CONT_ID == oh->mesg[u].type->id) {
- /*don't consider continuation messages */
- } else if (oh->mesg[u].raw_size >= cont_size &&
+ for(u = 0; u < oh->nmesgs; u++) {
+ int msg_id = oh->mesg[u].type->id; /* Temp. copy of message type ID */
+
+ if(H5O_NULL_ID == msg_id) {
+ if(cont_size == oh->mesg[u].raw_size) {
+ found_null = u;
+ break;
+ } else if(oh->mesg[u].raw_size >= cont_size &&
+ (found_null < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_null].raw_size)) {
+ found_null = u;
+ }
+ } else if(H5O_CONT_ID == msg_id) {
+ /*don't consider continuation messages */
+ } else if(H5O_ATTR_ID == msg_id) {
+ if(oh->mesg[u].raw_size >= cont_size &&
+ (found_attr < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_attr].raw_size))
+ found_attr = u;
+ } else if(H5O_LINK_ID == msg_id) {
+ if(oh->mesg[u].raw_size >= cont_size &&
+ (found_link < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_link].raw_size))
+ found_link = u;
+ } else {
+ if(oh->mesg[u].raw_size >= cont_size &&
(found_other < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_other].raw_size)) {
- found_other = u;
- }
- }
- assert(found_null >= 0 || found_other >= 0);
+ oh->mesg[u].raw_size < oh->mesg[found_other].raw_size))
+ found_other = u;
+ } /* end else */
+ } /* end for */
+ HDassert(found_null >= 0 || found_attr >= 0 || found_link >= 0 || found_other >= 0);
/*
* If we must move some other message to make room for the null
* message, then make sure the new chunk has enough room for that
* other message.
+ *
+ * Move attributes first, then link messages, then other messages.
+ *
*/
- if (found_null < 0)
+ if(found_null < 0) {
+ if(found_attr >= 0)
+ found_other = found_attr;
+ else if(found_link >= 0)
+ found_other = found_link;
+
+ HDassert(found_other >= 0);
size += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
+ } /* end if */
/*
* The total chunk size must include the requested space plus enough
@@ -3110,7 +3096,7 @@ H5O_alloc_new_chunk(H5F_t *f,
* multiple of the alignment size.
*/
size = MAX(H5O_MIN_SIZE, size + H5O_SIZEOF_MSGHDR(f));
- assert (size == H5O_ALIGN (size));
+ HDassert(size == H5O_ALIGN (size));
/* allocate space in file to hold the new chunk */
new_chunk_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)size);
@@ -3120,47 +3106,46 @@ H5O_alloc_new_chunk(H5F_t *f,
/*
* Create the new chunk giving it a file address.
*/
- if ( oh->nchunks >= oh->alloc_nchunks ) {
-
+ if(oh->nchunks >= oh->alloc_nchunks) {
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
oh->alloc_nchunks = na;
oh->chunk = x;
- }
+ } /* end if */
chunkno = oh->nchunks++;
oh->chunk[chunkno].dirty = TRUE;
oh->chunk[chunkno].addr = new_chunk_addr;
oh->chunk[chunkno].size = size;
if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_CALLOC(chunk_image,size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
/*
* Make sure we have enough space for all possible new messages
* that could be generated below.
*/
- if (oh->nmesgs + 3 > oh->alloc_nmesgs) {
- int old_alloc=oh->alloc_nmesgs;
+ if(oh->nmesgs + 3 > oh->alloc_nmesgs) {
+ int old_alloc = oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
oh->alloc_nmesgs = na;
oh->mesg = x;
/* Set new object header info to zeros */
HDmemset(&oh->mesg[old_alloc], 0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
- }
+ } /* end if */
/*
* Describe the messages of the new chunk.
*/
- if (found_null < 0) {
+ if(found_null < 0) {
found_null = u = oh->nmesgs++;
oh->mesg[u].type = H5O_NULL;
oh->mesg[u].dirty = TRUE;
@@ -3178,7 +3163,7 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_other].chunkno = chunkno;
p += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
size -= H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
- }
+ } /* end if */
idx = oh->nmesgs++;
oh->mesg[idx].type = H5O_NULL;
oh->mesg[idx].dirty = TRUE;
@@ -3192,7 +3177,7 @@ H5O_alloc_new_chunk(H5F_t *f,
* is larger than the continuation message, then split it into
* two null messages.
*/
- if (oh->mesg[found_null].raw_size > cont_size) {
+ if(oh->mesg[found_null].raw_size > cont_size) {
u = oh->nmesgs++;
oh->mesg[u].type = H5O_NULL;
oh->mesg[u].dirty = TRUE;
@@ -3206,7 +3191,7 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_null].dirty = TRUE;
oh->mesg[found_null].raw_size = cont_size;
- }
+ } /* end if */
/*
* Initialize the continuation message.
@@ -3221,10 +3206,10 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_null].native = cont;
/* Set return value */
- ret_value=idx;
+ ret_value = idx;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_alloc_new_chunk() */
@@ -3241,23 +3226,6 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * John Mainzer, 6/7/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field directly.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/19/05
- * Reworked the function to allocate disk space immediately instead
- * of waiting to cache eviction time. This is necessary since cache
- * evictions need not be synchronized across the processes in the
- * PHDF5 case.
- *
- * Note the use of a revised versions of H5O_alloc_new_chunk() and
- * H5O_alloc_extend_chunk().
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -3268,25 +3236,24 @@ H5O_alloc(H5F_t *f,
size_t size,
unsigned * oh_flags_ptr)
{
- unsigned idx;
H5O_mesg_t *msg; /* Pointer to newly allocated message */
size_t aligned_size = H5O_ALIGN(size);
- htri_t tri_result;
+ unsigned idx; /* Index of message which fits allocation */
unsigned ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_alloc)
/* check args */
- HDassert (oh);
- HDassert (type);
- HDassert (oh_flags_ptr);
+ HDassert(oh);
+ HDassert(type);
+ HDassert(oh_flags_ptr);
/* look for a null message which is large enough */
- for (idx = 0; idx < oh->nmesgs; idx++) {
- if (H5O_NULL_ID == oh->mesg[idx].type->id &&
+ for(idx = 0; idx < oh->nmesgs; idx++) {
+ if(H5O_NULL_ID == oh->mesg[idx].type->id &&
oh->mesg[idx].raw_size >= aligned_size)
break;
- }
+ } /* end for */
#ifdef LATER
/*
@@ -3299,7 +3266,7 @@ H5O_alloc(H5F_t *f,
#endif
/* if we didn't find one, then allocate more header space */
- if (idx >= oh->nmesgs) {
+ if(idx >= oh->nmesgs) {
unsigned chunkno;
/* check to see if we can extend one of the chunks. If we can,
@@ -3308,62 +3275,56 @@ H5O_alloc(H5F_t *f,
* Note that in this new version of this function, all chunks
* must have file space allocated to them.
*/
- for (chunkno = 0; chunkno < oh->nchunks; chunkno++) {
- HDassert( H5F_addr_defined(oh->chunk[chunkno].addr) );
-
- tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
+ for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
+ htri_t tri_result;
- if ( tri_result == TRUE ) {
+ HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
+ tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
+ if(tri_result == TRUE)
break;
-
- } else if ( tri_result == FALSE ) {
-
+ else if(tri_result == FALSE)
idx = UFAIL;
-
- } else {
-
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, \
- "H5O_alloc_extend_chunk failed unexpectedly");
- }
- }
+ else
+ HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
+ } /* end for */
/* if idx is still UFAIL, we were not able to extend a chunk.
* Create a new one.
*/
- if(idx == UFAIL) {
+ if(idx == UFAIL)
if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, size)) == UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk")
- }
- }
+ } /* end if */
/* Set pointer to newly allocated message */
msg = &(oh->mesg[idx]);
/* do we need to split the null message? */
- if (msg->raw_size > aligned_size) {
+ if(msg->raw_size > aligned_size) {
H5O_mesg_t *null_msg; /* Pointer to null message */
- size_t mesg_size = aligned_size+ H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
+ size_t mesg_size = aligned_size + H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
HDassert(msg->raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f));
- if (oh->nmesgs >= oh->alloc_nmesgs) {
- int old_alloc=oh->alloc_nmesgs;
+ /* Check if we need to extend message table */
+ if(oh->nmesgs >= oh->alloc_nmesgs) {
+ int old_alloc = oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
- oh->alloc_nmesgs = na;
- oh->mesg = x;
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
+ oh->alloc_nmesgs = na;
+ oh->mesg = x;
/* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc],0,
+ HDmemset(&oh->mesg[old_alloc], 0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
/* "Retarget" local 'msg' pointer into newly allocated array of messages */
- msg=&oh->mesg[idx];
- }
+ msg = &oh->mesg[idx];
+ } /* end if */
null_msg = &(oh->mesg[oh->nmesgs++]);
null_msg->type = H5O_NULL;
null_msg->dirty = TRUE;
@@ -3372,7 +3333,7 @@ H5O_alloc(H5F_t *f,
null_msg->raw_size = msg->raw_size - mesg_size;
null_msg->chunkno = msg->chunkno;
msg->raw_size = aligned_size;
- }
+ } /* end if */
/* initialize the new message */
msg->type = type;
@@ -3385,7 +3346,7 @@ H5O_alloc(H5F_t *f,
ret_value = idx;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_alloc() */
#ifdef NOT_YET
@@ -3427,9 +3388,9 @@ H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
if ((size = (type->raw_size)(f, mesg))>0) {
if (NULL==(buf = H5MM_malloc (size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- if ((type->encode)(f, buf, mesg)<0)
+ if ((type->encode)(f, buf, mesg) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message");
- if (H5HG_insert (f, dxpl_id, size, buf, hobj)<0)
+ if (H5HG_insert (f, dxpl_id, size, buf, hobj) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "unable to store message in global heap");
}
@@ -3454,8 +3415,6 @@ done:
* koziol@ncsa.uiuc.edu
* Feb 13 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
size_t
@@ -3467,7 +3426,7 @@ H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg)
FUNC_ENTER_NOAPI(H5O_raw_size,0)
/* Check args */
- HDassert(type_id<NELMTS(message_type_g));
+ HDassert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
HDassert(type->raw_size);
@@ -3506,7 +3465,7 @@ H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg)
FUNC_ENTER_NOAPI(H5O_mesg_size,0)
/* Check args */
- HDassert(type_id<NELMTS(message_type_g));
+ HDassert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
HDassert(type->raw_size);
@@ -3553,23 +3512,23 @@ H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share)
const H5O_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_get_share,FAIL);
+ FUNC_ENTER_NOAPI(H5O_get_share,FAIL)
/* Check args */
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert (type);
- assert (type->get_share);
- assert (f);
- assert (mesg);
- assert (share);
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(type->get_share);
+ HDassert(f);
+ HDassert(mesg);
+ HDassert(share);
/* Compute the raw data size for the mesg */
- if ((ret_value = (type->get_share)(f, mesg, share))<0)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information");
+ if((ret_value = (type->get_share)(f, mesg, share)) < 0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_get_share() */
@@ -3587,36 +3546,33 @@ done:
* koziol@ncsa.uiuc.edu
* Mar 19 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
{
- H5O_t *oh=NULL; /* Object header information */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5O_t *oh = NULL; /* Object header information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_delete,FAIL);
+ FUNC_ENTER_NOAPI(H5O_delete,FAIL)
/* Check args */
- assert (f);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
/* Get the object header information */
- if (NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Delete object */
- if(H5O_delete_oh(f,dxpl_id,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
+ if(H5O_delete_oh(f, dxpl_id, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
done:
- if (oh &&
- H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete() */
@@ -3635,54 +3591,36 @@ done:
* koziol@ncsa.uiuc.edu
* Mar 19 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
{
H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- H5O_chunk_t *curr_chk; /* Pointer to current chunk being operated on */
unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_delete_oh);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_oh)
/* Check args */
- assert (f);
- assert (oh);
+ HDassert(f);
+ HDassert(oh);
/* Walk through the list of object header messages, asking each one to
* delete any file space used
*/
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
/* Free any space referred to in the file from this message */
- if(H5O_delete_mesg(f, dxpl_id, curr_msg, TRUE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ if(H5O_delete_mesg(f, dxpl_id, curr_msg, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end for */
- /* Free all the chunks for the object header */
- for (u = 0, curr_chk=&oh->chunk[0]; u < oh->nchunks; u++,curr_chk++) {
- haddr_t chk_addr; /* Actual address of chunk */
- hsize_t chk_size; /* Actual size of chunk */
-
- if(u==0) {
- chk_addr = curr_chk->addr - H5O_SIZEOF_HDR(f);
- chk_size = curr_chk->size + H5O_SIZEOF_HDR(f);
- } /* end if */
- else {
- chk_addr = curr_chk->addr;
- chk_size = curr_chk->size;
- } /* end else */
-
- /* Free the file space for the chunk */
- if (H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, chk_addr, chk_size)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header");
- } /* end for */
+ /* Free main (first) object header "chunk" */
+ if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, (oh->chunk[0].addr - H5O_SIZEOF_HDR(f)), (hsize_t)(oh->chunk[0].size + H5O_SIZEOF_HDR(f))) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_oh() */
@@ -3699,8 +3637,6 @@ done:
* koziol@ncsa.uiuc.edu
* September 26 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -3709,15 +3645,15 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
const H5O_class_t *type; /* Type of object to free */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg)
/* Check args */
- assert (f);
- assert (mesg);
+ HDassert(f);
+ HDassert(mesg);
/* Get the message to free's type */
if(mesg->flags & H5O_FLAG_SHARED)
- type=H5O_SHARED;
+ type = H5O_SHARED;
else
type = mesg->type;
@@ -3726,19 +3662,19 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
/*
* Decode the message if necessary.
*/
- if (NULL == mesg->native) {
- assert(type->decode);
- mesg->native = (type->decode) (f, dxpl_id, mesg->raw, NULL);
- if (NULL == mesg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
+ if(NULL == mesg->native) {
+ HDassert(type->decode);
+ mesg->native = (type->decode) (f, dxpl_id, mesg->raw);
+ if(NULL == mesg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
} /* end if */
- if ((type->del)(f, dxpl_id, mesg->native, adj_link)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ if((type->del)(f, dxpl_id, mesg->native, adj_link) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_msg() */
@@ -3753,57 +3689,51 @@ done:
* koziol@ncsa.uiuc.edu
* Oct 7 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id)
+H5O_get_info(H5O_loc_t *loc, H5O_stat_t *ostat, hid_t dxpl_id)
{
- H5O_t *oh=NULL; /* Object header information */
+ H5O_t *oh = NULL; /* Object header information */
H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
hsize_t total_size; /* Total amount of space used in file */
hsize_t free_space; /* Free space in object header */
unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_get_info,FAIL);
+ FUNC_ENTER_NOAPI(H5O_get_info,FAIL)
/* Check args */
- assert (ent);
- assert (ostat);
+ HDassert(loc);
+ HDassert(ostat);
/* Get the object header information */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Iterate over all the messages, accumulating the total size & free space */
- total_size=H5O_SIZEOF_HDR(ent->file);
- free_space=0;
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ total_size = H5O_SIZEOF_HDR(loc->file);
+ free_space = 0;
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
/* Accumulate the size for this message */
- total_size+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size;
+ total_size += H5O_SIZEOF_MSGHDR(loc->file) + curr_msg->raw_size;
/* Check for this message being free space */
- if (H5O_NULL_ID == curr_msg->type->id)
- free_space+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size;
+ if(H5O_NULL_ID == curr_msg->type->id)
+ free_space+= H5O_SIZEOF_MSGHDR(loc->file) + curr_msg->raw_size;
} /* end for */
/* Set the information for this object header */
- ostat->size=total_size;
- ostat->free=free_space;
- ostat->nmesgs=oh->nmesgs;
- ostat->nchunks=oh->nchunks;
+ ostat->size = total_size;
+ ostat->free = free_space;
+ ostat->nmesgs = oh->nmesgs;
+ ostat->nchunks = oh->nchunks;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_get_info() */
@@ -3834,12 +3764,12 @@ H5O_encode(H5F_t *f, unsigned char *buf, void *obj, unsigned type_id)
FUNC_ENTER_NOAPI(H5O_encode,FAIL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Encode */
- if ((type->encode)(f, buf, obj)<0)
+ if ((type->encode)(f, buf, obj) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message");
done:
@@ -3874,12 +3804,12 @@ H5O_decode(H5F_t *f, const unsigned char *buf, unsigned type_id)
FUNC_ENTER_NOAPI(H5O_decode,NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* decode */
- if((ret_value = (type->decode)(f, 0, buf, NULL))==NULL)
+ if((ret_value = (type->decode)(f, 0, buf))==NULL)
HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message");
done:
@@ -3925,24 +3855,24 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_iterate(const H5G_entry_t *ent, unsigned type_id, H5O_operator_t op,
+H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
void *op_data, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
- herr_t ret_value=0; /* Return value */
+ const H5O_class_t *type; /* Actual H5O class type for the ID */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_iterate, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
- HDassert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" iterate routine */
- if((ret_value=H5O_iterate_real(ent, type, H5AC_READ, FALSE, (void *)op, op_data, dxpl_id))<0)
+ if((ret_value = H5O_iterate_real(loc, type, H5AC_READ, FALSE, (void *)op, op_data, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages")
done:
@@ -3984,49 +3914,37 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type, H5AC_protect_t prot,
+H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t prot,
hbool_t internal, void *op, void *op_data, hid_t dxpl_id)
{
- H5O_t *oh=NULL; /* Pointer to actual object header */
+ H5O_t *oh = NULL; /* Pointer to actual object header */
unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Start iteration with no flags set on object header */
unsigned idx; /* Absolute index of current message in all messages */
unsigned sequence; /* Relative index of current message for messages of type */
H5O_mesg_t *idx_msg; /* Pointer to current message */
- herr_t ret_value=0; /* Return value */
+ herr_t ret_value = H5O_ITER_CONT; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_iterate_real)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type);
HDassert(op);
/* Protect the object header to iterate over */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, prot)))
+ if (NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, prot)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
/* Iterate over messages */
- for (sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
- if (type->id == idx_msg->type->id) {
+ for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) {
+ if(type->id == idx_msg->type->id) {
/*
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- if (NULL == idx_msg->native) {
- const H5O_class_t *decode_type;
-
- if (idx_msg->flags & H5O_FLAG_SHARED)
- decode_type = H5O_SHARED;
- else
- decode_type = type;
-
- /* Decode the message if necessary */
- HDassert(decode_type->decode);
- if (NULL == (idx_msg->native = (decode_type->decode) (ent->file, dxpl_id, idx_msg->raw, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
- } /* end if */
+ LOAD_NATIVE(loc->file, dxpl_id, idx_msg)
/* Check for making an "internal" (i.e. within the H5O package) callback */
if(internal) {
@@ -4040,27 +3958,155 @@ H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type, H5AC_protect_t
break;
} /* end else */
+ /* Check for error from iterator */
+ if(ret_value < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "iterator function failed")
+
/* Increment sequence value for message type */
sequence++;
} /* end if */
} /* end for */
- /* Check if object header was modified */
- if(oh_flags & H5AC__DIRTIED_FLAG) {
- /* Shouldn't be able to modify object header if we don't have write access */
- HDassert(prot == H5AC_WRITE);
- H5O_touch_oh(ent->file, dxpl_id, oh, FALSE, &oh_flags);
- } /* end if */
-
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ if(oh) {
+ /* Check if object header was modified */
+ if(oh_flags & H5AC__DIRTIED_FLAG) {
+ /* Shouldn't be able to modify object header if we don't have write access */
+ HDassert(prot == H5AC_WRITE);
+
+ /* Try to condense object header info */
+ if(H5O_condense_header(loc->file, oh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack object header")
+
+ H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags);
+ } /* end if */
+
+ if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_iterate_real() */
/*-------------------------------------------------------------------------
+ * Function: H5O_obj_type
+ *
+ * Purpose: Returns the type of object pointed to by `loc'.
+ *
+ * Return: Success: An object type defined in H5Gpublic.h
+ * Failure: H5G_UNKNOWN
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, November 4, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id)
+{
+ size_t i; /* Local index variable */
+ H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_obj_type, H5G_UNKNOWN)
+
+ /* Test whether entry qualifies as a particular type of object */
+ /* (Note: loop is in reverse order, to test specific objects first) */
+ for(i = H5O_ntypes_g; i > 0; --i) {
+ htri_t isa; /* Is entry a particular type? */
+
+ if((isa = (H5O_type_g[i-1].isa)(loc, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
+ else if(isa)
+ HGOTO_DONE(H5O_type_g[i-1].type)
+ } /* end for */
+
+ if(0 == i)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_obj_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_reset
+ *
+ * Purpose: Reset a object location to an empty state
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_reset(H5O_loc_t *loc)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_loc_reset)
+
+ /* Check arguments */
+ HDassert(loc);
+
+ /* Clear the object location to an empty state */
+ HDmemset(loc, 0, sizeof(H5O_loc_t));
+ loc->addr = HADDR_UNDEF;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy
+ *
+ * Purpose: Copy object location information
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Monday, September 19, 2005
+ *
+ * Notes: 'depth' parameter determines how much of the group entry
+ * structure we want to copy. The values are:
+ * H5O_COPY_SHALLOW - Copy all the field values from the source
+ * to the destination, but not copying objects pointed to.
+ * (Destination "takes ownership" of objects pointed to)
+ * H5O_COPY_DEEP - Copy all the fields from the source to
+ * the destination, deep copying objects pointed to.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_loc_copy)
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+ HDassert(depth == H5O_COPY_SHALLOW || depth == H5O_COPY_DEEP);
+
+ /* Copy the top level information */
+ HDmemcpy(dst, src, sizeof(H5O_loc_t));
+
+ /* Deep copy the names */
+ if(depth == H5G_COPY_DEEP) {
+ /* Nothing currently */
+ ;
+ } else if(depth == H5G_COPY_SHALLOW) {
+ /* Discarding 'const' qualifier OK - QAK */
+ H5O_loc_reset((H5O_loc_t *)src);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_copy_mesg_file
*
* Purpose: Copies a message to file. If MESG is is the null pointer then a null
@@ -4100,47 +4146,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_post_copy_mesg_file
- *
- * Purpose: Copies what's left to file after the object a meesage is copied.
- * This function is need for situations like copying symbol tables.
- * Copying a member of symbol table requires the parent object header
- * exists in file. For this case, the first round of the message will
- * create symbol table enttries but will not go deep copying member
- * objects in the symbol table. The post copy will do that.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Peter Cao
- * September 28, 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_post_copy_mesg_file (const H5O_class_t *type, H5F_t *file_src,
- const void *mesg_src, H5G_entry_t *loc_dst,
- hid_t dxpl_id, H5SL_t *map_list)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_post_copy_mesg_file)
-
- /* check args */
- HDassert(type);
- HDassert(file_src);
- HDassert(mesg_src);
- HDassert(loc_dst->file);
- HDassert(map_list);
-
- if(type->post_copy_file && (type->post_copy_file)(file_src, mesg_src, loc_dst, dxpl_id, map_list) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy object header message to file")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_post_copy_mesg_file */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_copy_header_real
*
* Purpose: copy header object from one location to another.
@@ -4150,48 +4155,49 @@ done:
* Programmer: Peter Cao
* May 30, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_copy_header_real(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+H5O_copy_header_real(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
{
- H5O_addr_map_t *addr_map; /* Address mapping of object copied */
- uint8_t buf[16], *p;
- H5O_t *oh = NULL;
- unsigned chunkno = 0, mesgno = 0;
- size_t chunk_size, hdr_size;
- haddr_t addr_new;
- H5O_mesg_t *mesg_src;
- H5O_chunk_t *chunk;
- herr_t ret_value = SUCCEED;
+ H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
+ uint8_t buf[16], *p;
+ H5O_t *oh_src = NULL; /* Object header for source object */
+ H5O_t *oh_dst = NULL; /* Object header for destination object */
+ unsigned chunkno = 0, mesgno = 0;
+ size_t chunk_size, hdr_size;
+ haddr_t addr_new;
+ H5O_mesg_t *mesg_src; /* Message in source object header */
+ H5O_mesg_t *mesg_dst; /* Message in source object header */
+ H5O_chunk_t *chunk = NULL;
+ unsigned dst_oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether destination header was modified */
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real)
- HDassert(ent_src);
- HDassert(ent_src->file);
- HDassert(H5F_addr_defined(ent_src->header));
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_src->file);
+ HDassert(H5F_addr_defined(oloc_src->addr));
+ HDassert(oloc_dst->file);
HDassert(map_list);
- if(NULL == (oh = H5AC_protect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh_src = H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* get the size of the file header of the destination file */
- hdr_size = H5O_SIZEOF_HDR(ent_dst->file);
+ hdr_size = H5O_SIZEOF_HDR(oloc_dst->file);
/* allocate memory space for the destitnation chunks */
- if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->nchunks)))
+ if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh_src->nchunks)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Allocate space for the first chunk */
- if(HADDR_UNDEF == (addr_new = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh->chunk[0].size)))
+ if(HADDR_UNDEF == (addr_new = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh_src->chunk[0].size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
/* Return the first chunk address */
- ent_dst->header = addr_new;
+ oloc_dst->addr = addr_new;
/* Set chunk's address */
chunk[0].addr = addr_new + (hsize_t)hdr_size;
@@ -4206,13 +4212,13 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
*p++ = 0;
/* encode number of messages */
- UINT16ENCODE(p, oh->nmesgs);
+ UINT16ENCODE(p, oh_src->nmesgs);
/* encode link count (at zero initially) */
UINT32ENCODE(p, 0);
/* encode body size */
- UINT32ENCODE(p, oh->chunk[0].size);
+ UINT32ENCODE(p, oh_src->chunk[0].size);
/* zero to alignment */
HDmemset(p, 0, (size_t)(hdr_size-12));
@@ -4221,17 +4227,17 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
because continuation chunk message will need to know the chunk address of address of
continuation block.
*/
- for(chunkno = 1; chunkno < oh->nchunks; chunkno++) {
- if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh->chunk[chunkno].size)))
+ for(chunkno = 1; chunkno < oh_src->nchunks; chunkno++) {
+ if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh_src->chunk[chunkno].size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
} /* end for */
/* Loop through chunks to copy chunk information */
- for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
- chunk_size = oh->chunk[chunkno].size;
+ for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++) {
+ chunk_size = oh_src->chunk[chunkno].size;
/* copy chunk information */
- chunk[chunkno].dirty = oh->chunk[chunkno].dirty;
+ chunk[chunkno].dirty = oh_src->chunk[chunkno].dirty;
chunk[chunkno].size = chunk_size;
/* create memory image for the new chunk */
@@ -4242,13 +4248,13 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
/* (This copies over all the messages which don't require special
* callbacks to fix them up.)
*/
- HDmemcpy(chunk[chunkno].image, oh->chunk[chunkno].image, chunk_size);
+ HDmemcpy(chunk[chunkno].image, oh_src->chunk[chunkno].image, chunk_size);
/* Loop through messages, to fix up any which refer to addresses in the source file, etc. */
- for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
const H5O_class_t *copy_type;
- mesg_src = &(oh->mesg[mesgno]);
+ mesg_src = &(oh_src->mesg[mesgno]);
/* check if the message belongs to this chunk */
if(mesg_src->chunkno != chunkno)
@@ -4271,31 +4277,31 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
if(NULL == mesg_src->native) {
/* Decode the message if necessary */
HDassert(copy_type->decode);
- if(NULL == (mesg_src->native = (copy_type->decode)(ent_src->file, dxpl_id, mesg_src->raw, NULL)))
+ if(NULL == (mesg_src->native = (copy_type->decode)(oloc_src->file, dxpl_id, mesg_src->raw)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
} /* end if (NULL == mesg_src->native) */
/* Copy the source message */
if(H5O_CONT_ID == copy_type->id) {
- if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst->file, dxpl_id, map_list, chunk)) == NULL)
+ if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, chunk)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end if */
else {
- if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst->file, dxpl_id, map_list, NULL)) == NULL)
+ if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, NULL)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end else */
/* Calculate address in destination raw chunk */
- p = chunk[chunkno].image + (mesg_src->raw - oh->chunk[chunkno].image);
+ p = chunk[chunkno].image + (mesg_src->raw - oh_src->chunk[chunkno].image);
/*
* Encode the message. If the message is shared then we
* encode a Shared Object message instead of the object
* which is being shared.
*/
- if((copy_type->encode)(ent_dst->file, p, dst_native) < 0)
+ if((copy_type->encode)(oloc_dst->file, p, dst_native) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
/* Release native destination info */
@@ -4305,52 +4311,98 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
/* Write the object header to the file if this is the first chunk */
if(chunkno == 0)
- if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
+ if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk")
/* Write this chunk into disk */
- if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
+ if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
} /* end of chunkno loop */
+
+ /* Protect destination object header, so we can modify messages in it */
+ if(NULL == (oh_dst = H5AC_protect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+ HDassert(oh_dst->nmesgs == oh_src->nmesgs);
+
/* Allocate space for the address mapping of the object copied */
if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Insert the address mapping for the new object into the copied list */
/* (Do this here, because "post copy" possibly checks it) */
- addr_map->src_addr = ent_src->header;
- addr_map->dst_addr = ent_dst->header;
+ addr_map->src_addr = oloc_src->addr;
+ addr_map->dst_addr = oloc_dst->addr;
+ addr_map->is_locked = TRUE; /* We've locked the object currently */
+ addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
/* "post copy" loop over messages */
- for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
const H5O_class_t *copy_type;
- mesg_src = &(oh->mesg[mesgno]);
+ mesg_src = &(oh_src->mesg[mesgno]);
- if (mesg_src->flags & H5O_FLAG_SHARED)
+ if(mesg_src->flags & H5O_FLAG_SHARED)
copy_type = H5O_SHARED;
else
copy_type = mesg_src->type;
HDassert(copy_type);
- if(mesg_src->native) {
- if((H5O_post_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst, dxpl_id, map_list)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ if(copy_type->post_copy_file && mesg_src->native) {
+ hbool_t modified = FALSE;
+
+ /* Get destination message */
+ mesg_dst = &(oh_dst->mesg[mesgno]);
+ HDassert(mesg_dst->type == mesg_src->type);
+
+ /* Make certain the destination's native info is available */
+ LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst)
+
+ /* Perform "post copy" operation on messge */
+ if((copy_type->post_copy_file)(oloc_src->file, mesg_src->native, oloc_dst, mesg_dst->native, &modified, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+
+ /* Mark message and header as dirty if the destination message was modified */
+ if(modified) {
+ mesg_dst->dirty = TRUE;
+ dst_oh_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
} /* end if */
} /* end for */
done:
- /* Release pointer to object header itself */
- if(oh != NULL) {
- for(chunkno = 0; chunkno < oh->nchunks; chunkno++)
- H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
- H5FL_SEQ_FREE(H5O_chunk_t, chunk);
+ /* Release pointer to source object header and it's derived objects */
+ if(oh_src != NULL) {
+ /* Release all the chunks used to copy messages */
+ if(chunk) {
+ for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++)
+ H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
+ H5FL_SEQ_FREE(H5O_chunk_t, chunk);
+ } /* end if */
+
+ /* Unprotect the source object header */
+ if(H5AC_unprotect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, oh_src, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ } /* end if */
+
+ /* Release pointer to destination object header */
+ if(oh_dst != NULL) {
+ /* Perform operations on address mapping for object, if it's in use */
+ if(addr_map) {
+ /* Indicate that the destination address will no longer be locked */
+ addr_map->is_locked = FALSE;
+
+ /* Increment object header's reference count, if any descendents have created links to link to this object */
+ if(addr_map->inc_ref_count) {
+ oh_dst->nlink += addr_map->inc_ref_count;
+ dst_oh_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ } /* end if */
- if(H5AC_unprotect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, oh, H5AC__NO_FLAGS_SET) < 0)
+ /* Unprotect the destination object header */
+ if(H5AC_unprotect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, dst_oh_flags) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
} /* end if */
@@ -4372,39 +4424,56 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header_map(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+H5O_copy_header_map(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
{
H5O_addr_map_t *addr_map; /* Address mapping of object copied */
+ hbool_t inc_link; /* Whether to increment the link count for the object */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5O_copy_header_map, FAIL)
/* Sanity check */
- HDassert(ent_src);
- HDassert(ent_dst);
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
HDassert(map_list);
/* Look up the address of the object to copy in the skip list */
- addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(ent_src->header));
+ addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(oloc_src->addr));
/* Check if address is already in list of objects copied */
if(addr_map == NULL) {
/* Copy object for the first time */
/* Copy object referred to */
- if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* When an object is copied for the first time, increment it's link */
+ inc_link = TRUE;
} /* end if */
else {
/* Object has already been copied, set it's address in destination file */
- ent_dst->header = addr_map->dst_addr;
+ oloc_dst->addr = addr_map->dst_addr;
+
+ /* If the object is locked currently (because we are copying a group
+ * hierarchy and this is a link to a group higher in the hierarchy),
+ * increment it's deferred reference count instead of incrementing the
+ * reference count now.
+ */
+ if(addr_map->is_locked) {
+ addr_map->inc_ref_count++;
+ inc_link = FALSE;
+ } /* end if */
+ else
+ inc_link = TRUE;
} /* end else */
- /* Increment destination object's link count */
- if(H5O_link(ent_dst, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to increment object link count")
+ /* Increment destination object's link count, if allowed */
+ if(inc_link)
+ if(H5O_link(oloc_dst, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to increment object link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -4457,25 +4526,24 @@ H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id)
+H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id)
{
- H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
- herr_t ret_value = SUCCEED;
+ H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5O_copy_header, FAIL)
- HDassert(ent_src);
- HDassert(ent_src->file);
- HDassert(H5F_addr_defined(ent_src->header));
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_src->file);
+ HDassert(H5F_addr_defined(oloc_src->addr));
+ HDassert(oloc_dst->file);
/* Create a skip list to keep track of which objects are copied */
if((map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL)
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
- if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
done:
@@ -4511,7 +4579,7 @@ H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *str
FUNC_ENTER_NOAPI(H5O_debug_id,FAIL);
/* Check args */
- assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
+ assert(type_id>=0 && type_id < (hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(type->debug);
@@ -4522,7 +4590,7 @@ H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *str
assert(fwidth >= 0);
/* Call the debug method in the class */
- if ((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth))<0)
+ if ((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth)) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message");
done:
@@ -4531,7 +4599,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_debug
+ * Function: H5O_debug_real
*
* Purpose: Prints debugging info about an object header.
*
@@ -4541,38 +4609,28 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
*-------------------------------------------------------------------------
*/
herr_t
-H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth)
{
- H5O_t *oh = NULL;
unsigned i, chunkno;
size_t mesg_total = 0, chunk_total = 0;
int *sequence;
haddr_t tmp_addr;
- herr_t ret_value = SUCCEED;
- void *(*decode)(H5F_t*, hid_t, const uint8_t*, H5O_shared_t*);
+ void *(*decode)(H5F_t*, hid_t, const uint8_t*);
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL;
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5O_debug, FAIL);
+ FUNC_ENTER_NOAPI(H5O_debug_real, FAIL)
/* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(stream);
- assert(indent >= 0);
- assert(fwidth >= 0);
-
- if (NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ HDassert(f);
+ HDassert(oh);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
/* debug */
HDfprintf(stream, "%*sObject Header...\n", indent, "");
@@ -4597,7 +4655,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
(unsigned) (oh->nchunks), (unsigned) (oh->alloc_nchunks));
/* debug each chunk */
- for (i=0, chunk_total=0; i<oh->nchunks; i++) {
+ for (i=0, chunk_total=0; i < oh->nchunks; i++) {
chunk_total += oh->chunk[i].size;
HDfprintf(stream, "%*sChunk %d...\n", indent, "", i);
@@ -4619,7 +4677,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
/* debug each message */
if (NULL==(sequence = H5MM_calloc(NELMTS(message_type_g)*sizeof(int))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- for (i=0, mesg_total=0; i<oh->nmesgs; i++) {
+ for (i=0, mesg_total=0; i < oh->nmesgs; i++) {
mesg_total += H5O_SIZEOF_MSGHDR(f) + oh->mesg[i].raw_size;
HDfprintf(stream, "%*sMessage %d...\n", indent, "", i);
@@ -4638,6 +4696,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
(unsigned) (oh->mesg[i].type->id),
oh->mesg[i].type->name,
sequence[oh->mesg[i].type->id]++);
+ HDfprintf (stream, "%*s%-*s %d\n", indent+3, "", MAX (0, fwidth-3),
+ "Dirty:",
+ (int)(oh->mesg[i].dirty));
HDfprintf (stream, "%*s%-*s %s\n", indent+3, "", MAX (0, fwidth-3),
"Shared:",
(oh->mesg[i].flags & H5O_FLAG_SHARED) ? "Yes" : "No");
@@ -4658,6 +4719,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
chunkno = oh->mesg[i].chunkno;
if (chunkno >= oh->nchunks)
HDfprintf(stream, "*** BAD CHUNK NUMBER\n");
+ HDfprintf(stream, "%*s%-*s %u\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Raw data offset in chunk:",
+ (unsigned) (oh->mesg[i].raw - oh->chunk[chunkno].image));
/* check the size */
if ((oh->mesg[i].raw + oh->mesg[i].raw_size >
@@ -4675,7 +4739,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
debug = oh->mesg[i].type->debug;
}
if (NULL==oh->mesg[i].native && decode)
- oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw, NULL);
+ oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw);
if (NULL==oh->mesg[i].native)
debug = NULL;
@@ -4692,17 +4756,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
H5O_shared_t *shared = (H5O_shared_t*)(oh->mesg[i].native);
void *mesg = NULL;
- if (shared->in_gh) {
- void *p = H5HG_read (f, dxpl_id, oh->mesg[i].native, NULL);
- mesg = (oh->mesg[i].type->decode)(f, dxpl_id, p, oh->mesg[i].native);
- H5MM_xfree (p);
- } else {
- mesg = H5O_read_real(&(shared->u.ent), oh->mesg[i].type, 0, NULL, dxpl_id);
- }
- if (oh->mesg[i].type->debug) {
- (oh->mesg[i].type->debug)(f, dxpl_id, mesg, stream, indent+3,
- MAX (0, fwidth-3));
- }
+ mesg = H5O_read_real(&(shared->oloc), oh->mesg[i].type, 0, NULL, dxpl_id);
+ if (oh->mesg[i].type->debug)
+ (oh->mesg[i].type->debug)(f, dxpl_id, mesg, stream, indent+3, MAX (0, fwidth-3));
H5O_free_real(oh->mesg[i].type, mesg);
}
}
@@ -4712,8 +4768,48 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
done:
- if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_debug_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_debug
+ *
+ * Purpose: Prints debugging info about an object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+{
+ H5O_t *oh = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5O_debug, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* debug */
+ H5O_debug_real(f, dxpl_id, oh, addr, stream, indent, fwidth);
+
+done:
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_debug() */
- FUNC_LEAVE_NOAPI(ret_value);
-}