summaryrefslogtreecommitdiffstats
path: root/testpar/t_ph5basic.c
Commit message (Expand)AuthorAgeFilesLines
* Added H5Pset/get_mpi_params calls and unified them with the MPI-I/ODana Robinson2019-08-261-69/+66
* Merge pull request #426 in HDFFV/hdf5 from ~LRKNOX/hdf5_lrk:hdf5_1_10 to hdf5...Larry Knox2017-04-251-6/+4
* [svn-r24864] Description:Quincey Koziol2014-03-211-114/+0
* [svn-r13253] Updated all C and C++ style source code files with the THG copyr...Albert Cheng2007-02-071-2/+3
* [svn-r11245] Purpose:Quincey Koziol2005-08-131-3/+3
* [svn-r9358] Purpose:Quincey Koziol2004-10-041-1/+0
* [svn-r8096] Purpose:Albert Cheng2004-01-221-16/+16
* [svn-r7181] Purpose:Quincey Koziol2003-07-071-18/+0
* [svn-r7019] Purpose:Quincey Koziol2003-06-101-0/+18
* [svn-r7002] Purpose:Quincey Koziol2003-06-091-1/+0
* [svn-r6795] Purpose:Bill Wendling2003-05-051-5/+6
* [svn-r6755] Purpose:Albert Cheng2003-04-251-1/+116
* [svn-r6741] Purpose:Albert Cheng2003-04-231-4/+8
* [svn-r6709] Purpose:Albert Cheng2003-04-181-0/+188
id='n199' href='#n199'>199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * 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://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
 * access to either file, you may request a copy from help@hdfgroup.org.     *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/* 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.
*/


#include "H5Eprivate.h"		/* Error handling		  	*/
#include "H5FLprivate.h"	/* Free lists                           */
#include "H5STprivate.h"        /* Ternary search trees                 */

/* 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_NOAPI_NOINIT_NOFUNC(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_NOFUNC(H5ST_search);

    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_NOAPI_NOINIT_NOFUNC(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_NOAPI_NOINIT_NOFUNC(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_NOAPI_NOINIT_NOFUNC(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_NOFUNC(H5ST_findnext);

    /* 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_NOAPI_NOINIT_NOFUNC(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_NOAPI_NOINIT_NOFUNC(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 */

    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)
{
    FUNC_ENTER_NOAPI_NOFUNC(H5ST_dump,NULL);

    /* Dump the tree */
    H5ST_dump_internal(tree->root);

    FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5ST_dump() */
#endif /* H5ST_DEBUG */