summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5SL.c61
-rw-r--r--src/H5SLprivate.h7
-rw-r--r--test/tskiplist.c68
3 files changed, 130 insertions, 6 deletions
diff --git a/src/H5SL.c b/src/H5SL.c
index 01a413f..fb406db 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -701,6 +701,67 @@ H5SL_item(H5SL_node_t *slist_node)
/*--------------------------------------------------------------------------
NAME
+ H5SL_iterate
+ PURPOSE
+ Iterate over all nodes in a skip list
+ USAGE
+ herr_t H5SL_iterate(slist, op, op_data)
+ H5SL_t *slist; IN/OUT: Pointer to skip list to iterate over
+ H5SL_operator_t op; IN: Callback function for iteration
+ void *op_data; IN/OUT: Pointer to application data for callback
+
+ RETURNS
+ Returns a negative value if something is wrong, the return
+ value of the last operator if it was non-zero, or zero if all
+ nodes were processed.
+ DESCRIPTION
+ Iterate over all the nodes in a skip list, calling an application callback
+ with the item, key and any operator data.
+
+ The operator callback receives a pointer to the item and key for the list
+ being iterated over ('mesg'), and the pointer to the operator data passed
+ in to H5SL_iterate ('op_data'). The return values from an operator are:
+ A. Zero causes the iterator to continue, returning zero when all
+ nodes of that type have been processed.
+ B. Positive causes the iterator to immediately return that positive
+ value, indicating short-circuit success.
+ C. Negative causes the iterator to immediately return that value,
+ indicating failure.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data)
+{
+ H5SL_node_t *node; /* Pointers to skip list nodes */
+ herr_t ret_value=0; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_iterate);
+
+ /* Check args */
+ assert(slist);
+
+ /* Check internal consistency */
+ /* (Pre-condition) */
+
+ /* Free skip list nodes */
+ node=slist->header->forward[0];
+ while(node!=NULL) {
+ /* Call the iterator callback */
+ if((ret_value=(op)(node->item,node->key,op_data))!=0)
+ break;
+
+ node=node->forward[0];
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5SL_iterate() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5SL_release
PURPOSE
Release all nodes from a skip list
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index f2a4e24..633e3e5 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -50,6 +50,10 @@ typedef enum {
/**********/
#define H5SL_LEVEL_MAX 32 /* (for now) */
+/* Typedef for iteration operations */
+typedef herr_t (*H5SL_operator_t)(void *item, void *key,
+ void *operator_data/*in,out*/);
+
/********************/
/* Private routines */
/********************/
@@ -61,8 +65,9 @@ H5_DLL void *H5SL_search(H5SL_t *slist, void *key);
H5_DLL H5SL_node_t *H5SL_first(H5SL_t *slist);
H5_DLL H5SL_node_t *H5SL_next(H5SL_node_t *slist_node);
H5_DLL void *H5SL_item(H5SL_node_t *slist_node);
+H5_DLL herr_t H5SL_iterate(H5SL_t *slist, H5SL_operator_t op, void *op_data);
H5_DLL herr_t H5SL_release(H5SL_t *slist);
H5_DLL herr_t H5SL_close(H5SL_t *slist);
-#endif /* _H5HPprivate_H */
+#endif /* _H5SLprivate_H */
diff --git a/test/tskiplist.c b/test/tskiplist.c
index 4d29d01..e9d7c48 100644
--- a/test/tskiplist.c
+++ b/test/tskiplist.c
@@ -446,12 +446,12 @@ test_skiplist_remove_many(void)
/****************************************************************
**
-** test_skiplist_iterate(): Test H5SL (skip list) code.
-** Tests iterating over nodes in skip list.
+** test_skiplist_firstnext(): Test H5SL (skip list) code.
+** Tests iterating over nodes in skip list with first/next calls.
**
****************************************************************/
static void
-test_skiplist_iterate(void)
+test_skiplist_firstnext(void)
{
H5SL_t *slist; /* Skip list created */
H5SL_node_t *node; /* Skip list node */
@@ -495,7 +495,7 @@ test_skiplist_iterate(void)
ret=H5SL_close(slist);
CHECK(ret, FAIL, "H5SL_close");
-} /* end test_skiplist_iterate() */
+} /* end test_skiplist_firstnext() */
/****************************************************************
**
@@ -576,6 +576,63 @@ test_skiplist_string(void)
} /* end test_skiplist_string() */
+static herr_t
+test_skiplist_iter(void *item, void UNUSED *key, void *op_data)
+{
+ size_t *up=(size_t *)op_data;
+
+ VERIFY(*(int *)item,sort_rand_num[*up],"H5SL_iterate");
+ (*up)++;
+
+ return(0);
+}
+
+/****************************************************************
+**
+** test_skiplist_iterate(): Test H5SL (skip list) code.
+** Tests iterating over nodes in skip list with callbacks.
+**
+****************************************************************/
+static void
+test_skiplist_iterate(void)
+{
+ H5SL_t *slist; /* Skip list created */
+ ssize_t num; /* Number of elements in skip list */
+ size_t u; /* Local index variable */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(7, ("Testing Iterating Over Skip List\n"));
+
+ /* Create a skip list */
+ slist=H5SL_create(H5SL_TYPE_INT, 0.5, 16);
+ CHECK(slist, NULL, "H5SL_create");
+
+ /* Check that the skip list has no elements */
+ num=H5SL_count(slist);
+ VERIFY(num, 0, "H5SL_count");
+
+ /* Insert many objects into the skip list */
+ for(u=0; u<NUM_ELEMS; u++) {
+ ret=H5SL_insert(slist,&rand_num[u],&rand_num[u]);
+ CHECK(ret, FAIL, "H5SL_insert");
+ } /* end for */
+
+ /* Check that the skip list has correct # of elements */
+ num=H5SL_count(slist);
+ VERIFY(num, NUM_ELEMS, "H5SL_count");
+
+ /* Iterate over all the nodes in the skip list */
+ u=0;
+ ret=H5SL_iterate(slist,test_skiplist_iter,&u);
+ CHECK(ret, FAIL, "H5SL_iterate");
+
+ /* Close the skip list */
+ ret=H5SL_close(slist);
+ CHECK(ret, FAIL, "H5SL_close");
+
+} /* end test_skiplist_firstnext() */
+
/****************************************************************
**
** test_skiplist(): Main H5SL testing routine.
@@ -596,8 +653,9 @@ test_skiplist(void)
test_skiplist_insert_many(); /* Test insertion of many items into skip list */
test_skiplist_remove(); /* Test basic skip list removal */
test_skiplist_remove_many(); /* Test removal of many items from skip list */
- test_skiplist_iterate(); /* Test iteration over skip list nodes */
+ test_skiplist_firstnext(); /* Test iteration over skip list nodes with first/next */
test_skiplist_string(); /* Test skip list string keys */
+ test_skiplist_iterate(); /* Test iteration over skip list nodes with callback */
} /* end test_skiplist() */