Update code
Description:
Move "PABLO_MASK" definition above header file inclusion to avoid problems
with inline functions in header files.
Platforms tested:
FreeBSD 4.8 (sleipnir)
h5committest
802 lines
22 KiB
C
802 lines
22 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Copyright by the Board of Trustees of the University of Illinois. *
|
||
* All rights reserved. *
|
||
* *
|
||
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
||
* terms governing use, modification, and redistribution, is contained in *
|
||
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
||
* of the source code distribution tree; Copyright.html can be found at the *
|
||
* root level of an installed copy of the electronic HDF5 document set and *
|
||
* is linked from the top-level documents page. It can also be found at *
|
||
* http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
|
||
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
|
||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
||
/* TERNARY SEARCH TREE ALGS
|
||
This code is described in "Ternary Search Trees" by Jon
|
||
Bentley and Robert Sedgewick in the April, 1998, Dr. Dobb's Journal.
|
||
*/
|
||
|
||
/* Pablo information */
|
||
/* (Put before include files to avoid problems with inline functions) */
|
||
#define PABLO_MASK H5ST_mask
|
||
|
||
#include "H5Eprivate.h" /* Error handling */
|
||
#include "H5FLprivate.h" /* Free lists */
|
||
#include "H5STprivate.h" /* Ternary search trees */
|
||
|
||
/* Interface initialization */
|
||
static int interface_initialize_g = 0;
|
||
#define INTERFACE_INIT NULL
|
||
|
||
/* Declare a free list to manage the H5ST_node_t struct */
|
||
H5FL_DEFINE_STATIC(H5ST_node_t);
|
||
|
||
/* Declare a free list to manage the H5ST_tree_t struct */
|
||
H5FL_DEFINE_STATIC(H5ST_tree_t);
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_create
|
||
PURPOSE
|
||
Create a TST
|
||
USAGE
|
||
H5ST_ptr_t H5ST_create()
|
||
|
||
RETURNS
|
||
Returns a pointer to the new TST tree on success, NULL on failure.
|
||
DESCRIPTION
|
||
Create a TST.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
H5ST_tree_t *
|
||
H5ST_create(void)
|
||
{
|
||
H5ST_tree_t *ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_create,NULL);
|
||
|
||
/* Allocate wrapper for TST */
|
||
if((ret_value=H5FL_MALLOC(H5ST_tree_t))==NULL)
|
||
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed");
|
||
|
||
/* Set the internal fields */
|
||
ret_value->root=NULL;
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_create() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_close_internal
|
||
PURPOSE
|
||
Close a TST, deallocating it.
|
||
USAGE
|
||
herr_t H5ST_close(p)
|
||
H5ST_ptr_t p; IN/OUT: Root of TST to free
|
||
|
||
RETURNS
|
||
Returns non-negative on success, negative on failure.
|
||
DESCRIPTION
|
||
Close a TST, freeing all nodes.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
static herr_t
|
||
H5ST_close_internal(H5ST_ptr_t p)
|
||
{
|
||
FUNC_ENTER_NOINIT(H5ST_close_internal);
|
||
|
||
/* Recursively free TST */
|
||
if(p) {
|
||
H5ST_close_internal(p->lokid);
|
||
if (p->splitchar)
|
||
H5ST_close_internal(p->eqkid);
|
||
H5ST_close_internal(p->hikid);
|
||
H5FL_FREE(H5ST_node_t,p);
|
||
} /* end if */
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||
} /* end H5ST_close_internal() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_close
|
||
PURPOSE
|
||
Close a TST, deallocating it.
|
||
USAGE
|
||
herr_t H5ST_close(tree)
|
||
H5ST_tree_t *tree; IN/OUT: TST tree to free
|
||
|
||
RETURNS
|
||
Returns non-negative on success, negative on failure.
|
||
DESCRIPTION
|
||
Close a TST, freeing all nodes.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
herr_t
|
||
H5ST_close(H5ST_tree_t *tree)
|
||
{
|
||
herr_t ret_value=SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_close,FAIL);
|
||
|
||
/* Check arguments */
|
||
if(tree==NULL)
|
||
HGOTO_ERROR(H5E_ARGS,H5E_BADVALUE,FAIL,"invalid TST");
|
||
|
||
/* Free the TST itself */
|
||
if(H5ST_close_internal(tree->root)<0)
|
||
HGOTO_ERROR(H5E_TST,H5E_CANTFREE,FAIL,"can't free TST");
|
||
|
||
/* Free root node itself */
|
||
H5FL_FREE(H5ST_tree_t,tree);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_close() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_insert
|
||
PURPOSE
|
||
Insert a string/object pair into a TST
|
||
USAGE
|
||
herr_t H5ST_insert(tree,s,obj)
|
||
H5ST_tree_t *tree; IN/OUT: TST to insert string into
|
||
const char *s; IN: String to use as key for object
|
||
void *obj; IN: Pointer to object to insert
|
||
|
||
RETURNS
|
||
Returns non-negative on success, negative on failure.
|
||
DESCRIPTION
|
||
Insert a key (string)/object pair into a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
herr_t
|
||
H5ST_insert(H5ST_tree_t *tree, const char *s, void *obj)
|
||
{
|
||
int d; /* Comparison value */
|
||
H5ST_ptr_t pp, *p; /* Pointer to current node and pointer to that */
|
||
H5ST_ptr_t parent=NULL; /* Pointer to parent node */
|
||
H5ST_ptr_t up=NULL; /* Pointer to up node */
|
||
herr_t ret_value=SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_insert,FAIL);
|
||
|
||
/* Find the correct location to insert object */
|
||
p = &tree->root;
|
||
while((pp = *p)) {
|
||
/* If this node matches the character in the key, then drop down to the lower tree */
|
||
if ((d = *s - pp->splitchar) == 0) {
|
||
if (*s++ == 0)
|
||
HGOTO_ERROR(H5E_TST,H5E_EXISTS,FAIL,"key already in tree");
|
||
up=pp;
|
||
p = &(pp->eqkid);
|
||
} /* end if */
|
||
else {
|
||
/* Walk through the current tree, searching for the matching character */
|
||
parent=pp;
|
||
if (d < 0)
|
||
p = &(pp->lokid);
|
||
else
|
||
p = &(pp->hikid);
|
||
} /* end else */
|
||
} /* end while */
|
||
|
||
/* Finish walking through the key string, adding nodes until the end */
|
||
for (;;) {
|
||
if((*p = H5FL_MALLOC(H5ST_node_t))==NULL)
|
||
HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed");
|
||
pp = *p;
|
||
pp->splitchar = *s;
|
||
pp->up = up;
|
||
pp->parent = parent;
|
||
pp->lokid = pp->eqkid = pp->hikid = NULL;
|
||
|
||
/* If this is the end of the key string, break out */
|
||
if (*s++ == 0) {
|
||
pp->eqkid = (H5ST_ptr_t) obj;
|
||
break;
|
||
} /* end if */
|
||
|
||
/* Continue to next character */
|
||
parent=NULL;
|
||
up=pp;
|
||
p = &(pp->eqkid);
|
||
} /* end for */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_insert() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_search
|
||
PURPOSE
|
||
Determine if a key is in the TST
|
||
USAGE
|
||
hbool_t H5ST_search(tree,s)
|
||
H5ST_tree_t *tree; IN: TST to find string in
|
||
const char *s; IN: String to use as key to locate
|
||
|
||
RETURNS
|
||
Success: TRUE if key string in TST, FALSE if not
|
||
Failure: negative
|
||
DESCRIPTION
|
||
Locate a key (string) in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
htri_t
|
||
H5ST_search(H5ST_tree_t *tree, const char *s)
|
||
{
|
||
H5ST_ptr_t p; /* Temporary pointer to TST node */
|
||
htri_t ret_value=FALSE; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_search,FAIL);
|
||
|
||
p = tree->root;
|
||
while (p) {
|
||
if (*s < p->splitchar)
|
||
p = p->lokid;
|
||
else if (*s == p->splitchar) {
|
||
if (*s++ == 0)
|
||
HGOTO_DONE(TRUE);
|
||
p = p->eqkid;
|
||
} else
|
||
p = p->hikid;
|
||
} /* end while */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_search() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_find_internal
|
||
PURPOSE
|
||
Find the node matching a particular key string
|
||
USAGE
|
||
H5ST_ptr_t H5ST_find(p,s)
|
||
H5ST_ptr_t p; IN: TST to find string in
|
||
const char *s; IN: String to use as key to locate
|
||
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Locate a key (string) in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
static H5ST_ptr_t
|
||
H5ST_find_internal(H5ST_ptr_t p, const char *s)
|
||
{
|
||
H5ST_ptr_t ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOINIT(H5ST_find_internal);
|
||
|
||
while (p) {
|
||
if (*s < p->splitchar)
|
||
p = p->lokid;
|
||
else if (*s == p->splitchar) {
|
||
if (*s++ == 0)
|
||
HGOTO_DONE(p);
|
||
p = p->eqkid;
|
||
} else
|
||
p = p->hikid;
|
||
} /* end while */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_find_internal() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_find
|
||
PURPOSE
|
||
Find the node matching a particular key string
|
||
USAGE
|
||
H5ST_ptr_t H5ST_find(tree,s)
|
||
H5ST_tree_t *tree; IN: TST to find string in
|
||
const char *s; IN: String to use as key to locate
|
||
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Locate a key (string) in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
H5ST_ptr_t
|
||
H5ST_find(H5ST_tree_t *tree, const char *s)
|
||
{
|
||
H5ST_ptr_t ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_find,NULL);
|
||
|
||
if((ret_value=H5ST_find_internal(tree->root,s))==NULL)
|
||
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_find() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_locate
|
||
PURPOSE
|
||
Find an object in a TST
|
||
USAGE
|
||
void *H5ST_locate(tree,s)
|
||
H5ST_tree_t *tree; IN: TST to locate object within
|
||
const char *s; IN: String of key for object to locate
|
||
RETURNS
|
||
Success: Non-NULL, pointer to object stored for key
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Locate a node in a TST, returning the object from the node.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
void *
|
||
H5ST_locate(H5ST_tree_t *tree, const char *s)
|
||
{
|
||
H5ST_ptr_t node; /* Pointer to node located */
|
||
void *ret_value; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_locate,NULL);
|
||
|
||
/* Locate the node to remove */
|
||
if((node=H5ST_find_internal(tree->root,s))==NULL)
|
||
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
|
||
|
||
/* Get the pointer to the object to return */
|
||
ret_value=node->eqkid;
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* H5ST_locate() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_findfirst_internal
|
||
PURPOSE
|
||
Find the first node in a TST
|
||
USAGE
|
||
H5ST_ptr_t H5ST_findfirst_internal(p)
|
||
H5ST_ptr_t p; IN: TST to locate first node within
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Get the first (lexicographically) node in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
static H5ST_ptr_t
|
||
H5ST_findfirst_internal(H5ST_ptr_t p)
|
||
{
|
||
H5ST_ptr_t ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOINIT(H5ST_findfirst_internal);
|
||
|
||
while(p) {
|
||
/* Find least node in current tree */
|
||
while(p->lokid)
|
||
p=p->lokid;
|
||
|
||
/* Is least node '\0'? */
|
||
if(p->splitchar=='\0') {
|
||
/* Return it */
|
||
HGOTO_DONE(p);
|
||
} /* end if */
|
||
else {
|
||
/* Go down to next level of tree */
|
||
p=p->eqkid;
|
||
} /* end else */
|
||
} /* end while */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_findfirst_internal() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_findfirst
|
||
PURPOSE
|
||
Find the first node in a TST
|
||
USAGE
|
||
H5ST_ptr_t H5ST_findfirst(tree)
|
||
H5ST_tree_t *tree; IN: TST to locate first node within
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Get the first (lexicographically) node in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
H5ST_ptr_t
|
||
H5ST_findfirst(H5ST_tree_t *tree)
|
||
{
|
||
H5ST_ptr_t ret_value; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_findfirst,NULL);
|
||
|
||
if((ret_value=H5ST_findfirst_internal(tree->root))==NULL)
|
||
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"no nodes in TST");
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_findfirst() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_getnext
|
||
PURPOSE
|
||
Internal routine to find the next node in a given level of a TST
|
||
USAGE
|
||
H5ST_ptr_t H5ST_getnext(p)
|
||
H5ST_ptr_t *p; IN: Pointer to node to find next node from
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Get the next (lexicographically) node in the current level of a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
static H5ST_ptr_t
|
||
H5ST_getnext(H5ST_ptr_t p)
|
||
{
|
||
H5ST_ptr_t ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOINIT(H5ST_getnext);
|
||
|
||
/* If the node to continue from has higher-valued nodes attached */
|
||
if(p->hikid) {
|
||
/* Go to first higher-valued node */
|
||
p=p->hikid;
|
||
|
||
/* Find least node from here */
|
||
while(p->lokid)
|
||
p=p->lokid;
|
||
HGOTO_DONE(p);
|
||
} /* end if */
|
||
else {
|
||
H5ST_ptr_t q; /* Temporary TST node pointer */
|
||
|
||
/* Go up one level in current tree */
|
||
q=p->parent;
|
||
if(q==NULL)
|
||
HGOTO_DONE(NULL);
|
||
|
||
/* While the previous node was the higher-valued node, keep backing up the tree */
|
||
while(q->hikid==p) {
|
||
p=q;
|
||
q=p->parent;
|
||
if(q==NULL)
|
||
HGOTO_DONE(NULL);
|
||
} /* end while */
|
||
HGOTO_DONE(q);
|
||
} /* end else */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_getnext() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_findnext
|
||
PURPOSE
|
||
Find the next node from a node in a TST
|
||
USAGE
|
||
H5ST_ptr_t H5ST_findnext(p)
|
||
H5ST_ptr_t p; IN: Current node to continue from
|
||
RETURNS
|
||
Success: Non-NULL
|
||
Failure: NULL
|
||
DESCRIPTION
|
||
Get the next (lexicographically) node in a TST
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
H5ST_ptr_t
|
||
H5ST_findnext(H5ST_ptr_t p)
|
||
{
|
||
H5ST_ptr_t q; /* Temporary pointer to TST node */
|
||
H5ST_ptr_t ret_value=NULL; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_findnext,NULL);
|
||
|
||
/* Find the next node at the current level, or go back up the tree */
|
||
do {
|
||
q=H5ST_getnext(p);
|
||
if(q) {
|
||
HGOTO_DONE(H5ST_findfirst_internal(q->eqkid));
|
||
} /* end if */
|
||
else
|
||
p=p->up;
|
||
} while(p);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_findnext() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_delete_internal
|
||
PURPOSE
|
||
Delete a node from a TST
|
||
USAGE
|
||
herr_t H5ST_delete_internal(root,p)
|
||
H5ST_ptr_t *root; IN/OUT: Root of TST to delete node from
|
||
H5ST_ptr_t p; IN: Node to delete
|
||
RETURNS
|
||
Success: Non-negative
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Delete a node from a TST.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
This should be the final node for a string.
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
static herr_t
|
||
H5ST_delete_internal(H5ST_ptr_t *root, H5ST_ptr_t p)
|
||
{
|
||
H5ST_ptr_t q, /* Temporary pointer to TST node */
|
||
newp; /* Pointer to node which will replace deleted node in tree */
|
||
|
||
FUNC_ENTER_NOINIT(H5ST_delete_internal);
|
||
|
||
/* Find node to replace one being deleted */
|
||
if(p->lokid) {
|
||
/* If the deleted node has lo & hi kids, attach them together */
|
||
if(p->hikid) {
|
||
q=p->lokid;
|
||
while(q->hikid)
|
||
q=q->hikid;
|
||
q->hikid=p->hikid;
|
||
p->hikid->parent=q;
|
||
} /* end if */
|
||
newp=p->lokid;
|
||
} /* end if */
|
||
else if(p->hikid) {
|
||
newp=p->hikid;
|
||
} /* end if */
|
||
else {
|
||
newp=NULL;
|
||
} /* end else */
|
||
|
||
/* Deleted node is in middle of tree */
|
||
if(p->parent) {
|
||
/* Attach new node to correct side of parent */
|
||
if(p==p->parent->lokid)
|
||
p->parent->lokid=newp;
|
||
else
|
||
p->parent->hikid=newp;
|
||
if(newp)
|
||
newp->parent=p->parent;
|
||
} /* end if */
|
||
else {
|
||
if(newp)
|
||
newp->parent=p->parent;
|
||
if(p->up) {
|
||
p->up->eqkid=newp;
|
||
/* If we deleted the last node in the TST, delete the upper node also */
|
||
if(newp==NULL)
|
||
H5ST_delete_internal(root,p->up);
|
||
} /* end if */
|
||
else /* Deleted last node at top level of tree */
|
||
*root=newp;
|
||
} /* end else */
|
||
|
||
H5FL_FREE(H5ST_node_t,p);
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||
} /* end H5ST_delete_internal() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_delete
|
||
PURPOSE
|
||
Delete a node from a TST
|
||
USAGE
|
||
herr_t H5ST_delete(tree,p)
|
||
H5ST_tree_t *tree; IN/OUT: TST to delete node from
|
||
H5ST_ptr_t p; IN: Node to delete
|
||
RETURNS
|
||
Success: Non-negative
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Delete a node from a TST.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
This should be the final node for a string.
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
herr_t
|
||
H5ST_delete(H5ST_tree_t *tree, H5ST_ptr_t p)
|
||
{
|
||
herr_t ret_value=SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_delete,FAIL);
|
||
|
||
if(H5ST_delete_internal(&tree->root,p)<0)
|
||
HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,FAIL,"can't delete node from TST");
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_delete() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_remove
|
||
PURPOSE
|
||
Remove a node from a TST
|
||
USAGE
|
||
void *H5ST_remove(tree,s)
|
||
H5ST_tree_t *tree; IN/OUT: TST to remove node from
|
||
const char *s; IN: String of key for node to remove
|
||
RETURNS
|
||
Success: Non-NULL, pointer to object stored for key
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Remove a node from a TST, returning the object from the node.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
void *
|
||
H5ST_remove(H5ST_tree_t *tree, const char *s)
|
||
{
|
||
H5ST_ptr_t node; /* Pointer to node to remove */
|
||
void *ret_value; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_remove,NULL);
|
||
|
||
/* Locate the node to remove */
|
||
if((node=H5ST_find_internal(tree->root,s))==NULL)
|
||
HGOTO_ERROR(H5E_TST,H5E_NOTFOUND,NULL,"key not found in TST");
|
||
|
||
/* Get the pointer to the object to return */
|
||
ret_value=node->eqkid;
|
||
|
||
/* Remove the node from the TST */
|
||
if(H5ST_delete_internal(&tree->root,node)<0)
|
||
HGOTO_ERROR(H5E_TST,H5E_CANTDELETE,NULL,"can't delete node from TST");
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* H5ST_remove() */
|
||
|
||
#ifdef H5ST_DEBUG
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_dump_internal
|
||
PURPOSE
|
||
Dump all the nodes of a TST
|
||
USAGE
|
||
herr_t H5ST_dump(p)
|
||
H5ST_ptr_t p; IN: Root of TST to dump
|
||
RETURNS
|
||
Success: Non-negative
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Dump information for a TST.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
herr_t
|
||
H5ST_dump_internal(H5ST_ptr_t p)
|
||
{
|
||
FUNC_ENTER_NOINIT(H5ST_dump_internal);
|
||
|
||
if (p) {
|
||
printf("p=%p\n",p);
|
||
printf("\tp->up=%p\n",p->up);
|
||
printf("\tp->parent=%p\n",p->parent);
|
||
printf("\tp->lokid=%p\n",p->lokid);
|
||
printf("\tp->hikid=%p\n",p->hikid);
|
||
printf("\tp->eqkid=%p\n",p->eqkid);
|
||
printf("\tp->splitchar=%c\n",p->splitchar);
|
||
|
||
H5ST_dump_internal(p->lokid);
|
||
if (p->splitchar)
|
||
H5ST_dump_internal(p->eqkid);
|
||
else
|
||
printf("%s\n", (char *) p->eqkid);
|
||
H5ST_dump_internal(p->hikid);
|
||
} /* end if */
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(SUCCEED);
|
||
} /* end H5ST_dump_internal() */
|
||
|
||
|
||
/*--------------------------------------------------------------------------
|
||
NAME
|
||
H5ST_dump
|
||
PURPOSE
|
||
Dump all the nodes of a TST
|
||
USAGE
|
||
herr_t H5ST_dump(tree)
|
||
H5ST_tree_t *tree; IN: TST to dump
|
||
RETURNS
|
||
Success: Non-negative
|
||
Failure: Negative
|
||
DESCRIPTION
|
||
Dump information for a TST.
|
||
GLOBAL VARIABLES
|
||
COMMENTS, BUGS, ASSUMPTIONS
|
||
EXAMPLES
|
||
REVISION LOG
|
||
--------------------------------------------------------------------------*/
|
||
herr_t
|
||
H5ST_dump(H5ST_tree_t *tree)
|
||
{
|
||
herr_t ret_value=SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5ST_dump,NULL);
|
||
|
||
/* Dump the tree */
|
||
H5ST_dump_internal(tree->root);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value);
|
||
} /* end H5ST_dump() */
|
||
#endif /* H5ST_DEBUG */
|