summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
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);
-}