summaryrefslogtreecommitdiffstats
path: root/src/H5Abtree2.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-03-08 20:10:12 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-03-08 20:10:12 (GMT)
commit74a30fff3e0fcd8919ced487abd03eefd27d57c1 (patch)
tree2df0a0d2cfc51cce067f25e503e6dfd26c8e827d /src/H5Abtree2.c
parent25bb6f5dd8af42d2facaab26f0cdeb7fc76456ae (diff)
downloadhdf5-74a30fff3e0fcd8919ced487abd03eefd27d57c1.zip
hdf5-74a30fff3e0fcd8919ced487abd03eefd27d57c1.tar.gz
hdf5-74a30fff3e0fcd8919ced487abd03eefd27d57c1.tar.bz2
[svn-r13477] Description:
The main purpose of this checkin was to eliminate the space used for tracking creation time indices when there is no way they can be used (i.e. attributes can't be shared in the file and the user hasn't turned on attribute creation tracking), however there were some other minor changes which crept in: - Fix a cache locking deadlock when a shared attribute and one of its components end up in the same fractal heap direct block. (This is fixed the "slow" way for right now, until John has time to add support for readers/writer locking to the cache. - Optimize attribute copying when a copy will be kept during a v2 B-tree search. - When freeing a block on disk, attempt to merge it with the metadata and "small data" aggregators. Tested on: Mac OS X/32 10.4.8 (amazon) FreeBSD/32 6.2 (duty)
Diffstat (limited to 'src/H5Abtree2.c')
-rw-r--r--src/H5Abtree2.c87
1 files changed, 84 insertions, 3 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)