diff options
Diffstat (limited to 'src/H5Abtree2.c')
-rw-r--r-- | src/H5Abtree2.c | 87 |
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) |