summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt9
-rw-r--r--src/H5Spkg.h5
-rw-r--r--src/H5Spoint.c33
3 files changed, 40 insertions, 7 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 24fe4c1..3bd3e01 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -356,6 +356,15 @@ New Features
Library:
--------
+ - Improved performance of H5Sget_select_elem_pointlist
+
+ Modified library to cache the point after the last block of points
+ retrieved by H5Sget_select_elem_pointlist, so a subsequent call to the
+ same function to retrieve the next block of points from the list can
+ proceed immediately without needing to iterate over the point list.
+
+ (NAF - 2021/01/19)
+
- Replaced H5E_ATOM with H5E_ID in H5Epubgen.h
The term "atom" is archaic and not in line with current HDF5 library
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 8b1922b..5fe8795 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -137,6 +137,11 @@ struct H5S_pnt_list_t {
H5S_pnt_node_t *head; /* Pointer to head of point list */
H5S_pnt_node_t *tail; /* Pointer to tail of point list */
+
+ hsize_t last_idx; /* Index of the point after the last returned from H5S__get_select_elem_pointlist() */
+ H5S_pnt_node_t *last_idx_pnt; /* Point after the last returned from H5S__get_select_elem_pointlist().
+ * If we ever add a way to remove points or add points in the middle of
+ * the pointlist we will need to invalidate these fields. */
};
/* Information about hyperslab spans */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index c58e7a7..6cb5d9b 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -843,6 +843,10 @@ H5S__copy_pnt_list(const H5S_pnt_list_t *src, unsigned rank)
H5MM_memcpy(dst->high_bounds, src->high_bounds, (rank * sizeof(hsize_t)));
H5MM_memcpy(dst->low_bounds, src->low_bounds, (rank * sizeof(hsize_t)));
+ /* Clear cached iteration point */
+ dst->last_idx = 0;
+ dst->last_idx_pnt = NULL;
+
/* Set return value */
ret_value = dst;
@@ -1511,6 +1515,7 @@ done:
static herr_t
H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, hsize_t numpoints, hsize_t *buf)
{
+ const hsize_t endpoint = startpoint + numpoints; /* Index of last point in iteration */
H5S_pnt_node_t *node; /* Point node */
unsigned rank; /* Dataspace rank */
@@ -1522,14 +1527,20 @@ H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, hsize_t n
/* Get the dataspace extent rank */
rank = space->extent.rank;
- /* Get the head of the point list */
- node = space->select.sel_info.pnt_lst->head;
+ /* Check for cached point at the correct index */
+ if(space->select.sel_info.pnt_lst->last_idx_pnt
+ && startpoint == space->select.sel_info.pnt_lst->last_idx)
+ node = space->select.sel_info.pnt_lst->last_idx_pnt;
+ else {
+ /* Get the head of the point list */
+ node = space->select.sel_info.pnt_lst->head;
- /* Iterate to the first point to return */
- while (node != NULL && startpoint > 0) {
- startpoint--;
- node = node->next;
- } /* end while */
+ /* Iterate to the first point to return */
+ while (node != NULL && startpoint > 0) {
+ startpoint--;
+ node = node->next;
+ } /* end while */
+ } /* end else */
/* Iterate through the node, copying each point's information */
while (node != NULL && numpoints > 0) {
@@ -1539,6 +1550,10 @@ H5S__get_select_elem_pointlist(const H5S_t *space, hsize_t startpoint, hsize_t n
node = node->next;
} /* end while */
+ /* Cached next point in iteration */
+ space->select.sel_info.pnt_lst->last_idx = endpoint;
+ space->select.sel_info.pnt_lst->last_idx_pnt = node;
+
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S__get_select_elem_pointlist() */
@@ -2331,6 +2346,10 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
} /* end for */
} /* end else */
+ /* Clear cached iteration point */
+ new_space->select.sel_info.pnt_lst->last_idx = 0;
+ new_space->select.sel_info.pnt_lst->last_idx_pnt = NULL;
+
/* Number of elements selected will be the same */
new_space->select.num_elem = base_space->select.num_elem;