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