summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2011-10-18 21:27:58 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2011-10-18 21:27:58 (GMT)
commit395c1c7db532897452716615889ad882c4ee935a (patch)
tree1625604f48f8d78b13efe29909fd1eff801fb766
parentaca9bf5cf3039fa0179067c1ee8877870350e819 (diff)
downloadhdf5-395c1c7db532897452716615889ad882c4ee935a.zip
hdf5-395c1c7db532897452716615889ad882c4ee935a.tar.gz
hdf5-395c1c7db532897452716615889ad882c4ee935a.tar.bz2
[svn-r21603] Purpose: Add generic skip list implementation
Description: Added new H5SL_TYPE_GENERIC skip list type, which uses void *'s as keys and a client-supplied callback for key comparison. This was added to support the upcoming "merge named datatype" feature for H5Ocopy, but may be used in other places as well. Also added testing. Also fixed a potential bug with the H5SL_TYPE_OBJ implementation, and added testing for that. Tested: jam, koala, heiwa (h5committest), durandal
-rw-r--r--src/H5AC.c6
-rw-r--r--src/H5C.c4
-rw-r--r--src/H5Dchunk.c2
-rw-r--r--src/H5FO.c4
-rw-r--r--src/H5FSsection.c8
-rw-r--r--src/H5Fefc.c2
-rw-r--r--src/H5G.c2
-rw-r--r--src/H5O.c2
-rw-r--r--src/H5Ocopy.c2
-rw-r--r--src/H5Opkg.h2
-rw-r--r--src/H5Pint.c18
-rw-r--r--src/H5SL.c88
-rw-r--r--src/H5SLprivate.h8
-rw-r--r--test/tskiplist.c284
-rw-r--r--tools/lib/h5tools_ref.c2
15 files changed, 311 insertions, 123 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index 2b78c84..ff22b8e 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -536,10 +536,10 @@ H5AC_create(const H5F_t *f,
sprintf(prefix, "%d:", mpi_rank);
if(mpi_rank == 0) {
- if(NULL == (aux_ptr->d_slist_ptr = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (aux_ptr->d_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create dirtied entry list.")
- if(NULL == (aux_ptr->c_slist_ptr = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (aux_ptr->c_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create cleaned entry list.")
} /* end if */
@@ -547,7 +547,7 @@ H5AC_create(const H5F_t *f,
* when the distributed strategy is selected as all processes
* will use it in the case of a flush.
*/
- if(NULL == (aux_ptr->candidate_slist_ptr = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (aux_ptr->candidate_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create candidate entry list.")
} /* end if */
diff --git a/src/H5C.c b/src/H5C.c
index 5a4f5e9..04e7b9e 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -1013,7 +1013,7 @@ H5C_create(size_t max_cache_size,
"memory allocation failed")
}
- if ( (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR)) == NULL ) {
+ if ( (cache_ptr->slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.")
}
@@ -5058,7 +5058,7 @@ H5C_dump_cache(H5C_t * cache_ptr,
HDassert(cache_name != NULL );
/* First, create a skip list */
- slist_ptr = H5SL_create(H5SL_TYPE_HADDR);
+ slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL);
if ( slist_ptr == NULL ) {
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 0026183..092e1b5 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -691,7 +691,7 @@ H5D_chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info
else {
/* Initialize skip list for chunk selections */
if(NULL == dataset->shared->cache.chunk.sel_chunks) {
- if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE)))
+ if(NULL == (dataset->shared->cache.chunk.sel_chunks = H5SL_create(H5SL_TYPE_HSIZE, NULL)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create skip list for chunk selections")
} /* end if */
fm->sel_chunks = dataset->shared->cache.chunk.sel_chunks;
diff --git a/src/H5FO.c b/src/H5FO.c
index 8e1b98c..cae3d6d 100644
--- a/src/H5FO.c
+++ b/src/H5FO.c
@@ -82,7 +82,7 @@ H5FO_create(const H5F_t *f)
assert(f->shared);
/* Create container used to store open object info */
- if((f->shared->open_objs = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
+ if((f->shared->open_objs = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
done:
@@ -400,7 +400,7 @@ H5FO_top_create(H5F_t *f)
HDassert(f);
/* Create container used to store open object info */
- if((f->obj_count = H5SL_create(H5SL_TYPE_HADDR)) == NULL)
+ if((f->obj_count = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
done:
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index 9fb34df..7d18003 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -967,7 +967,7 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a\n", FUNC, sect->size, s
bin = H5V_log2_gen(sect->size);
HDassert(bin < sinfo->nbins);
if(sinfo->bins[bin].bin_list == NULL) {
- if(NULL == (sinfo->bins[bin].bin_list = H5SL_create(H5SL_TYPE_HSIZE)))
+ if(NULL == (sinfo->bins[bin].bin_list = H5SL_create(H5SL_TYPE_HSIZE, NULL)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for free space nodes")
} /* end if */
else {
@@ -985,7 +985,7 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a\n", FUNC, sect->size, s
/* Initialize the free list size node */
fspace_node->sect_size = sect->size;
fspace_node->serial_count = fspace_node->ghost_count = 0;
- if(NULL == (fspace_node->sect_list = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (fspace_node->sect_list = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for free space nodes")
/* Insert new free space size node into bin's list */
@@ -1072,7 +1072,7 @@ H5FS_sect_link_rest(H5FS_t *fspace, const H5FS_section_class_t *cls,
HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
if(fspace->sinfo->merge_list == NULL)
- if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
if(H5SL_insert(fspace->sinfo->merge_list, sect, &sect->addr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
@@ -2187,7 +2187,7 @@ HDfprintf(stderr, "%s: to_mergable = %u\n", FUNC, to_mergable);
HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
#endif /* QAK */
if(fspace->sinfo->merge_list == NULL)
- if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR)))
+ if(NULL == (fspace->sinfo->merge_list = H5SL_create(H5SL_TYPE_HADDR, NULL)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
if(H5SL_insert(fspace->sinfo->merge_list, sect, &sect->addr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
diff --git a/src/H5Fefc.c b/src/H5Fefc.c
index a0c204e..1dc7f70 100644
--- a/src/H5Fefc.c
+++ b/src/H5Fefc.c
@@ -184,7 +184,7 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id,
} /* end if */
else {
HDassert(efc->nfiles == 0);
- if(NULL == (efc->slist = H5SL_create(H5SL_TYPE_STR)))
+ if(NULL == (efc->slist = H5SL_create(H5SL_TYPE_STR, NULL)))
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't create skip list")
} /* end else */
diff --git a/src/H5G.c b/src/H5G.c
index 32d3b28..2cbca65 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -1807,7 +1807,7 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type,
udata.curr_path_len = 0;
/* Create skip list to store visited object information */
- if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, NULL)) == NULL)
HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
/* Get the group's reference count */
diff --git a/src/H5O.c b/src/H5O.c
index 5de0dc4..6924882 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -3320,7 +3320,7 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
udata.op_data = op_data;
/* Create skip list to store visited object information */
- if((udata.visited = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
+ if((udata.visited = H5SL_create(H5SL_TYPE_OBJ, NULL)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create skip list for visited objects")
/* If its ref count is > 1, we add it to the list of visited objects */
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 7f121d9..be27167 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -970,7 +970,7 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
cpy_info.preserve_null = TRUE;
/* Create a skip list to keep track of which objects are copied */
- if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ)) == NULL)
+ if((cpy_info.map_list = H5SL_create(H5SL_TYPE_OBJ, NULL)) == NULL)
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 54e7233..b5afe7b 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -333,7 +333,7 @@ typedef struct H5O_addr_map_t {
haddr_t dst_addr; /* Address of object in destination file */
hbool_t is_locked; /* Indicate that the destination object is locked currently */
hsize_t inc_ref_count; /* Number of deferred increments to reference count */
- H5O_obj_class_t *obj_class; /* Object class */
+ const H5O_obj_class_t *obj_class; /* Object class */
void *udata; /* Object class copy file udata */
} H5O_addr_map_t;
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 4ae274e..5a0c54d 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -650,11 +650,11 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref)
new_plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */
/* Initialize the skip list to hold the changed properties */
- if((new_plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((new_plist->props = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for changed properties")
/* Create the skip list for deleted properties */
- if((new_plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((new_plist->del = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for deleted properties")
/* Create the skip list to hold names of properties already seen
@@ -662,7 +662,7 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref)
* 'create' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR))== NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR, NULL))== NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties")
nseen = 0;
@@ -1468,7 +1468,7 @@ H5P_create_class(H5P_genclass_t *par_class, const char *name, hbool_t internal,
pclass->revision = H5P_GET_NEXT_REV; /* Get a revision number for the class */
/* Create the skip list for properties */
- if(NULL == (pclass->props = H5SL_create(H5SL_TYPE_STR)))
+ if(NULL == (pclass->props = H5SL_create(H5SL_TYPE_STR, NULL)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, NULL, "can't create skip list for properties")
/* Set callback functions and pass-along data */
@@ -1558,11 +1558,11 @@ H5P_create(H5P_genclass_t *pclass)
plist->class_init = FALSE; /* Initially, wait until the class callback finishes to set */
/* Create the skip list for changed properties */
- if((plist->props = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((plist->props = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for changed properties")
/* Create the skip list for deleted properties */
- if((plist->del = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((plist->del = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for deleted properties")
/* Create the skip list to hold names of properties already seen
@@ -1570,7 +1570,7 @@ H5P_create(H5P_genclass_t *pclass)
* 'create' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,NULL,"can't create skip list for seen properties")
/*
@@ -3359,7 +3359,7 @@ H5P_iterate_plist(hid_t plist_id, int *idx, H5P_iterate_t iter_func, void *iter_
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Create the skip list to hold names of properties already seen */
- if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties")
/* Walk through the changed properties in the list */
@@ -4316,7 +4316,7 @@ H5P_close(void *_plist)
* 'close' callback called, if a property in the class hierarchy has
* already been seen)
*/
- if((seen = H5SL_create(H5SL_TYPE_STR)) == NULL)
+ if((seen = H5SL_create(H5SL_TYPE_STR, NULL)) == NULL)
HGOTO_ERROR(H5E_PLIST,H5E_CANTCREATE,FAIL,"can't create skip list for seen properties")
nseen = 0;
diff --git a/src/H5SL.c b/src/H5SL.c
index c996392..b34d300 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -82,32 +82,42 @@
/* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+#define H5SL_LOCATE_SCALAR_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
(*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+#define H5SL_LOCATE_STRING_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
(((PNODE)->hashval == HASHVAL) ? \
(HDstrcmp((const char *)(PNODE)->key, (const char *)PKEY) < 0) : \
((PNODE)->hashval < HASHVAL))
/* Define a code template for comparing H5_obj_t keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_OBJ_CMP(TYPE, PNODE, PKEY, HASHVAL) \
- ((((TYPE *)((PNODE)->key))->fileno < ((TYPE *)PKEY)->fileno) ? TRUE : (((TYPE *)((PNODE)->key))->addr < ((TYPE *)PKEY)->addr))
+#define H5SL_LOCATE_OBJ_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
+ ((((TYPE *)((PNODE)->key))->fileno == ((TYPE *)PKEY)->fileno) \
+ ? (((TYPE *)((PNODE)->key))->addr < ((TYPE *)PKEY)->addr) \
+ : (((TYPE *)((PNODE)->key))->fileno < ((TYPE *)PKEY)->fileno))
+
+/* Define a code template for comparing generic keys for the "CMP" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_GENERIC_CMP(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
+ ((SLIST)->cmp((TYPE *)((PNODE)->key), (TYPE *)PKEY) < 0)
/* Define a code template for comparing scalar keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+#define H5SL_LOCATE_SCALAR_EQ(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
(*(TYPE *)((PNODE)->key) == *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+#define H5SL_LOCATE_STRING_EQ(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
(((PNODE)->hashval == HASHVAL) && (HDstrcmp((const char *)(PNODE)->key, (const char *)PKEY) == 0))
/* Define a code template for comparing H5_obj_t keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_OBJ_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+#define H5SL_LOCATE_OBJ_EQ(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
((((TYPE *)((PNODE)->key))->fileno == ((TYPE *)PKEY)->fileno) && (((TYPE *)((PNODE)->key))->addr == ((TYPE *)PKEY)->addr))
+/* Define a code template for comparing generic keys for the "EQ" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_GENERIC_EQ(SLIST, TYPE, PNODE, PKEY, HASHVAL) \
+ ((SLIST)->cmp((TYPE *)((PNODE)->key), (TYPE *)PKEY) == 0)
+
/* Define a code template for initializing the hash value for scalar keys for the "HASHINIT" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_SCALAR_HASHINIT(KEY, HASHVAL)
@@ -119,6 +129,9 @@
/* Define a code template for initializing the hash value for H5_obj_t keys for the "HASHINIT" in the H5SL_LOCATE macro */
#define H5SL_LOCATE_OBJ_HASHINIT(KEY, HASHVAL)
+/* Define a code template for initializing the hash value for generic keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_GENERIC_HASHINIT(KEY, HASHVAL)
+
/* Macro used to find node for operation */
#define H5SL_LOCATE(OP, CMP, SLIST, X, TYPE, KEY, HASHVAL) \
@@ -130,15 +143,15 @@
for(_i = (int)SLIST->curr_level; _i >= 0; _i--) { \
_count = 0; \
while(_count < 3 && X->forward[_i] && \
- H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL) ) { \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL) ) { \
X = X->forward[_i]; \
_count++; \
} /* end while */ \
} /* end for */ \
X = X->forward[0]; \
- if(X != NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, X, KEY, HASHVAL) ) { \
+ if(X != NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(SLIST, TYPE, X, KEY, HASHVAL) ) { \
/* What to do when a node is found */ \
- H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, _i) \
+ H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, _i) \
} /* end if */ \
}
@@ -266,7 +279,7 @@
} /* end if */ \
\
/* Check if this node is the start of the next gap */ \
- if(!_drop && !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL)) \
+ if(!_drop && !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) \
_drop = X; \
\
/* No need to check the last node in the gap if there are 3, as */ \
@@ -280,7 +293,7 @@
X = X->forward[_i]; \
} /* end for */ \
HDassert(!_drop->forward[_i] || \
- !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, _drop->forward[_i], KEY, HASHVAL)); \
+ !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \
\
/* Promote the middle node if necessary */ \
if(_count == 3) { \
@@ -293,7 +306,7 @@
_next = _drop->forward[_i]; \
} /* end for */ \
\
- if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, _next, KEY, HASHVAL)) \
+ if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) \
HGOTO_ERROR(H5E_SLIST, H5E_CANTINSERT, NULL, "can't insert duplicate key") \
}
@@ -316,7 +329,7 @@
H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
\
/* Find the gap to drop in to at the highest level */ \
- while(X && (!X->key || H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X, KEY, HASHVAL))) { \
+ while(X && (!X->key || H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, X, KEY, HASHVAL))) { \
_llast = _last; \
_last = X; \
X = X->forward[_i]; \
@@ -347,7 +360,7 @@
break; \
} else { /* !_drop */ \
/* Check if this node is the start of the next gap */ \
- if (!H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL)) { \
+ if (!H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, X->forward[_i], KEY, HASHVAL)) { \
_drop = X; \
/* Again check if we can stop searching */ \
if(_count) { \
@@ -370,7 +383,7 @@
} /* end for */ \
HDassert(_count >= 1 && _count <= 3); \
HDassert(!_drop->forward[_i] || \
- !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, _drop->forward[_i], KEY, HASHVAL)); \
+ !H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(SLIST, TYPE, _drop->forward[_i], KEY, HASHVAL)); \
\
/* Check if we need to adjust node heights */ \
if(_count == 1) { \
@@ -431,7 +444,7 @@
} /* end for */ \
\
/* Check if we've found the node */ \
- if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, _next, KEY, HASHVAL)) { \
+ if(_next && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(SLIST, TYPE, _next, KEY, HASHVAL)) { \
void *tmp = _next->item; \
X = _next; \
\
@@ -485,6 +498,7 @@ struct H5SL_node_t {
struct H5SL_t {
/* Static values for each list */
H5SL_type_t type; /* Type of skip list */
+ H5SL_cmp_t cmp; /* Comparison callback, if type is H5SL_TYPE_GENERIC */
/* Dynamic values for each list */
int curr_level; /* Current top level used in list */
@@ -667,6 +681,10 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
H5SL_INSERT(OBJ, slist, prev, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_INSERT(GENERIC, slist, prev, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -834,7 +852,7 @@ done:
PURPOSE
Create a skip list
USAGE
- H5SL_t *H5SL_create(H5SL_type_t type)
+ H5SL_t *H5SL_create(H5SL_type_t type, H5SL_cmp_t cmp)
RETURNS
Returns a pointer to a skip list on success, NULL on failure.
@@ -846,7 +864,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
H5SL_t *
-H5SL_create(H5SL_type_t type)
+H5SL_create(H5SL_type_t type, H5SL_cmp_t cmp)
{
H5SL_t *new_slist = NULL; /* Pointer to new skip list object created */
H5SL_node_t *header; /* Pointer to skip list header node */
@@ -855,7 +873,7 @@ H5SL_create(H5SL_type_t type)
FUNC_ENTER_NOAPI(H5SL_create,NULL);
/* Check args */
- HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_OBJ);
+ HDassert(type>=H5SL_TYPE_INT && type<=H5SL_TYPE_GENERIC);
/* Allocate skip list structure */
if(NULL == (new_slist = H5FL_MALLOC(H5SL_t)))
@@ -863,6 +881,8 @@ H5SL_create(H5SL_type_t type)
/* Set the static internal fields */
new_slist->type = type;
+ HDassert((type == H5SL_TYPE_GENERIC) == !!cmp);
+ new_slist->cmp = cmp;
/* Set the dynamic internal fields */
new_slist->curr_level = -1;
@@ -1090,6 +1110,10 @@ H5SL_remove(H5SL_t *slist, const void *key)
H5SL_REMOVE(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_REMOVE(GENERIC, slist, x, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -1269,6 +1293,10 @@ H5SL_search(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -1354,6 +1382,10 @@ H5SL_less(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -1452,6 +1484,10 @@ H5SL_greater(H5SL_t *slist, const void *key)
H5SL_SEARCH(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_SEARCH(GENERIC, slist, x, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -1540,6 +1576,10 @@ H5SL_find(H5SL_t *slist, const void *key)
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+ case H5SL_TYPE_GENERIC:
+ H5SL_FIND(GENERIC, slist, x, const void, key, -)
+ break;
+
default:
HDassert(0 && "Unknown skiplist type!");
} /* end switch */
@@ -1624,6 +1664,10 @@ H5SL_below(H5SL_t *slist, const void *key)
case H5SL_TYPE_OBJ:
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ case H5SL_TYPE_GENERIC:
+ H5SL_FIND(GENERIC, slist, x, const void, key, -)
+ break;
} /* end switch */
/* An exact match for 'key' must not have been found in list, if we get here */
@@ -1719,6 +1763,10 @@ H5SL_above(H5SL_t *slist, const void *key)
case H5SL_TYPE_OBJ:
H5SL_FIND(OBJ, slist, x, const H5_obj_t, key, -)
break;
+
+ case H5SL_TYPE_GENERIC:
+ H5SL_FIND(GENERIC, slist, x, const void, key, -)
+ break;
} /* end switch */
/* An exact match for 'key' must not have been found in list, if we get here */
diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h
index 40fbfa9..07ee414 100644
--- a/src/H5SLprivate.h
+++ b/src/H5SLprivate.h
@@ -47,13 +47,17 @@ typedef enum {
H5SL_TYPE_HSIZE, /* Skip list keys are 'hsize_t's */
H5SL_TYPE_UNSIGNED, /* Skip list keys are 'unsigned's */
H5SL_TYPE_SIZE, /* Skip list keys are 'size_t's */
- H5SL_TYPE_OBJ /* Skip list keys are 'H5_obj_t's */
+ H5SL_TYPE_OBJ, /* Skip list keys are 'H5_obj_t's */
+ H5SL_TYPE_GENERIC /* Skip list keys are unknown, comparison callback supplied */
} H5SL_type_t;
/**********/
/* Macros */
/**********/
+/* Typedef for comparison operations */
+typedef int (*H5SL_cmp_t)(const void *key1, const void *key2);
+
/* Typedef for iteration operations */
typedef herr_t (*H5SL_operator_t)(void *item, void *key,
void *operator_data/*in,out*/);
@@ -61,7 +65,7 @@ typedef herr_t (*H5SL_operator_t)(void *item, void *key,
/********************/
/* Private routines */
/********************/
-H5_DLL H5SL_t *H5SL_create(H5SL_type_t type);
+H5_DLL H5SL_t *H5SL_create(H5SL_type_t type, H5SL_cmp_t cmp);
H5_DLL size_t H5SL_count(H5SL_t *slist);
H5_DLL herr_t H5SL_insert(H5SL_t *slist, void *item, const void *key);
H5_DLL H5SL_node_t *H5SL_add(H5SL_t *slist, void *item, const void *key);
diff --git a/test/tskiplist.c b/test/tskiplist.c
index 8510db2..8966e39 100644
--- a/test/tskiplist.c
+++ b/test/tskiplist.c
@@ -121,7 +121,7 @@ test_skiplist_create(void)
MESSAGE(6, ("Testing Creating & Closing Skip Lists\n"));
/* Try creating a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Try closing the skip list */
@@ -151,7 +151,7 @@ test_skiplist_insert(void)
MESSAGE(7, ("Testing Insertion Into Skip List\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -160,7 +160,7 @@ test_skiplist_insert(void)
/* Try searching for item in empty skip list */
key=37;
- found_item=H5SL_search(slist,&key);
+ found_item=(int *)H5SL_search(slist,&key);
VERIFY(found_item, NULL, "H5SL_search");
/* Insert an object into the skip list */
@@ -173,13 +173,13 @@ test_skiplist_insert(void)
VERIFY(num, 1, "H5SL_count");
/* Search for the item just inserted */
- found_item=H5SL_search(slist,&key);
+ found_item=(int *)H5SL_search(slist,&key);
CHECK(found_item, NULL, "H5SL_search");
VERIFY(*found_item,item,"H5SL_search");
/* Search for an item not in list */
search_key=37;
- found_item=H5SL_search(slist,&search_key);
+ found_item=(int *)H5SL_search(slist,&search_key);
VERIFY(found_item, NULL, "H5SL_search");
/* Attempt to insert duplicate key (should fail) */
@@ -212,7 +212,7 @@ test_skiplist_insert_many(void)
MESSAGE(7, ("Testing Insertion of Many Items Into Skip List\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -231,7 +231,7 @@ test_skiplist_insert_many(void)
/* Search for all objects in the skip list */
for(u=0; u<NUM_ELEMS; u++) {
- found_item=H5SL_search(slist,&rand_num[u]);
+ found_item=(int *)H5SL_search(slist,&rand_num[u]);
CHECK(found_item, NULL, "H5SL_search");
VERIFY(*found_item,rand_num[u],"H5SL_search");
} /* end for */
@@ -286,7 +286,7 @@ test_skiplist_remove(void)
MESSAGE(7, ("Testing Removal From Skip List\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -295,7 +295,7 @@ test_skiplist_remove(void)
/* Try removing an item in empty skip list */
search_key=37;
- found_item=H5SL_remove(slist,&search_key);
+ found_item=(int *)H5SL_remove(slist,&search_key);
VERIFY(found_item, NULL, "H5SL_remove");
/* Insert three objects into the skip list */
@@ -317,17 +317,17 @@ test_skiplist_remove(void)
/* Try removing items from skip list */
search_key=key1;
- found_item=H5SL_remove(slist,&search_key);
+ found_item=(int *)H5SL_remove(slist,&search_key);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(found_item, &key1, "H5SL_remove");
search_key=key2;
- found_item=H5SL_remove(slist,&search_key);
+ found_item=(int *)H5SL_remove(slist,&search_key);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(found_item, &key2, "H5SL_remove");
search_key=key3;
- found_item=H5SL_remove(slist,&search_key);
+ found_item=(int *)H5SL_remove(slist,&search_key);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(found_item, &key3, "H5SL_remove");
@@ -337,7 +337,7 @@ test_skiplist_remove(void)
/* Try removing items from empty skip list (after its been worked on) */
search_key=key1;
- found_item=H5SL_remove(slist,&search_key);
+ found_item=(int *)H5SL_remove(slist,&search_key);
VERIFY(found_item, NULL, "H5SL_remove");
/* Close the skip list */
@@ -365,7 +365,7 @@ test_skiplist_remove_many(void)
MESSAGE(7, ("Testing Removal of Many Items From Skip List\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -384,7 +384,7 @@ test_skiplist_remove_many(void)
/* Remove all objects from the skip list (in random order) */
for(u=0; u<NUM_ELEMS; u++) {
- found_item=H5SL_remove(slist,&rand_num[u]);
+ found_item=(int *)H5SL_remove(slist,&rand_num[u]);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(*found_item,rand_num[u],"H5SL_remove");
} /* end for */
@@ -407,7 +407,7 @@ test_skiplist_remove_many(void)
/* Remove all objects from the skip list */
for(u=0; u<NUM_ELEMS; u++) {
- found_item=H5SL_remove(slist,&sort_rand_num[u]);
+ found_item=(int *)H5SL_remove(slist,&sort_rand_num[u]);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(*found_item,sort_rand_num[u],"H5SL_remove");
} /* end for */
@@ -430,7 +430,7 @@ test_skiplist_remove_many(void)
/* Remove all objects from the skip list */
for(u=0; u<NUM_ELEMS; u++) {
- found_item=H5SL_remove(slist,&rev_sort_rand_num[u]);
+ found_item=(int *)H5SL_remove(slist,&rev_sort_rand_num[u]);
CHECK(found_item, NULL, "H5SL_remove");
VERIFY(*found_item,rev_sort_rand_num[u],"H5SL_remove");
} /* end for */
@@ -465,13 +465,13 @@ test_skiplist_firstnext(void)
MESSAGE(7, ("Testing Iterating Over Skip List With First/Next\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
num=H5SL_count(slist);
- VERIFY(num, 0, "H5SL_count");
+ VERIFY(num, 0, "H5SL_count");
/* Check that the list appears empty */
node=H5SL_first(slist);
VERIFY(node, NULL, "H5SL_first");
@@ -491,7 +491,7 @@ test_skiplist_firstnext(void)
CHECK(node, NULL, "H5SL_first");
u=0;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(int *)H5SL_item(node);
VERIFY(*found_item,sort_rand_num[u],"H5SL_next");
u++;
node=H5SL_next(node);
@@ -558,7 +558,7 @@ test_skiplist_string(void)
MESSAGE(7, ("Testing Skip List With String Keys\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_STR);
+ slist = H5SL_create(H5SL_TYPE_STR, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -579,7 +579,7 @@ test_skiplist_string(void)
node=H5SL_first(slist);
u=0;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(string_node *)H5SL_item(node);
VERIFY(found_item->i, hashed_data[u].i, "H5SL_next");
u++;
node=H5SL_next(node);
@@ -620,7 +620,7 @@ test_skiplist_iterate(void)
MESSAGE(7, ("Testing Iterating Over Skip List\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -670,7 +670,7 @@ test_skiplist_hsize(void)
MESSAGE(7, ("Testing Skip List With hsize_t Keys\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_HSIZE);
+ slist = H5SL_create(H5SL_TYPE_HSIZE, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -691,7 +691,7 @@ test_skiplist_hsize(void)
node=H5SL_first(slist);
u=0;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(hsize_t *)H5SL_item(node);
VERIFY(*found_item,sorted_data[u],"H5SL_next");
u++;
node=H5SL_next(node);
@@ -725,7 +725,7 @@ test_skiplist_unsigned(void)
MESSAGE(7, ("Testing Skip List With unsigned Keys\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -746,7 +746,7 @@ test_skiplist_unsigned(void)
node=H5SL_first(slist);
u=0;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(unsigned *)H5SL_item(node);
VERIFY(*found_item,sorted_data[u],"H5SL_next");
u++;
node=H5SL_next(node);
@@ -760,6 +760,140 @@ test_skiplist_unsigned(void)
/****************************************************************
**
+** test_skiplist_obj(): Test H5SL (skip list) code.
+** Tests using H5_obj_t's for keys in skip lists.
+**
+****************************************************************/
+static void
+test_skiplist_obj(void)
+{
+ H5SL_t *slist; /* Skip list created */
+ H5SL_node_t *node; /* Skip list node */
+ size_t num; /* Number of elements in skip list */
+ size_t u; /* Local index variable */
+ H5_obj_t data[10]={ {10, 12}, {20, 12}, {10, 32}, {10, 11}, {50, 1}, {8, 12}, {31, 12}, {20, 11}, {31, 11}, {8, 32} };
+ H5_obj_t sorted_data[10]={ {8, 12}, {8, 32}, {10, 11}, {10, 12}, {10, 32}, {20, 11}, {20, 12}, {31, 11}, {31, 12}, {50, 1} };
+ H5_obj_t *found_item; /* Item found in skip list */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(7, ("Testing Skip List With H5_obj_t Keys\n"));
+
+ /* Create a skip list */
+ slist = H5SL_create(H5SL_TYPE_OBJ, NULL);
+ CHECK(slist, NULL, "H5SL_create");
+
+ /* Check that the skip list has no elements */
+ num=H5SL_count(slist);
+ VERIFY(num, 0, "H5SL_count");
+
+ /* Insert objects into the skip list */
+ for(u=0; u<10; u++) {
+ ret=H5SL_insert(slist,&data[u],&data[u]);
+ CHECK(ret, FAIL, "H5SL_insert");
+ } /* end for */
+
+ /* Check that the skip list has correct # of elements */
+ num=H5SL_count(slist);
+ VERIFY(num, 10, "H5SL_count");
+
+ /* Iterate over all the nodes in the skip list */
+ node=H5SL_first(slist);
+ u=0;
+ while(node!=NULL) {
+ found_item=(H5_obj_t *)H5SL_item(node);
+ VERIFY(found_item->fileno,sorted_data[u].fileno,"H5SL_next");
+ VERIFY(found_item->addr,sorted_data[u].addr,"H5SL_next");
+ u++;
+ node=H5SL_next(node);
+ } /* end while */
+
+ /* Close the skip list */
+ ret=H5SL_close(slist);
+ CHECK(ret, FAIL, "H5SL_close");
+
+} /* end test_skiplist_obj() */
+
+/****************************************************************
+**
+** test_skiplist_generic(): Test H5SL (skip list) code.
+** Tests using generic keys in skip lists. Define
+** structure for keys, and define comparison using
+** key.a-key.b.
+**
+****************************************************************/
+typedef struct generic_t {
+ unsigned a;
+ unsigned b;
+} generic_t;
+
+static int
+test_skiplist_generic_cmp(const void *_key1, const void *_key2)
+{
+ const generic_t *key1 = (const generic_t *)_key1;
+ const generic_t *key2 = (const generic_t *)_key2;
+ long long result = (long long)(key1->a) - (long long)(key1->b) - (long long)(key2->a) + (long long)(key2->b);
+
+ if(result < 0)
+ return -1;
+ else if(result > 0)
+ return 1;
+ else
+ return 0;
+} /* end test_skiplist_generic_cmp */
+
+static void
+test_skiplist_generic(void)
+{
+ H5SL_t *slist; /* Skip list created */
+ H5SL_node_t *node; /* Skip list node */
+ size_t num; /* Number of elements in skip list */
+ size_t u; /* Local index variable */
+ generic_t data[10]={ {10, 1}, {20, 13}, {15, 32}, {5, 2}, {50, 37}, {30, 100}, {31, 38}, {32, 34}, {80, 32}, {90, 0} };
+ generic_t sorted_data[10]={ {30, 100}, {15, 32}, {31, 38}, {32, 34}, {5, 2}, {20, 13}, {10, 1}, {50, 37}, {80, 32}, {90, 0} };
+ generic_t *found_item; /* Item found in skip list */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(7, ("Testing Skip List With generic Keys\n"));
+
+ /* Create a skip list */
+ slist = H5SL_create(H5SL_TYPE_GENERIC, test_skiplist_generic_cmp);
+ CHECK(slist, NULL, "H5SL_create");
+
+ /* Check that the skip list has no elements */
+ num=H5SL_count(slist);
+ VERIFY(num, 0, "H5SL_count");
+
+ /* Insert objects into the skip list */
+ for(u=0; u<10; u++) {
+ ret=H5SL_insert(slist,&data[u],&data[u]);
+ CHECK(ret, FAIL, "H5SL_insert");
+ } /* end for */
+
+ /* Check that the skip list has correct # of elements */
+ num=H5SL_count(slist);
+ VERIFY(num, 10, "H5SL_count");
+
+ /* Iterate over all the nodes in the skip list */
+ node=H5SL_first(slist);
+ u=0;
+ while(node!=NULL) {
+ found_item=(generic_t *)H5SL_item(node);
+ VERIFY(found_item->a,sorted_data[u].a,"H5SL_next");
+ VERIFY(found_item->b,sorted_data[u].b,"H5SL_next");
+ u++;
+ node=H5SL_next(node);
+ } /* end while */
+
+ /* Close the skip list */
+ ret=H5SL_close(slist);
+ CHECK(ret, FAIL, "H5SL_close");
+
+} /* end test_skiplist_generic() */
+
+/****************************************************************
+**
** test_skiplist_lastprev(): Test H5SL (skip list) code.
** Tests iterating over nodes in skip list with last/prev calls.
**
@@ -778,7 +912,7 @@ test_skiplist_lastprev(void)
MESSAGE(7, ("Testing Iterating Over Skip List With Last/Prev\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Check that the skip list has no elements */
@@ -804,7 +938,7 @@ test_skiplist_lastprev(void)
CHECK(node, NULL, "H5SL_last");
u=NUM_ELEMS-1;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(int *)H5SL_item(node);
VERIFY(*found_item,sort_rand_num[u],"H5SL_prev");
u--;
node=H5SL_prev(node);
@@ -846,7 +980,7 @@ test_skiplist_find(void)
MESSAGE(7, ("Testing Skip List 'Find' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -863,7 +997,7 @@ test_skiplist_find(void)
/* Iterate over the rest of the nodes in the skip list */
u=4;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(unsigned *)H5SL_item(node);
VERIFY(*found_item,sorted_data[u],"H5SL_next");
u++;
node=H5SL_next(node);
@@ -902,7 +1036,7 @@ test_skiplist_add(void)
MESSAGE(7, ("Testing Skip List 'Add' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -923,7 +1057,7 @@ test_skiplist_add(void)
/* Iterate over the rest of the nodes in the skip list */
u=2;
while(node!=NULL) {
- found_item=H5SL_item(node);
+ found_item=(unsigned *)H5SL_item(node);
VERIFY(*found_item,sorted_data[u],"H5SL_item");
u++;
node=H5SL_next(node);
@@ -964,7 +1098,7 @@ test_skiplist_destroy(void)
MESSAGE(7, ("Testing Skip List 'Destroy' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1000,7 +1134,7 @@ test_skiplist_free(void)
MESSAGE(7, ("Testing Skip List 'Free' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1056,7 +1190,7 @@ test_skiplist_less(void)
MESSAGE(7, ("Testing Skip List 'Less' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1067,30 +1201,30 @@ test_skiplist_less(void)
/* Check for exact match of items in various positions */
find_item=20;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,find_item,"H5SL_less");
find_item=90;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,find_item,"H5SL_less");
find_item=5;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,find_item,"H5SL_less");
/* Find item less than a missing key, in various positions */
find_item=19;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,15,"H5SL_less");
find_item=89;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,80,"H5SL_less");
find_item=100;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,90,"H5SL_less");
find_item=9;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(*found_item,5,"H5SL_less");
find_item=4;
- found_item=H5SL_less(slist,&find_item);
+ found_item=(unsigned *)H5SL_less(slist,&find_item);
VERIFY(found_item,NULL,"H5SL_less");
/* Close the skip list */
@@ -1120,7 +1254,7 @@ test_skiplist_greater(void)
MESSAGE(7, ("Testing Skip List 'Greater' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1131,30 +1265,30 @@ test_skiplist_greater(void)
/* Check for exact match of items in various positions */
find_item = 20;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, find_item, "H5SL_greater");
find_item = 90;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, find_item, "H5SL_greater");
find_item = 5;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, find_item, "H5SL_greater");
/* Find item greater than a missing key, in various positions */
find_item = 19;
- found_item = H5SL_greater(slist,&find_item);
+ found_item = (unsigned *)H5SL_greater(slist,&find_item);
VERIFY(*found_item, 20, "H5SL_greater");
find_item = 89;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, 90, "H5SL_greater");
find_item = 100;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(found_item, NULL, "H5SL_greater");
find_item = 6;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, 10, "H5SL_greater");
find_item = 4;
- found_item = H5SL_greater(slist, &find_item);
+ found_item = (unsigned *)H5SL_greater(slist, &find_item);
VERIFY(*found_item, 5, "H5SL_greater");
/* Close the skip list */
@@ -1185,7 +1319,7 @@ test_skiplist_below(void)
MESSAGE(7, ("Testing Skip List 'Below' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1198,42 +1332,42 @@ test_skiplist_below(void)
find_item = 20;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_below");
find_item = 90;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_below");
find_item = 5;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_below");
/* Find item less than a missing key, in various positions */
find_item = 19;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 15, "H5SL_below");
find_item = 89;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 80, "H5SL_below");
find_item = 100;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 90, "H5SL_below");
find_item = 9;
node = H5SL_below(slist, &find_item);
CHECK(node, NULL, "H5SL_below");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 5, "H5SL_below");
find_item = 4;
- node = H5SL_less(slist, &find_item);
+ node = (H5SL_node_t *)H5SL_less(slist, &find_item);
VERIFY(node, NULL, "H5SL_below");
/* Close the skip list */
@@ -1264,7 +1398,7 @@ test_skiplist_above(void)
MESSAGE(7, ("Testing Skip List 'Above' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1277,29 +1411,29 @@ test_skiplist_above(void)
find_item = 20;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_above");
find_item = 90;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_above");
find_item = 5;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, find_item, "H5SL_above");
/* Find item greater than a missing key, in various positions */
find_item = 19;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 20, "H5SL_above");
find_item = 89;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 90, "H5SL_above");
find_item = 100;
node = H5SL_above(slist, &find_item);
@@ -1307,12 +1441,12 @@ test_skiplist_above(void)
find_item = 6;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 10, "H5SL_above");
find_item = 4;
node = H5SL_above(slist, &find_item);
CHECK(node, NULL, "H5SL_above");
- found_item = H5SL_item(node);
+ found_item = (unsigned *)H5SL_item(node);
VERIFY(*found_item, 5, "H5SL_above");
/* Close the skip list */
@@ -1341,7 +1475,7 @@ test_skiplist_remove_first(void)
MESSAGE(7, ("Testing Skip List 'Remove First' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_UNSIGNED);
+ slist = H5SL_create(H5SL_TYPE_UNSIGNED, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1352,12 +1486,12 @@ test_skiplist_remove_first(void)
/* Remove objects from the skip list */
for(u = 0; u < 10; u++) {
- found_item = H5SL_remove_first(slist);
+ found_item = (unsigned *)H5SL_remove_first(slist);
VERIFY(*found_item, sorted_data[u], "H5SL_remove_first");
} /* end for */
/* Check for removing object from empty list */
- found_item = H5SL_remove_first(slist);
+ found_item = (unsigned *)H5SL_remove_first(slist);
VERIFY(found_item, NULL, "H5SL_remove_first");
/* Close the skip list */
@@ -1385,7 +1519,7 @@ test_skiplist_remove_first_many(void)
MESSAGE(7, ("Testing Skip List 'Remove First' Operation\n"));
/* Create a skip list */
- slist = H5SL_create(H5SL_TYPE_INT);
+ slist = H5SL_create(H5SL_TYPE_INT, NULL);
CHECK(slist, NULL, "H5SL_create");
/* Insert objects into the skip list */
@@ -1436,6 +1570,8 @@ test_skiplist(void)
test_skiplist_iterate(); /* Test iteration over skip list nodes with callback */
test_skiplist_hsize(); /* Test skip list hsize_t keys */
test_skiplist_unsigned(); /* Test skip list unsigned keys */
+ test_skiplist_obj(); /* Test skip list H5_obj_t keys */
+ test_skiplist_generic(); /* Test skip list generic keys */
test_skiplist_lastprev(); /* Test iteration over skip list nodes with last/prev */
test_skiplist_find(); /* Test 'find' operation */
test_skiplist_add(); /* Test 'add' operation */
diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c
index 07d2a57..caf71df 100644
--- a/tools/lib/h5tools_ref.c
+++ b/tools/lib/h5tools_ref.c
@@ -114,7 +114,7 @@ init_ref_path_table(void)
HDassert(thefile > 0);
/* Create skip list to store reference path information */
- if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR))==NULL)
+ if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, NULL))==NULL)
return (-1);
/* Iterate over objects in this file */