summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Abtree2.c87
-rw-r--r--src/H5Adense.c17
-rw-r--r--src/H5Aint.c3
-rw-r--r--src/H5Apkg.h5
-rw-r--r--src/H5F.c29
-rw-r--r--src/H5FD.c51
-rw-r--r--src/H5Fpkg.h3
-rw-r--r--src/H5Fprivate.h3
-rw-r--r--src/H5Gobj.c27
-rw-r--r--src/H5O.c17
-rw-r--r--src/H5Oattribute.c6
-rw-r--r--src/H5Ocache.c33
-rw-r--r--src/H5Omessage.c80
-rw-r--r--src/H5Opkg.h18
-rw-r--r--src/H5Oprivate.h6
-rwxr-xr-xsrc/H5SM.c12
-rw-r--r--src/H5Tcommit.c2
17 files changed, 338 insertions, 61 deletions
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c
index 57e669e..02e1bed 100644
--- a/src/H5Abtree2.c
+++ b/src/H5Abtree2.c
@@ -44,11 +44,17 @@
/* Local Macros */
/****************/
+#ifndef QAK
+/* Size of stack buffer for serialized attributes */
+#define H5A_ATTR_BUF_SIZE 128
+#endif /* QAK */
+
/******************/
/* Local Typedefs */
/******************/
+#ifdef QAK
/*
* Data exchange structure for dense attribute storage. This structure is
* passed through the fractal heap layer to compare attributes.
@@ -59,12 +65,13 @@ typedef struct H5A_fh_ud_cmp_t {
hid_t dxpl_id; /* DXPL for operation */
const char *name; /* Name of attribute to compare */
const H5A_dense_bt2_name_rec_t *record; /* v2 B-tree record for attribute */
- H5B2_found_t found_op; /* Callback when correct attribute is found */
+ H5A_bt2_found_t found_op; /* Callback when correct attribute is found */
void *found_op_data; /* Callback data when correct attribute is found */
/* upward */
int cmp; /* Comparison of two attribute names */
} H5A_fh_ud_cmp_t;
+#endif /* QAK */
/********************/
@@ -101,7 +108,9 @@ static herr_t H5A_dense_btree2_name_debug(FILE *stream, const H5F_t *f, hid_t dx
int indent, int fwidth, const void *record, const void *_udata);
/* Fractal heap function callbacks */
+#ifdef QAK
static herr_t H5A_dense_fh_name_cmp(const void *obj, size_t obj_len, void *op_data);
+#endif /* QAK */
/*********************/
@@ -136,6 +145,11 @@ const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */
/* Library Private Variables */
/*****************************/
+#ifndef QAK
+/* Declare extern a free list to manage blocks of type conversion data */
+H5FL_BLK_EXTERN(ser_attr);
+#endif /* QAK */
+
/*******************/
/* Local Variables */
@@ -157,11 +171,13 @@ const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */
*
*-------------------------------------------------------------------------
*/
+#ifdef QAK
static herr_t
H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
{
H5A_fh_ud_cmp_t *udata = (H5A_fh_ud_cmp_t *)_udata; /* User data for 'op' callback */
H5A_t *attr = NULL; /* Pointer to attribute created from heap object */
+ hbool_t took_ownership = FALSE; /* Whether the "found" operator took ownership of the attribute */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fh_name_cmp)
@@ -183,17 +199,18 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
attr->crt_idx = udata->record->corder;
/* Make callback */
- if((udata->found_op)(attr, udata->found_op_data) < 0)
+ if((udata->found_op)(attr, &took_ownership, udata->found_op_data) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPERATE, FAIL, "attribute found callback failed")
} /* end if */
done:
/* Release the space allocated for the attrbute */
- if(attr)
+ if(attr && !took_ownership)
H5O_msg_free(H5O_ATTR_ID, attr);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_fh_name_cmp() */
+#endif /* QAK */
/*-------------------------------------------------------------------------
@@ -284,13 +301,16 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
else if(bt2_udata->name_hash > bt2_rec->hash)
ret_value = 1;
else {
+#ifdef QAK
H5A_fh_ud_cmp_t fh_udata; /* User data for fractal heap 'op' callback */
+#endif /* QAK */
H5HF_t *fheap; /* Fractal heap handle to use for finding object */
herr_t status; /* Status from fractal heap 'op' routine */
/* Sanity check */
HDassert(bt2_udata->name_hash == bt2_rec->hash);
+#ifdef QAK
/* Prepare user data for callback */
/* down */
fh_udata.f = bt2_udata->f;
@@ -302,6 +322,7 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
/* up */
fh_udata.cmp = 0;
+#endif /* QAK */
/* Check for attribute in shared storage */
if(bt2_rec->flags)
@@ -310,12 +331,72 @@ H5A_dense_btree2_name_compare(const void *_bt2_udata, const void *_bt2_rec)
fheap = bt2_udata->fheap;
HDassert(fheap);
+#ifdef QAK
/* Check if the user's attribute and the B-tree's attribute have the same name */
status = H5HF_op(fheap, bt2_udata->dxpl_id, &bt2_rec->id, H5A_dense_fh_name_cmp, &fh_udata);
HDassert(status >= 0);
/* Callback will set comparison value */
ret_value = fh_udata.cmp;
+#else /* QAK */
+/* XXX: This hack is due to a shared attribute and one of its components
+ * ending up in the same fractal heap direct block. Once John's change
+ * to the metadata cache that allows re-entrant read "protects" is in
+ * place, the previous code can be uncommented. -QAK
+ */
+ {
+ H5A_t *attr; /* Pointer to attribute created from heap object */
+ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */
+ void *attr_ptr; /* Pointer to serialized message */
+ hbool_t took_ownership = FALSE; /* Whether the "found" operator took ownership of the attribute */
+ size_t attr_size; /* Length of existing encoded attribute */
+
+ /* Get length of encoded attribute */
+ status = H5HF_get_obj_len(fheap, bt2_udata->dxpl_id, &bt2_rec->id, &attr_size);
+ HDassert(status >= 0);
+
+ /* Allocate space for serialized message, if necessary */
+ if(attr_size > sizeof(attr_buf)) {
+ attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size);
+ HDassert(attr_ptr);
+ } /* end if */
+ else
+ attr_ptr = attr_buf;
+
+ /* Read the encoded attribute */
+ status = H5HF_read(fheap, bt2_udata->dxpl_id, &bt2_rec->id, attr_ptr);
+ HDassert(status >= 0);
+
+ /* Decode attribute information */
+ attr = (H5A_t *)H5O_msg_decode(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)attr_ptr);
+ HDassert(attr);
+
+ /* Release space, if we allocated it */
+ if(attr_ptr != attr_buf)
+ (void)H5FL_BLK_FREE(ser_attr, attr_ptr);
+
+ /* Compare the string values */
+ ret_value = HDstrcmp(bt2_udata->name, attr->name);
+
+ /* Check for correct attribute & callback to make */
+ if(ret_value == 0 && bt2_udata->found_op) {
+ /* Check whether we should "reconstitute" the shared message info */
+ if(bt2_rec->flags & H5O_MSG_FLAG_SHARED)
+ H5SM_reconstitute(&(attr->sh_loc), bt2_rec->id);
+
+ /* Set the creation order index for the attribute */
+ attr->crt_idx = bt2_rec->corder;
+
+ /* Make callback */
+ status = (bt2_udata->found_op)(attr, &took_ownership, bt2_udata->found_op_data);
+ HDassert(status >= 0);
+ } /* end if */
+
+ /* Release the space allocated for the attrbute */
+ if(!took_ownership)
+ H5O_msg_free(H5O_ATTR_ID, attr);
+ }
+#endif /* QAK */
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 1dc7ad9..a1f9587 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -289,13 +289,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_fnd_cb(const void *_attr, void *_user_attr)
+H5A_dense_fnd_cb(const H5A_t *attr, hbool_t *took_ownership, void *_user_attr)
{
- const H5A_t *attr = (const H5A_t *)_attr; /* Record from B-tree */
- H5A_t **user_attr = (H5A_t **)_user_attr; /* User data from v2 B-tree attribute lookup */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5A_t const **user_attr = (H5A_t const **)_user_attr; /* User data from v2 B-tree attribute lookup */
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fnd_cb)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_dense_fnd_cb)
/*
* Check arguments.
@@ -303,12 +301,11 @@ H5A_dense_fnd_cb(const void *_attr, void *_user_attr)
HDassert(attr);
HDassert(user_attr);
- /* Copy attribute information */
- if(NULL == (*user_attr = H5A_copy(NULL, attr)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+ /* Take over attribute ownership */
+ *user_attr = attr;
+ *took_ownership = TRUE;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5A_dense_fnd_cb() */
diff --git a/src/H5Aint.c b/src/H5Aint.c
index a8bcedd..953dda2 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -194,7 +194,8 @@ H5A_compact_build_table(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_index_t idx_type,
udata.dxpl_id = dxpl_id;
udata.atable = atable;
udata.curr_attr = 0;
- udata.bogus_crt_idx = (oh->version == H5O_VERSION_1) ? TRUE : FALSE;
+ udata.bogus_crt_idx = (oh->version == H5O_VERSION_1 ||
+ !(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) ? TRUE : FALSE;
/* Iterate over existing attributes, checking for attribute with same name */
op.op_type = H5O_MESG_OP_LIB;
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 8d95ce9..f5d843b 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -95,6 +95,9 @@ typedef struct H5A_dense_bt2_corder_rec_t {
H5O_msg_crt_idx_t corder; /* 'creation order' field value */
} H5A_dense_bt2_corder_rec_t;
+/* Define the 'found' callback function pointer for matching an attribute record in a v2 B-tree */
+typedef herr_t (*H5A_bt2_found_t)(const H5A_t *attr, hbool_t *took_ownership, void *op_data);
+
/*
* Common data exchange structure for dense attribute storage. This structure
* is passed through the v2 B-tree layer to the methods for the objects
@@ -110,7 +113,7 @@ typedef struct H5A_bt2_ud_common_t {
uint32_t name_hash; /* Hash of name of attribute to compare */
uint8_t flags; /* Flags for attribute storage location */
H5O_msg_crt_idx_t corder; /* Creation order value of attribute to compare */
- H5B2_found_t found_op; /* Callback when correct attribute is found */
+ H5A_bt2_found_t found_op; /* Callback when correct attribute is found */
void *found_op_data; /* Callback data when correct attribute is found */
} H5A_bt2_ud_common_t;
diff --git a/src/H5F.c b/src/H5F.c
index 96fe355..6f8796b 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -850,7 +850,6 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
f->shared->extension_addr = HADDR_UNDEF;
f->shared->sohm_addr = HADDR_UNDEF;
f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION;
- f->shared->sohm_nindexes = 0;
f->shared->driver_addr = HADDR_UNDEF;
f->shared->lf = lf;
@@ -2909,6 +2908,34 @@ H5F_decr_nopen_objs(H5F_t *f)
/*-------------------------------------------------------------------------
+ * Function: H5F_store_msg_crt_idx
+ *
+ * Purpose: Retrieve the 'store message creation index' flag for the file.
+ *
+ * Return: Success: Non-negative, the 'store message creation index' flag
+ *
+ * Failure: (can't happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 6 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5F_store_msg_crt_idx(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_store_msg_crt_idx)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->store_msg_crt_idx)
+} /* end H5F_store_msg_crt_idx() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_block_read
*
* Purpose: Reads some data from a file/server/etc into a buffer.
diff --git a/src/H5FD.c b/src/H5FD.c
index ce8d91f..d1cb7c1 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -2444,6 +2444,54 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type
/* Check if we increased the size of the largest block on the list */
file->maxsize = MAX(file->maxsize, last->size);
+ /* Check if this free block adjoins the "metadata aggregator" */
+ if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA && file->eoma != 0) {
+ hbool_t adjoins = FALSE; /* Whether the block adjoined the metadata aggregator */
+
+ /* Does the new block adjoin the end of the metadata aggregator */
+ if((file->eoma + file->cur_meta_block_size) == last->addr) {
+ last->addr = file->eoma;
+ adjoins = TRUE;
+ } /* end if */
+ /* Does the new block adjoin the beginning of the metadata aggregator */
+ else if((last->addr + last->size) == file->eoma)
+ adjoins = TRUE;
+
+ /* Reset metadata aggregator information, if adjoined */
+ if(adjoins) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Adjoined metadata aggregator\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ last->size += file->cur_meta_block_size;
+ file->eoma = 0;
+ file->cur_meta_block_size = 0;
+ } /* end if */
+ } /* end if */
+
+ /* Check if this free block adjoins the "small data aggregator" */
+ if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA && file->eosda != 0) {
+ hbool_t adjoins = FALSE; /* Whether the block adjoined the small-data aggregator */
+
+ /* Does the new block adjoin the end of the small-data aggregator */
+ if((file->eosda + file->cur_sdata_block_size) == last->addr) {
+ last->addr = file->eosda;
+ adjoins = TRUE;
+ } /* end if */
+ /* Does the new block adjoin the beginning of the small-data aggregator */
+ else if((last->addr + last->size) == file->eosda)
+ adjoins = TRUE;
+
+ /* Reset small-data aggregator information, if adjoined */
+ if(adjoins) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Adjoined small data aggregator\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ last->size += file->cur_sdata_block_size;
+ file->eosda = 0;
+ file->cur_sdata_block_size = 0;
+ } /* end if */
+ } /* end if */
+
/* Check if this free block is at the end of file allocated space.
* Truncate it if this is true. */
if(file->cls->get_eoa) {
@@ -2451,6 +2499,9 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type
eoa = file->cls->get_eoa(file, type);
if(eoa == (last->addr + last->size)) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
+#endif /* H5FD_ALLOC_DEBUG */
if(file->cls->set_eoa(file, type, last->addr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 616bb81..10f219f 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -72,7 +72,7 @@ typedef struct H5F_file_t {
uint8_t consist_flags; /* File Consistency Flags */
unsigned flags; /* Access Permissions for file */
- /* Cached values from FCPL */
+ /* Cached values from FCPL/superblock */
unsigned sym_leaf_k; /* Size of leaves in symbol tables */
unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree key values for each type */
size_t sizeof_addr; /* Size of addresses in file */
@@ -102,6 +102,7 @@ typedef struct H5F_file_t {
hsize_t alignment; /* Alignment */
unsigned gc_ref; /* Garbage-collect references? */
hbool_t latest_format; /* Always use the latest format? */
+ hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */
int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
struct H5G_t *root_grp; /* Open root group */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 264218f..14e3c85 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -266,6 +266,7 @@ typedef struct H5F_t H5F_t;
#define H5F_USE_LATEST_FORMAT(F) ((F)->shared->latest_format)
#define H5F_INTENT(F) ((F)->intent)
#define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree)
+#define H5F_STORE_MSG_CRT_IDX(F) ((F)->shared->store_msg_crt_idx)
#else /* H5F_PACKAGE */
#define H5F_FCPL(F) (H5F_get_fcpl(F))
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
@@ -283,6 +284,7 @@ typedef struct H5F_t H5F_t;
#define H5F_USE_LATEST_FORMAT(F) (H5F_use_latest_format(F))
#define H5F_INTENT(F) (H5F_get_intent(F))
#define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F))
+#define H5F_STORE_MSG_CRT_IDX(F) (H5F_store_msg_crt_idx(F))
#endif /* H5F_PACKAGE */
@@ -446,6 +448,7 @@ H5_DLL size_t H5F_sieve_buf_size(const H5F_t *f);
H5_DLL unsigned H5F_gc_ref(const H5F_t *f);
H5_DLL hbool_t H5F_use_latest_format(const H5F_t *f);
H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f);
+H5_DLL hbool_t H5F_store_msg_crt_idx(const H5F_t *f);
/* Functions that operate on blocks of bytes wrt super block */
H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index f8bc556..81dbf2d 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -163,17 +163,17 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
size_t link_size; /* Size of a link message */
/* Calculate message size infomation, for creating group's object header */
- linfo_size = H5O_msg_mesg_size(f, H5O_LINFO_ID, linfo, (size_t)0);
+ linfo_size = H5O_msg_size_f(f, gcpl_id, H5O_LINFO_ID, linfo, (size_t)0);
HDassert(linfo_size);
- ginfo_size = H5O_msg_mesg_size(f, H5O_GINFO_ID, ginfo, (size_t)0);
+ ginfo_size = H5O_msg_size_f(f, gcpl_id, H5O_GINFO_ID, ginfo, (size_t)0);
HDassert(ginfo_size);
lnk.type = H5L_TYPE_HARD;
lnk.corder = 0;
lnk.corder_valid = ginfo->track_corder;
lnk.name = &null_char;
- link_size = H5O_msg_mesg_size(f, H5O_LINK_ID, &lnk, (size_t)ginfo->est_name_len);
+ link_size = H5O_msg_size_f(f, gcpl_id, H5O_LINK_ID, &lnk, (size_t)ginfo->est_name_len);
HDassert(link_size);
/* Compute size of header to use for creation */
@@ -887,6 +887,7 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
/* Check if we should switch from dense storage back to link messages */
if(linfo->nlinks < ginfo.min_dense) {
+ struct H5O_t *oh = NULL; /* Pointer to group's object header */
H5G_link_table_t ltable; /* Table of links */
hbool_t can_convert = TRUE; /* Whether converting to link messages is possible */
size_t u; /* Local index */
@@ -895,24 +896,22 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
if(H5G_dense_build_table(oloc->file, dxpl_id, linfo, H5_INDEX_NAME, H5_ITER_NATIVE, &ltable) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over links")
+ /* Get a pointer to the object header itself */
+ if((oh = H5O_protect(oloc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
+
/* Inspect links in table for ones that can't be converted back
* into link message form (currently only links which can't fit
* into an object header message)
*/
for(u = 0; u < linfo->nlinks; u++)
- if(H5O_msg_mesg_size(oloc->file, H5O_LINK_ID, &(ltable.lnks[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
+ if(H5O_msg_size_oh(oloc->file, oh, H5O_LINK_ID, &(ltable.lnks[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
can_convert = FALSE;
break;
} /* end if */
/* If ok, insert links as link messages */
if(can_convert) {
- struct H5O_t *oh = NULL; /* Pointer to group's object header */
-
- /* Get a pointer to the object header itself */
- if((oh = H5O_protect(oloc, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
-
/* Insert link messages into group */
for(u = 0; u < linfo->nlinks; u++)
if(H5O_msg_append(oloc->file, dxpl_id, oh, H5O_LINK_ID, 0, H5O_UPDATE_TIME, &(ltable.lnks[u])) < 0) {
@@ -923,15 +922,15 @@ H5G_obj_remove_update_linfo(H5O_loc_t *oloc, H5O_linfo_t *linfo, hid_t dxpl_id)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
} /* end if */
- /* Release object header */
- if(H5O_unprotect(oloc, oh) < 0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
-
/* Remove the dense storage */
if(H5G_dense_delete(oloc->file, dxpl_id, linfo, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete dense link storage")
} /* end if */
+ /* Release object header */
+ if(H5O_unprotect(oloc, oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
+
/* Free link table information */
if(H5G_link_release_table(&ltable) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
diff --git a/src/H5O.c b/src/H5O.c
index f4dd5d9..0741621 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -634,9 +634,10 @@ herr_t
H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
H5O_loc_t *loc/*out*/)
{
- H5O_t *oh = NULL;
+ H5O_t *oh = NULL; /* Object header created */
haddr_t oh_addr; /* Address of initial object header */
size_t oh_size; /* Size of initial object header */
+ hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_NOAPI(H5O_create, FAIL)
@@ -653,8 +654,12 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
if(NULL == (oh = H5FL_CALLOC(H5O_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- /* Initialize rudimentary information object object header */
- oh->version = H5F_USE_LATEST_FORMAT(f) ? H5O_VERSION_LATEST : H5O_VERSION_1;
+ /* Initialize file-specific information for object header */
+ store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f);
+ if(H5F_USE_LATEST_FORMAT(f) || store_msg_crt_idx)
+ oh->version = H5O_VERSION_LATEST;
+ else
+ oh->version = H5O_VERSION_1;
oh->sizeof_size = H5F_SIZEOF_SIZE(f);
oh->sizeof_addr = H5F_SIZEOF_ADDR(f);
@@ -676,7 +681,11 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
else
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
- /* Initialize attribute tracking fields */
+ /* Make certain attribute creation order tracking is enabled if
+ * attributes can be shared in this file.
+ */
+ if(store_msg_crt_idx)
+ oh->flags |= H5O_HDR_ATTR_CRT_ORDER_TRACKED;
/* Retrieve attribute storage phase change values from property list */
if(H5P_get(oc_plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &oh->max_compact) < 0)
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 9637055..3e97862 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -258,8 +258,8 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr)
/* Increment attribute count on object */
oh->nattrs++;
- /* Later versions of the object header track the creation index on all messages */
- if(oh->version > H5O_VERSION_1) {
+ /* Later versions of the object header track the creation index on attributes */
+ if(oh->version > H5O_VERSION_1 && (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) {
/* Check for attribute creation order index on the object wrapping around */
if(oh->max_attr_crt_idx == H5O_MAX_CRT_ORDER_IDX)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINC, FAIL, "attribute creation index can't be incremented")
@@ -1145,7 +1145,7 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, hid_t dxpl_id)
* can't fit into an object header message)
*/
for(u = 0; u < oh->nattrs; u++)
- if(H5O_msg_mesg_size(loc->file, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
+ if(H5O_msg_size_oh(loc->file, oh, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
can_convert = FALSE;
break;
} /* end if */
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index c4430e6..7000e9e 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -150,7 +150,9 @@ H5O_flush_msgs(H5F_t *f, H5O_t *oh)
} /* end for */
/* Only encode creation index for version 2+ of format */
else {
- UINT16ENCODE(p, curr_msg->crt_idx);
+ /* Only encode creation index if they are being tracked */
+ if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+ UINT16ENCODE(p, curr_msg->crt_idx);
} /* end else */
HDassert(p == curr_msg->raw);
@@ -262,7 +264,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
if(NULL == (oh = H5FL_CALLOC(H5O_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Generic, non-stored information */
+ /* File-specific, non-stored information */
oh->sizeof_size = H5F_SIZEOF_SIZE(f);
oh->sizeof_addr = H5F_SIZEOF_ADDR(f);
@@ -326,7 +328,12 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
H5F_addr_decode(f, &p, &(oh->attr_fheap_addr));
H5F_addr_decode(f, &p, &(oh->name_bt2_addr));
H5F_addr_decode(f, &p, &(oh->corder_bt2_addr));
- UINT16DECODE(p, oh->max_attr_crt_idx);
+
+ /* Only encode max. creation index if they are being tracked */
+ if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+ UINT16DECODE(p, oh->max_attr_crt_idx)
+ else
+ oh->max_attr_crt_idx = 0;
} /* end if */
else {
/* Reset unused time fields */
@@ -449,17 +456,28 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
H5O_msg_crt_idx_t crt_idx = H5O_MAX_CRT_ORDER_IDX; /* Creation index for current message */
/* Decode message prefix info */
+
+ /* Version # */
if(oh->version == H5O_VERSION_1)
UINT16DECODE(p, id)
else
id = *p++;
+
+ /* Message size */
UINT16DECODE(p, mesg_size);
HDassert(mesg_size == H5O_ALIGN_OH(oh, mesg_size));
+
+ /* Message flags */
flags = *p++;
+
+ /* Reserved bytes/creation index */
if(oh->version == H5O_VERSION_1)
p += 3; /*reserved*/
- else
- UINT16DECODE(p, crt_idx);
+ else {
+ /* Only encode creation index if they are being tracked */
+ if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+ UINT16DECODE(p, crt_idx);
+ } /* end else */
/* Try to detect invalidly formatted object header message that
* extends past end of chunk.
@@ -675,7 +693,10 @@ H5O_assert(oh);
H5F_addr_encode(f, &p, oh->attr_fheap_addr);
H5F_addr_encode(f, &p, oh->name_bt2_addr);
H5F_addr_encode(f, &p, oh->corder_bt2_addr);
- UINT16ENCODE(p, oh->max_attr_crt_idx);
+
+ /* Only encode max. creation index if they are being tracked */
+ if(oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+ UINT16ENCODE(p, oh->max_attr_crt_idx);
/* Chunk size */
UINT32ENCODE(p, (oh->chunk[0].size - H5O_SIZEOF_HDR(oh)));
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index cccf8b8..bf0d0b0 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -37,6 +37,7 @@
#include "H5Aprivate.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* File access */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
@@ -1327,7 +1328,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_msg_mesg_size
+ * Function: H5O_msg_size_f
*
* Purpose: Calculate the final size of an encoded message in an object
* header.
@@ -1344,12 +1345,15 @@ done:
*-------------------------------------------------------------------------
*/
size_t
-H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t extra_raw)
+H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id,
+ const void *mesg, size_t extra_raw)
{
- const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
- size_t ret_value; /* Return value */
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
+ H5P_genplist_t *ocpl; /* Object Creation Property list */
+ uint8_t oh_flags; /* Object header status flags */
+ size_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_msg_mesg_size, 0)
+ FUNC_ENTER_NOAPI(H5O_msg_size_f, 0)
/* Check args */
HDassert(type_id < NELMTS(H5O_msg_class_g));
@@ -1359,6 +1363,15 @@ H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t ext
HDassert(f);
HDassert(mesg);
+ /* Get the property list */
+ if(NULL == (ocpl = H5I_object(ocpl_id)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, 0, "not a property list")
+
+ /* Get any object header status flags set by properties */
+ if(H5P_get(ocpl, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "can't get object header flags")
+
+
/* Compute the raw data size for the mesg */
if((ret_value = (type->raw_size)(f, FALSE, mesg)) == 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message")
@@ -1370,11 +1383,64 @@ H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg, size_t ext
ret_value = H5O_ALIGN_F(f, ret_value);
/* Add space for message header */
- ret_value += H5O_SIZEOF_MSGHDR_F(f);
+ ret_value += H5O_SIZEOF_MSGHDR_F(f,
+ (H5F_STORE_MSG_CRT_IDX(f) || oh_flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED));
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_msg_size_f() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_msg_size_oh
+ *
+ * Purpose: Calculate the final size of an encoded message in an object
+ * header.
+ *
+ * Note: This routine assumes that the message is already used in
+ * an object header.
+ *
+ * Return: Size of message on success, 0 on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Mar 7 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5O_msg_size_oh(const H5F_t *f, const H5O_t *oh, unsigned type_id,
+ const void *mesg, size_t extra_raw)
+{
+ const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_msg_size_oh, 0)
+
+ /* Check args */
+ HDassert(type_id < NELMTS(H5O_msg_class_g));
+ type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(type->raw_size);
+ HDassert(f);
+ HDassert(mesg);
+
+ /* Compute the raw data size for the mesg */
+ if((ret_value = (type->raw_size)(f, FALSE, mesg)) == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, 0, "unable to determine size of message")
+
+ /* Add in "extra" raw space */
+ ret_value += extra_raw;
+
+ /* Adjust size for alignment, if necessary */
+ ret_value = H5O_ALIGN_OH(oh, ret_value);
+
+ /* Add space for message header */
+ ret_value += H5O_SIZEOF_MSGHDR_OH(oh);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_msg_mesg_size() */
+} /* end H5O_msg_size_oh() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 716260e..68066cf 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -120,7 +120,9 @@
(O)->sizeof_addr + /*addr of attribute heap */ \
(O)->sizeof_addr + /*addr of attribute name index */ \
(O)->sizeof_addr + /*addr of attribute creation order index */ \
- 2 + /*max attr. creation index */ \
+ (((O)->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? ( \
+ 2 /*max attr. creation index */ \
+ ) : 0) + \
4 + /*chunk data size */ \
H5O_SIZEOF_CHKSUM) /*checksum size */ \
)
@@ -128,7 +130,7 @@
/*
* Size of object header message prefix
*/
-#define H5O_SIZEOF_MSGHDR_VERS(V) \
+#define H5O_SIZEOF_MSGHDR_VERS(V,C) \
(((V) == H5O_VERSION_1) \
? \
H5O_ALIGN_OLD(2 + /*message type */ \
@@ -139,12 +141,14 @@
(1 + /*message type */ \
2 + /*sizeof message data */ \
1 + /*flags */ \
- 2) /*creation index */ \
+ ((C) ? ( \
+ 2 /*creation index */ \
+ ) : 0)) \
)
#define H5O_SIZEOF_MSGHDR_OH(O) \
- H5O_SIZEOF_MSGHDR_VERS((O)->version)
-#define H5O_SIZEOF_MSGHDR_F(F) \
- H5O_SIZEOF_MSGHDR_VERS(H5F_USE_LATEST_FORMAT(F) ? H5O_VERSION_LATEST : H5O_VERSION_1)
+ H5O_SIZEOF_MSGHDR_VERS((O)->version, (O)->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)
+#define H5O_SIZEOF_MSGHDR_F(F, C) \
+ H5O_SIZEOF_MSGHDR_VERS((H5F_USE_LATEST_FORMAT(F) || H5F_STORE_MSG_CRT_IDX(F)) ? H5O_VERSION_LATEST : H5O_VERSION_1, (C))
/*
* Size of chunk "header" for each chunk
@@ -241,7 +245,7 @@ struct H5O_t {
H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
/* first field in structure */
- /* General information (not stored) */
+ /* File-specific information (not stored) */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 0d1f918..5349827 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -477,8 +477,10 @@ H5_DLL herr_t H5O_msg_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operat
void *op_data, hid_t dxpl_id);
H5_DLL size_t H5O_msg_raw_size(const H5F_t *f, unsigned type_id,
hbool_t disable_shared, const void *mesg);
-H5_DLL size_t H5O_msg_mesg_size(const H5F_t *f, unsigned type_id, const void *mesg,
- size_t extra_raw);
+H5_DLL size_t H5O_msg_size_f(const H5F_t *f, hid_t ocpl_id, unsigned type_id,
+ const void *mesg, size_t extra_raw);
+H5_DLL size_t H5O_msg_size_oh(const H5F_t *f, const H5O_t *oh, unsigned type_id,
+ const void *mesg, size_t extra_raw);
H5_DLL htri_t H5O_msg_is_shared(unsigned type_id, const void *mesg);
H5_DLL htri_t H5O_msg_can_share(unsigned type_id, const void *mesg);
H5_DLL herr_t H5O_msg_set_share(unsigned type_id, H5O_shared_t *share, void *mesg);
diff --git a/src/H5SM.c b/src/H5SM.c
index 8192c21..f923664 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -197,6 +197,12 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d
/* Record the address of the master table in the file */
f->shared->sohm_addr = table_addr;
+ /* Check for sharing attributes in this file, which means that creation
+ * indices must be tracked on object header message in the file.
+ */
+ if(type_flags_used & H5O_MESG_ATTR_FLAG)
+ f->shared->store_msg_crt_idx = TRUE;
+
/* Write shared message information to the superblock extension */
sohm_table.addr = f->shared->sohm_addr;
sohm_table.version = f->shared->sohm_vers;
@@ -1535,6 +1541,12 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id)
/* Sanity check */
HDassert(sohm_l2b == table->indexes[u].list_max);
HDassert(sohm_b2l == table->indexes[u].btree_min);
+
+ /* Check for sharing attributes in this file, which means that creation
+ * indices must be tracked on object header message in the file.
+ */
+ if(index_flags[u] & H5O_MESG_ATTR_FLAG)
+ shared->store_msg_crt_idx = TRUE;
} /* end for */
/* Set values in the property list */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index b198a37..684b9ff 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -270,7 +270,7 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t dxpl_id, hid_t tcpl_id, hid_t UNUSED
loc_init = TRUE;
/* Calculate message size infomation, for creating object header */
- dtype_size = H5O_msg_mesg_size(file, H5O_DTYPE_ID, type, (size_t)0);
+ dtype_size = H5O_msg_size_f(file, tcpl_id, H5O_DTYPE_ID, type, (size_t)0);
HDassert(dtype_size);
/*