diff options
author | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2014-06-11 22:25:52 (GMT) |
---|---|---|
committer | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2014-06-11 22:25:52 (GMT) |
commit | 058eba7f5ba66817f1a544117c463f4f1200a8fb (patch) | |
tree | fd2460afaf956605a8713dbd0b1c86717587d476 /src/H5Xalacrity.c | |
parent | a0aa11c0b2ba024e69e3d8ff5185057acd49df3a (diff) | |
download | hdf5-058eba7f5ba66817f1a544117c463f4f1200a8fb.zip hdf5-058eba7f5ba66817f1a544117c463f4f1200a8fb.tar.gz hdf5-058eba7f5ba66817f1a544117c463f4f1200a8fb.tar.bz2 |
[svn-r25265] Clean up ALACRITY plugin
Free ALACRITY resources correctly
Get range from query
Fix hyperslab selection
Fix index example
Diffstat (limited to 'src/H5Xalacrity.c')
-rw-r--r-- | src/H5Xalacrity.c | 582 |
1 files changed, 403 insertions, 179 deletions
diff --git a/src/H5Xalacrity.c b/src/H5Xalacrity.c index d7dce42..345c827 100644 --- a/src/H5Xalacrity.c +++ b/src/H5Xalacrity.c @@ -33,6 +33,7 @@ #include "H5RCprivate.h" #include "H5TRprivate.h" #include "H5Qprivate.h" +#include "H5VMprivate.h" /* TODO using private headers but could use public ones */ #include <alacrity.h> @@ -57,21 +58,35 @@ /* Local Typedefs */ /******************/ typedef struct H5X_alacrity_t { - hbool_t metadata_read; /* Has metadata been read already */ - ALMetadata metadata; /* Alacrity metadata */ - ALEncoderConfig config; /* Alacrity config */ - ALPartitionData output; /* Alacrity output */ - hid_t opaque_type_id; /* Datatype used for index datasets */ - hid_t metadata_id; /* Array for metadata */ - hid_t index_id; /* Array for index data */ + void *private_metadata; /* Internal metadata */ + + hid_t dataset_id; /* ID of the indexed dataset */ + unsigned dataset_ndims; /* dataset number of dimensions */ + hsize_t *dataset_dims; /* dataset dimensions */ + hsize_t *dataset_down_dims; /* dataset downed dimensions */ + + ALMetadata *metadata; /* Alacrity metadata */ + ALEncoderConfig config; /* Alacrity config */ + ALPartitionData *output; /* Alacrity output */ + hid_t opaque_type_id; /* Datatype used for index datasets */ + hid_t metadata_id; /* Array for metadata */ + hid_t index_id; /* Array for index data */ } H5X_alacrity_t; +typedef struct H5X_alacrity_range_t { + value_types_t lb; /* Lower bound */ + value_types_t ub; /* Upper bound */ +} H5X_alacrity_range_t; + /********************/ /* Local Prototypes */ /********************/ +static H5X_alacrity_t * +H5X__alacrity_init(hid_t dataset_id); + static herr_t -H5X__alacrity_configure(H5X_alacrity_t *alacrity, hid_t dataset_id); +H5X__alacrity_term(H5X_alacrity_t *alacrity); static herr_t H5X__alacrity_read_data(hid_t dataset_id, hid_t rcxt_id, void **buf, @@ -90,19 +105,27 @@ H5X__alacrity_deserialize_metadata(H5X_alacrity_t *alacrity, void *buf, hid_t trans_id); static herr_t -H5X__alacrity_get_query_range(hid_t query_id, value_types_t *query_lb, - value_types_t *query_ub); +H5X__alacrity_get_query_value(H5Q_t *query, value_types_t *value); + +static herr_t +H5X__alacrity_get_query_ranges(hid_t query_id, + H5X_alacrity_range_t *query_ranges, size_t *nranges); static hbool_t H5X__alacrity_find_bin_range(ALMetadata *metadata, value_types_t query_lb, value_types_t query_ub, bin_id_t *start_bin, bin_id_t *end_bin); static herr_t +H5X__alacrity_read_metadata(H5X_alacrity_t *alacrity, hid_t rcxt_id); + +static herr_t H5X__alacrity_read_index(H5X_alacrity_t *alacrity, bin_id_t start_bin, bin_id_t end_bin, hid_t rcxt_id, ALIndex *al_index, size_t *al_index_size); - +static herr_t +H5X__alacrity_query_range(H5X_alacrity_t *alacrity, hid_t dataspace_id, + H5X_alacrity_range_t query_range, hid_t rcxt_id); static void * H5X_alacrity_create(hid_t file_id, hid_t dataset_id, hid_t xcpl_id, @@ -169,7 +192,7 @@ const H5X_class_t H5X_ALACRITY[1] = {{ }}; /*------------------------------------------------------------------------- - * Function: H5X__alacrity_configure + * Function: H5X__alacrity_init * * Purpose: Configure and set up and the ALACRITY encoder. * @@ -177,32 +200,63 @@ const H5X_class_t H5X_ALACRITY[1] = {{ * *------------------------------------------------------------------------- */ -static herr_t -H5X__alacrity_configure(H5X_alacrity_t *alacrity, hid_t dataset_id) +static H5X_alacrity_t * +H5X__alacrity_init(hid_t dataset_id) { - hid_t type_id = FAIL; + H5X_alacrity_t *alacrity = NULL; + hid_t type_id = FAIL, space_id = FAIL; size_t type_size; ALDatatype al_type; - herr_t ret_value = SUCCEED; /* Return value */ + H5X_alacrity_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT - /* Create an opaque type to handle ALACRITY data */ - if (FAIL == (alacrity->opaque_type_id = H5Tcreate(H5T_OPAQUE, 1))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCREATE, FAIL, "can't create type"); - if (FAIL == H5Tset_tag(alacrity->opaque_type_id, "alacrity metadata type")) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set tag to type"); + if (NULL == (alacrity = (H5X_alacrity_t *) H5MM_malloc(sizeof(H5X_alacrity_t)))) + HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate alacrity struct"); + alacrity->private_metadata = NULL; + alacrity->dataset_id = dataset_id; + + /* Get dimensions of dataset */ + if (FAIL == (space_id = H5Dget_space(dataset_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get dataspace from dataset"); + if (0 == (alacrity->dataset_ndims = (unsigned) H5Sget_simple_extent_ndims(space_id))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, NULL, "invalid number of dimensions"); + if (NULL == (alacrity->dataset_dims = H5MM_malloc(alacrity->dataset_ndims * sizeof(hsize_t)))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, NULL, "can't allocate dim array"); + if (FAIL == H5Sget_simple_extent_dims(space_id, alacrity->dataset_dims, NULL)) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, NULL, "can't get dataspace dims"); + + /* Useful for coordinate conversion */ + if (NULL == (alacrity->dataset_down_dims = H5MM_malloc(alacrity->dataset_ndims * sizeof(hsize_t)))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, NULL, "can't allocate dim array"); + if (FAIL == H5VM_array_down(alacrity->dataset_ndims, alacrity->dataset_dims, + alacrity->dataset_down_dims)) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, NULL, "can't get dataspace down dims"); + + alacrity->metadata = NULL; + alacrity->output = NULL; if (FAIL == (type_id = H5Dget_type(dataset_id))) - HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get type from dataset"); + HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get type from dataset"); if (0 == (type_size = H5Tget_size(type_id))) - HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get type size"); + HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get type size"); al_type = (type_size == 4) ? DATATYPE_FLOAT32 : DATATYPE_FLOAT64; if (ALErrorNone != ALEncoderConfigure(&alacrity->config, 16, al_type, ALInvertedIndex)) - HGOTO_ERROR(H5E_INDEX, H5E_CANTSET, FAIL, "can't configure ALACRITY encoder"); + HGOTO_ERROR(H5E_INDEX, H5E_CANTSET, NULL, "can't configure ALACRITY encoder"); + + /* Create an opaque type to handle ALACRITY data */ + if (FAIL == (alacrity->opaque_type_id = H5Tcreate(H5T_OPAQUE, 1))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCREATE, NULL, "can't create type"); + if (FAIL == H5Tset_tag(alacrity->opaque_type_id, "alacrity metadata type")) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, NULL, "can't set tag to type"); + + alacrity->metadata_id = FAIL; + alacrity->index_id = FAIL; + + ret_value = alacrity; done: if (type_id != FAIL) @@ -211,6 +265,63 @@ done: } /*------------------------------------------------------------------------- + * Function: H5X__alacrity_term + * + * Purpose: Free plugin resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5X__alacrity_term(H5X_alacrity_t *alacrity) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if (!alacrity) + HGOTO_DONE(SUCCEED); + + H5MM_free(alacrity->private_metadata); + + /* Free dim arrays */ + H5MM_free(alacrity->dataset_dims); + H5MM_free(alacrity->dataset_down_dims); + + /* Free metadata if created */ + if (alacrity->metadata) { + H5MM_free(alacrity->metadata->binLayout.binStartOffsets); + H5MM_free(alacrity->metadata->binLayout.binValues); + H5MM_free(alacrity->metadata); + } + + /* Free output if created */ + if (alacrity->output) { + ALPartitionDataDestroy(alacrity->output); + H5MM_free(alacrity->output); + } + + /* Close opaque type */ + if ((FAIL != alacrity->opaque_type_id) && + (FAIL == H5Tclose(alacrity->opaque_type_id))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close opaque type"); + + /* Close anonymous dataset */ + if ((FAIL != alacrity->metadata_id) && + (FAIL == H5Dclose_ff(alacrity->metadata_id, H5_EVENT_STACK_NULL))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close anonymous dataset for index"); + if ((FAIL != alacrity->index_id) && + (FAIL == H5Dclose_ff(alacrity->index_id, H5_EVENT_STACK_NULL))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close anonymous dataset for index"); + + H5MM_free(alacrity); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- * Function: H5X__alacrity_read_data * * Purpose: Read data from dataset. @@ -286,20 +397,24 @@ H5X__alacrity_create_index(H5X_alacrity_t *alacrity, hid_t file_id, FUNC_ENTER_NOAPI_NOINIT + /* Allocate PartitionData struct */ + if (NULL == (alacrity->output = H5MM_malloc(sizeof(ALPartitionData)))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate ALACRITY output"); + /* Get number of elements */ nelmts = buf_size / ((size_t) alacrity->config.elementSize); /* Call ALACRITY encoder */ H5X_ALACRITY_LOG_DEBUG("Calling ALACRITY encoder on data (%zu elements)", nelmts); - if (ALErrorNone != ALEncode(&alacrity->config, buf, nelmts, &alacrity->output)) + if (ALErrorNone != ALEncode(&alacrity->config, buf, nelmts, alacrity->output)) HGOTO_ERROR(H5E_INDEX, H5E_CANTENCODE, FAIL, "ALACRITY encoder failed"); /* Get sizes */ - if (0 == (metadata_size = ALGetMetadataSize(&alacrity->output.metadata))) + if (0 == (metadata_size = ALGetMetadataSize(&alacrity->output->metadata))) HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "ALACRITY metadata size is NULL"); - if (0 == (index_size = ALGetIndexSize(&alacrity->output.index, - &alacrity->output.metadata))) + if (0 == (index_size = ALGetIndexSize(&alacrity->output->index, + &alacrity->output->metadata))) HGOTO_ERROR(H5E_INDEX, H5E_BADVALUE, FAIL, "ALACRITY index size is NULL"); H5X_ALACRITY_LOG_DEBUG("Metadata size: %zu", (size_t) metadata_size); @@ -323,7 +438,7 @@ H5X__alacrity_create_index(H5X_alacrity_t *alacrity, hid_t file_id, if (NULL == (metadata_buf = H5MM_malloc(metadata_size))) HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate metadata buffer"); memstreamInit(&memstream, metadata_buf); - if (ALErrorNone != ALSerializeMetadata(&alacrity->output.metadata, &memstream)) + if (ALErrorNone != ALSerializeMetadata(&alacrity->output->metadata, &memstream)) HGOTO_ERROR(H5E_INDEX, H5E_CANTSERIALIZE, FAIL, "can't serialize ALACRITY metadata"); if (FAIL == H5Dwrite_ff(alacrity->metadata_id, alacrity->opaque_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, memstream.buf, trans_id, H5_EVENT_STACK_NULL)) @@ -332,14 +447,19 @@ H5X__alacrity_create_index(H5X_alacrity_t *alacrity, hid_t file_id, /* Write ALACRITY index */ if (FAIL == H5Dwrite_ff(alacrity->index_id, alacrity->opaque_type_id, H5S_ALL, - H5S_ALL, H5P_DEFAULT, alacrity->output.index, trans_id, H5_EVENT_STACK_NULL)) + H5S_ALL, H5P_DEFAULT, alacrity->output->index, trans_id, H5_EVENT_STACK_NULL)) HGOTO_ERROR(H5E_INDEX, H5E_CANTUPDATE, FAIL, "can't write index data"); + done: H5MM_free(metadata_buf); if (metadata_space_id != FAIL) H5Sclose(metadata_space_id); if (index_space_id != FAIL) H5Sclose(index_space_id); + if (err_occurred) { + H5MM_free(alacrity->output); + alacrity->output = NULL; + } FUNC_LEAVE_NOAPI(ret_value) } @@ -439,46 +559,104 @@ done: } /*------------------------------------------------------------------------- - * Function: H5X__alacrity_get_query_range + * Function: H5X__alacrity_get_query_value * - * Purpose: Get range value from query. + * Purpose: Get value from query. * * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ static herr_t -H5X__alacrity_get_query_range(hid_t query_id, value_types_t *query_lb, - value_types_t *query_ub) +H5X__alacrity_get_query_value(H5Q_t *query, value_types_t *value) { - H5Q_t *query; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT - if (NULL == (query = (H5Q_t *) H5I_object_verify(query_id, H5I_QUERY))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID"); + switch (query->query.select.elem.data_elem.type_size) { + case sizeof(double): + value->asDouble = + *((double *) query->query.select.elem.data_elem.value); + H5X_ALACRITY_LOG_DEBUG("Double %lf\n", value->asDouble); + break; + case sizeof(float): + value->asFloat = + *((float *) query->query.select.elem.data_elem.value); + H5X_ALACRITY_LOG_DEBUG("Float %f\n", value->asFloat); + break; + default: + HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "unsupported query element type"); + } - if (query->is_combined) { +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5X__alacrity_get_query_ranges + * + * Purpose: Get range value from query. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5X__alacrity_get_query_range(H5Q_t *query, H5X_alacrity_range_t *query_range) +{ + herr_t ret_value = SUCCEED; /* Return value */ + /* Would also need min and max values */ + + FUNC_ENTER_NOAPI_NOINIT + if (query->is_combined) { + H5X__alacrity_get_query_range(query->query.combine.l_query, query_range); + H5X__alacrity_get_query_range(query->query.combine.r_query, query_range); } else { if (H5Q_TYPE_DATA_ELEM != query->query.select.type) HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "unsupported query type"); if (query->query.select.match_op == H5Q_MATCH_GREATER_THAN) { /* This is a lower bound */ + H5X__alacrity_get_query_value(query, &query_range->lb); } if (query->query.select.match_op == H5Q_MATCH_LESS_THAN) { /* This is a higher bound */ + H5X__alacrity_get_query_value(query, &query_range->ub); } if (query->query.select.match_op == H5Q_MATCH_EQUAL) { /* Lower bound is equal to higher bound */ - query_lb->asFloat = *((float *) query->query.select.elem.data_elem.value); + H5X__alacrity_get_query_value(query, &query_range->lb); + query_range->ub = query_range->lb; } } - /* Find bins that satisfy query */ - query_lb->asFloat = 39.1f; - query_ub->asFloat = 42.1f; +done: + FUNC_LEAVE_NOAPI(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5X__alacrity_get_query_ranges + * + * Purpose: Get range value from query. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5X__alacrity_get_query_ranges(hid_t query_id, + H5X_alacrity_range_t *query_ranges, size_t *nranges) +{ + H5Q_t *query; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if (NULL == (query = (H5Q_t *) H5I_object_verify(query_id, H5I_QUERY))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID"); + + H5X__alacrity_get_query_range(query, query_ranges); done: FUNC_LEAVE_NOAPI(ret_value) @@ -526,9 +704,60 @@ H5X__alacrity_find_bin_range(ALMetadata *metadata, value_types_t query_lb, } /*------------------------------------------------------------------------- - * Function: H5X__alacrity_readIndex + * Function: H5X__alacrity_read_metadata * - * Purpose: Read index that correspond to selected bins + * Purpose: Read ALACRITY metadata + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5X__alacrity_read_metadata(H5X_alacrity_t *alacrity, hid_t rcxt_id) +{ + memstream_t memstream; /* Alacrity Memstream */ + hid_t metadata_space_id = FAIL; + void *buf; + size_t buf_size; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* allocate space for ALACRITY metadata */ + if (NULL == (alacrity->metadata = H5MM_malloc(sizeof(ALMetadata)))) + HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate ALACRITY metadata"); + + if (FAIL == (metadata_space_id = H5Dget_space(alacrity->metadata_id))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get dataspace from index"); + if (0 == (buf_size = (size_t) H5Sget_select_npoints(metadata_space_id))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements"); + + /* allocate buffer to hold data */ + if (NULL == (buf = H5MM_malloc(buf_size))) + HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate read buffer"); + + /* read metadata */ + if (FAIL == H5Dread_ff(alacrity->metadata_id, alacrity->opaque_type_id, + H5S_ALL, metadata_space_id, H5P_DEFAULT, buf, rcxt_id, + H5_EVENT_STACK_NULL)) + HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read data"); + + memstreamInit(&memstream, buf); + if (ALErrorNone != ALDeserializeMetadata(alacrity->metadata, &memstream)) + HGOTO_ERROR(H5E_INDEX, H5E_CANTDECODE, FAIL, "can't deserialize metadata"); + memstreamDestroy(&memstream, 0); + +done: + H5MM_free(buf); + if (FAIL != metadata_space_id) + H5Sclose(metadata_space_id); + FUNC_LEAVE_NOAPI(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5X__alacrity_read_index + * + * Purpose: Read ALACRITY index that correspond to selected bins * * Return: Non-negative on success/Negative on failure * @@ -539,7 +768,7 @@ H5X__alacrity_read_index(H5X_alacrity_t *alacrity, bin_id_t start_bin, bin_id_t end_bin, hid_t rcxt_id, ALIndex *al_index, size_t *al_index_size) { - const ALMetadata *meta = &alacrity->metadata; + const ALMetadata *meta = alacrity->metadata; const hsize_t first_bin_off = (hsize_t) ALGetIndexBinOffset(meta, start_bin); const hsize_t last_bin_off = (hsize_t) ALGetIndexBinOffset(meta, end_bin); const hsize_t bin_read_len = last_bin_off - first_bin_off; @@ -590,6 +819,87 @@ done: } /*------------------------------------------------------------------------- + * Function: H5X__alacrity_query_range + * + * Purpose: Read index that correspond to selected bins + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5X__alacrity_query_range(H5X_alacrity_t *alacrity, hid_t dataspace_id, + H5X_alacrity_range_t query_range, hid_t rcxt_id) +{ + ALIndex al_index = NULL; + bool found_bin; + bin_id_t start_bin = 0, end_bin = 0; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /** + * First, find which bins are touched by the query (all elements in the + * query range will fall into these bins, however not all elements in these + * bins fall into the query range). + */ + found_bin = H5X__alacrity_find_bin_range(alacrity->metadata, query_range.lb, + query_range.ub, &start_bin, &end_bin); + + /* If bins were found, read index and create dataspace */ + if (found_bin) { + rid_t *al_index_rids = NULL; + size_t al_index_size; + hsize_t count[H5S_MAX_RANK + 1]; + hsize_t start_coord[H5S_MAX_RANK + 1], end_coord[H5S_MAX_RANK + 1], nelmts; + unsigned int i; + + if (FAIL == H5X__alacrity_read_index(alacrity, start_bin, end_bin, + rcxt_id, &al_index, &al_index_size)) + HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read index"); + al_index_rids = (rid_t *) al_index; + +#ifdef H5X_ALACRITY_DEBUG + /* TODO remove debug */ + printf(" # %s(): Index read contains following rIDs: ", __func__); + for (i = 0; i < al_index_size / (sizeof(rid_t)); i++) { + printf("%d ", al_index_rids[i]); + } + printf("\n"); +#endif + + /* Initialize count */ + for (i = 0; i < H5S_MAX_RANK; i++) + count[i] = 1; + + for (i = 0; i < al_index_size / (sizeof(rid_t)); i++) { + hsize_t coords[H5S_MAX_RANK + 1]; + const hsize_t point = al_index_rids[i]; + + /* Convert coordinates */ + if (FAIL == H5VM_array_calc_pre(point, alacrity->dataset_ndims, + alacrity->dataset_down_dims, coords)) + HGOTO_ERROR(H5E_INDEX, H5E_CANTALLOC, FAIL, "can't allocate coord array"); + + /* Add converted coordinate to selection */ + if (H5Sselect_hyperslab(dataspace_id, H5S_SELECT_OR, coords, NULL, count, NULL)) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to add point to selection"); + } + + if (FAIL == H5Sget_select_bounds(dataspace_id, start_coord, end_coord)) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to get bounds"); + if (0 == (nelmts = (hsize_t) H5Sget_select_npoints(dataspace_id))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements"); + H5X_ALACRITY_LOG_DEBUG("Created dataspace from index with %llu elements [(%llu, %llu):(%llu, %llu)]", + nelmts, start_coord[0], start_coord[1], end_coord[0], end_coord[1]); + } + +done: + H5MM_free(al_index); + FUNC_LEAVE_NOAPI(ret_value); +} + +/*------------------------------------------------------------------------- * Function: H5X_alacrity_create * * Purpose: This function creates a new instance of a ALACRITY plugin index. @@ -604,10 +914,9 @@ H5X_alacrity_create(hid_t file_id, hid_t dataset_id, hid_t UNUSED xcpl_id, hid_t xapl_id, size_t *metadata_size, void **metadata) { H5X_alacrity_t *alacrity = NULL; - hid_t trans_id, rcxt_id; + hid_t trans_id = FAIL, rcxt_id = FAIL; void *ret_value = NULL; /* Return value */ - size_t alacrity_metadata_size; - void *alacrity_metadata; + size_t private_metadata_size; void *buf = NULL; size_t buf_size; uint64_t version; @@ -615,13 +924,9 @@ H5X_alacrity_create(hid_t file_id, hid_t dataset_id, hid_t UNUSED xcpl_id, FUNC_ENTER_NOAPI_NOINIT H5X_ALACRITY_LOG_DEBUG("Enter"); - if (NULL == (alacrity = (H5X_alacrity_t *) H5MM_malloc(sizeof(H5X_alacrity_t)))) - HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate alacrity struct"); - alacrity->metadata_read = FALSE; - - /* Configure the ALACRITY encoder */ - if (FAIL == H5X__alacrity_configure(alacrity, dataset_id)) - HGOTO_ERROR(H5E_INDEX, H5E_CANTSET, NULL, "can't configure ALACRITY"); + /* Initialize ALACRITY plugin */ + if (NULL == (alacrity = H5X__alacrity_init(dataset_id))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTSET, NULL, "can't initialize ALACRITY"); /* Get transaction ID from xapl */ if (FAIL == H5Pget_xapl_transaction(xapl_id, &trans_id)) @@ -644,28 +949,29 @@ H5X_alacrity_create(hid_t file_id, hid_t dataset_id, hid_t UNUSED xcpl_id, /* Serialize metadata for H5X interface */ if (FAIL == H5X__alacrity_serialize_metadata(alacrity, NULL, - &alacrity_metadata_size)) + &private_metadata_size)) HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get plugin metadata size"); - if (NULL == (alacrity_metadata = H5MM_malloc(alacrity_metadata_size))) + if (NULL == (alacrity->private_metadata = H5MM_malloc(private_metadata_size))) HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate plugin metadata"); - if (FAIL == H5X__alacrity_serialize_metadata(alacrity, alacrity_metadata, - &alacrity_metadata_size)) + /* Serialize plugin metadata */ + if (FAIL == H5X__alacrity_serialize_metadata(alacrity, alacrity->private_metadata, + &private_metadata_size)) HGOTO_ERROR(H5E_INDEX, H5E_CANTENCODE, NULL, "can't serialize plugin metadata"); /* Metadata is token for anonymous dataset */ - *metadata = alacrity_metadata; - *metadata_size = alacrity_metadata_size; + *metadata = alacrity->private_metadata; + *metadata_size = private_metadata_size; ret_value = alacrity; done: - if (NULL == ret_value) - H5MM_free(alacrity); if (FAIL != rcxt_id) H5RCclose(rcxt_id); H5MM_free(buf); + if (NULL == ret_value) + H5X__alacrity_term(alacrity); H5X_ALACRITY_LOG_DEBUG("Leave"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5X_alacrity_create() */ @@ -703,7 +1009,7 @@ H5X_alacrity_remove(hid_t UNUSED file_id, hid_t UNUSED dataset_id, *------------------------------------------------------------------------- */ static void * -H5X_alacrity_open(hid_t file_id, hid_t UNUSED dataset_id, hid_t xapl_id, +H5X_alacrity_open(hid_t file_id, hid_t dataset_id, hid_t xapl_id, size_t metadata_size, void *metadata) { H5X_alacrity_t *alacrity = NULL; @@ -723,22 +1029,17 @@ H5X_alacrity_open(hid_t file_id, hid_t UNUSED dataset_id, hid_t xapl_id, if (FAIL == H5Pget_xapl_read_context(xapl_id, &rcxt_id)) HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get rc_id from xapl"); - if (NULL == (alacrity = (H5X_alacrity_t *) H5MM_malloc(sizeof(H5X_alacrity_t)))) - HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, NULL, "can't allocate alacrity struct"); - alacrity->metadata_read = FALSE; + /* Initialize ALACRITY plugin */ + if (NULL == (alacrity = H5X__alacrity_init(dataset_id))) + HGOTO_ERROR(H5E_INDEX, H5E_CANTSET, NULL, "can't initialize ALACRITY"); - /* Create an opaque type to handle ALACRITY data */ - if (FAIL == (alacrity->opaque_type_id = H5Tcreate(H5T_OPAQUE, 1))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCREATE, NULL, "can't create type"); - if (FAIL == H5Tset_tag(alacrity->opaque_type_id, "alacrity metadata type")) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, NULL, "can't set tag to type"); - - /* Create transaction from version */ + /* Create transaction from version (for open_by_token) */ if (FAIL == H5RCget_version(rcxt_id, &c_version)) HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, NULL, "can't get version from read context ID"); if (FAIL == (trans_id = H5TRcreate(file_id, rcxt_id, c_version))) HGOTO_ERROR(H5E_INDEX, H5E_CANTCREATE, NULL, "can't create transaction"); + /* Deserialize plugin metadata */ if (FAIL == H5X__alacrity_deserialize_metadata(alacrity, metadata, trans_id)) HGOTO_ERROR(H5E_INDEX, H5E_CANTDECODE, NULL, "can't deserialize plugin metadata"); @@ -747,6 +1048,8 @@ H5X_alacrity_open(hid_t file_id, hid_t UNUSED dataset_id, hid_t xapl_id, done: if (FAIL != trans_id) H5TRclose(trans_id); + if (NULL == ret_value) + H5X__alacrity_term(alacrity); H5X_ALACRITY_LOG_DEBUG("Leave"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5X_alacrity_open() */ @@ -772,18 +1075,8 @@ H5X_alacrity_close(void *idx_handle) if (NULL == alacrity) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL index handle"); -// ALPartitionDataDestroy(&alacrity->output); - - /* Close anonymous dataset */ - if (FAIL == H5Dclose_ff(alacrity->metadata_id, H5_EVENT_STACK_NULL)) - HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close anonymous dataset for index"); - if (FAIL == H5Dclose_ff(alacrity->index_id, H5_EVENT_STACK_NULL)) - HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close anonymous dataset for index"); - - if ((FAIL != alacrity->opaque_type_id) && (FAIL == H5Tclose(alacrity->opaque_type_id))) - HGOTO_ERROR(H5E_INDEX, H5E_CANTCLOSEOBJ, FAIL, "can't close opaque type"); - - H5MM_free(alacrity); + if (FAIL == H5X__alacrity_term(alacrity)) + HGOTO_ERROR(H5E_INDEX, H5E_CANTFREE, FAIL, "Cannot terminate ALACRITY"); done: H5X_ALACRITY_LOG_DEBUG("Leave"); @@ -860,11 +1153,9 @@ H5X_alacrity_query(void *idx_handle, hid_t query_id, hid_t xxpl_id, hid_t *dataspace_id) { H5X_alacrity_t *alacrity = (H5X_alacrity_t *) idx_handle; - bin_id_t start_bin = 0, end_bin = 0; - value_types_t query_lb, query_ub; hid_t rcxt_id; - bool found_bin; - hid_t ret_space_id = FAIL; + hid_t space_id = FAIL, ret_space_id = FAIL; + H5X_alacrity_range_t query_range; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -878,100 +1169,33 @@ H5X_alacrity_query(void *idx_handle, hid_t query_id, hid_t xxpl_id, HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get rcxt_id from xxpl"); /* If metadata has not been read already, read it */ - if (!alacrity->metadata_read) { - memstream_t memstream; /* Alacrity Memstream */ - hid_t metadata_space_id = FAIL; - void *buf; - size_t buf_size; - - if (FAIL == (metadata_space_id = H5Dget_space(alacrity->metadata_id))) - HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get dataspace from index"); - if (0 == (buf_size = (size_t) H5Sget_select_npoints(metadata_space_id))) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements"); - - /* allocate buffer to hold data */ - if (NULL == (buf = H5MM_malloc(buf_size))) - HGOTO_ERROR(H5E_INDEX, H5E_NOSPACE, FAIL, "can't allocate read buffer"); - - /* read metadata */ - if (FAIL == H5Dread_ff(alacrity->metadata_id, alacrity->opaque_type_id, - H5S_ALL, metadata_space_id, H5P_DEFAULT, buf, rcxt_id, - H5_EVENT_STACK_NULL)) - HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read data"); - - memstreamInit(&memstream, buf); - if (ALErrorNone != ALDeserializeMetadata(&alacrity->metadata, &memstream)) - HGOTO_ERROR(H5E_INDEX, H5E_CANTDECODE, FAIL, "can't deserialize metadata"); - memstreamDestroy(&memstream, 0); - H5MM_free(buf); - H5Sclose(metadata_space_id); - - /* Set this to TRUE so we don't read metadata again */ - alacrity->metadata_read = TRUE; - } - - /* Get range value from query */ - if (FAIL == H5X__alacrity_get_query_range(query_id, &query_lb, &query_ub)) + if (!alacrity->metadata && (FAIL == H5X__alacrity_read_metadata(alacrity, rcxt_id))) + HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read ALACRITY metadata"); + + /* Create a copy of the original dataspace */ + if (FAIL == (space_id = H5Dget_space(alacrity->dataset_id))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get dataspace from dataset"); + if (FAIL == (ret_space_id = H5Scopy(space_id))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy dataspace"); + if (FAIL == H5Sselect_none(ret_space_id)) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't reset selection"); + + /* Get range values from query */ + if (FAIL == H5X__alacrity_get_query_ranges(query_id, &query_range, NULL)) + HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get query ranges"); + + /* Query range */ + if (FAIL == H5X__alacrity_query_range(alacrity, ret_space_id, query_range, + rcxt_id)) HGOTO_ERROR(H5E_INDEX, H5E_CANTGET, FAIL, "can't get query range"); - /** - * First, find which bins are touched by the query (all elements in the - * query range will fall into these bins, however not all elements in these - * bins fall into the query range). - */ - found_bin = H5X__alacrity_find_bin_range(&alacrity->metadata, query_lb, - query_ub, &start_bin, &end_bin); - - /* If bins were found, read index and create dataspace */ - if (found_bin) { - ALIndex al_index = NULL; - rid_t *al_index_rids = NULL; - size_t al_index_size; - hsize_t dims; - hsize_t start_coord, end_coord, nelmts; - unsigned int i; - - if (FAIL == H5X__alacrity_read_index(alacrity, start_bin, end_bin, - rcxt_id, &al_index, &al_index_size)) - HGOTO_ERROR(H5E_INDEX, H5E_READERROR, FAIL, "can't read index"); - al_index_rids = (rid_t *) al_index; - -#ifdef H5X_ALACRITY_DEBUG - /* TODO debug */ - printf(" # %s(): Index read contains following rIDs: ", __func__); - for (i = 0; i < al_index_size / (sizeof(rid_t)); i++) { - printf("%d ", al_index_rids[i]); - } - printf("\n"); -#endif - - /* If element satisfies query, add it to the selection */ - dims = al_index_size / (sizeof(rid_t)); - if (FAIL == (ret_space_id = H5Screate_simple(1, &dims, NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to create dataspace"); - - for (i = 0; i < al_index_size / (sizeof(rid_t)); i++) { - const hsize_t point = al_index_rids[i]; - if (H5Sselect_elements(ret_space_id, H5S_SELECT_APPEND, 1, &point)) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to add point to selection"); - } - - if (FAIL == H5Sget_select_bounds(ret_space_id, &start_coord, &end_coord)) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to get bounds"); - if (0 == (nelmts = (hsize_t) H5Sget_select_npoints(ret_space_id))) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "invalid number of elements"); - H5X_ALACRITY_LOG_DEBUG("Created dataspace from index with %llu elements [%llu:%llu]", - nelmts, start_coord, end_coord); - - H5MM_free(al_index); - } else { - if (FAIL == (ret_space_id = H5Screate(H5S_NULL))) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to create NULL dataspace"); - } - *dataspace_id = ret_space_id; done: + if (FAIL != space_id) + H5Sclose(space_id); + if ((FAIL == ret_value) && (FAIL != ret_space_id)) + H5Sclose(ret_space_id); H5X_ALACRITY_LOG_DEBUG("Leave"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5X_alacrity_query() */ |