summaryrefslogtreecommitdiffstats
path: root/src/H5Xalacrity.c
diff options
context:
space:
mode:
authorJerome Soumagne <jsoumagne@hdfgroup.org>2014-06-11 22:25:52 (GMT)
committerJerome Soumagne <jsoumagne@hdfgroup.org>2014-06-11 22:25:52 (GMT)
commit058eba7f5ba66817f1a544117c463f4f1200a8fb (patch)
treefd2460afaf956605a8713dbd0b1c86717587d476 /src/H5Xalacrity.c
parenta0aa11c0b2ba024e69e3d8ff5185057acd49df3a (diff)
downloadhdf5-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.c582
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() */