[svn-r6436] Purpose:

New internal feature

Description:
    Add internal API for building and working with heaps (H5HP).  This will be
    used for the LRU algorithm in the new metadata cache code.

Platforms tested:
    Tested h5committest {arabica (fortran), eirene (fortran, C++)
	modi4 (parallel, fortran)}
    FreeBSD 4.7 (sleipnir)
This commit is contained in:
Quincey Koziol 2003-02-24 15:25:13 -05:00
parent f239b2e7f3
commit 474a1434bd
8 changed files with 2107 additions and 20 deletions

View File

@ -855,6 +855,8 @@
./src/H5HL.c
./src/H5HLprivate.h
./src/H5HLpublic.h
./src/H5HP.c
./src/H5HPprivate.h
./src/H5I.c
./src/H5Iprivate.h
./src/H5Ipublic.h
@ -1005,6 +1007,7 @@
./test/tgenprop.c
./test/th5s.c
./test/th5s.h5
./test/theap.c
./test/titerate.c
./test/tmeta.c
./test/tmisc.c

934
src/H5HP.c Normal file
View File

@ -0,0 +1,934 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Purpose: Provides a heap abstract data type.
*
* (See chapter 11 - "Priority Queues" of _Algorithms_, by
* Sedgewick for additional information)
*
*/
/* Private headers needed */
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5HPprivate.h" /* Heap routines */
#include "H5FLprivate.h" /* Memory management functions */
/* Pablo information */
#define PABLO_MASK H5HP_mask
/* Interface initialization? */
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
/* Local Macros */
#define H5HP_START_SIZE 16 /* Initial number of entries for heaps */
/* Private typedefs & structs */
/* Data structure for entries in the internal heap array */
typedef struct {
int val; /* Value to be used for heap condition */
H5HP_info_t *obj; /* Pointer to object stored in heap */
}H5HP_ent_t;
/* Main heap data structure */
struct H5HP_t {
H5HP_type_t type; /* Type of heap (minimum or maximum value at "top") */
size_t nobjs; /* Number of active objects in heap array */
size_t nalloc; /* Number of allocated locations in heap array */
H5HP_ent_t *heap; /* Pointer to array containing heap entries */
};
/* Static functions */
static herr_t H5HP_swim_max(H5HP_t *heap, size_t loc);
static herr_t H5HP_swim_min(H5HP_t *heap, size_t loc);
static herr_t H5HP_sink_max(H5HP_t *heap, size_t loc);
static herr_t H5HP_sink_min(H5HP_t *heap, size_t loc);
/* Declare a free list to manage the H5HP_t struct */
H5FL_DEFINE_STATIC(H5HP_t);
/* Declare a free list to manage arrays of H5HP_ent_t */
H5FL_ARR_DEFINE_STATIC(H5HP_ent_t,-1);
/*--------------------------------------------------------------------------
NAME
H5HP_swim_max
PURPOSE
Restore heap condition by moving an object upward
USAGE
herr_t H5HP_swim_max(heap, loc)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
size_t loc; IN: Location to start from
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Restore the heap condition for the heap's array by "swimming" the object
at a location upward.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
This routine is for "maximum" value heaps.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
H5HP_swim_max(H5HP_t *heap, size_t loc)
{
int val; /* Temporary copy value of object to move in heap */
H5HP_info_t *obj; /* Temporary pointer to object to move in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5HP_swim_max);
/* Get copies of the information about the object to move in the heap */
val=heap->heap[loc].val;
obj=heap->heap[loc].obj;
/* Move object up in heap until it's reached the maximum location possible */
while(heap->heap[loc/2].val < val) {
/* Move object "above" current location in heap down */
heap->heap[loc].val=heap->heap[loc/2].val;
heap->heap[loc].obj=heap->heap[loc/2].obj;
/* Update heap location for object which moved */
heap->heap[loc].obj->heap_loc=loc;
/* Move to location "above" current location */
loc=loc/2;
} /* end while */
/* Put object into heap at correct location */
heap->heap[loc].val=val;
heap->heap[loc].obj=obj;
/* Update heap location for object */
heap->heap[loc].obj->heap_loc=loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_swim_max() */
/*--------------------------------------------------------------------------
NAME
H5HP_swim_min
PURPOSE
Restore heap condition by moving an object upward
USAGE
herr_t H5HP_swim_min(heap, loc)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
size_t loc; IN: Location to start from
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Restore the heap condition for the heap's array by "swimming" the object
at a location upward.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
This routine is for "minimum" value heaps.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
H5HP_swim_min(H5HP_t *heap, size_t loc)
{
int val; /* Temporary copy value of object to move in heap */
H5HP_info_t *obj; /* Temporary pointer to object to move in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5HP_swim_min);
/* Get copies of the information about the object to move in the heap */
val=heap->heap[loc].val;
obj=heap->heap[loc].obj;
/* Move object up in heap until it's reached the minimum location possible */
while(heap->heap[loc/2].val > val) {
/* Move object "above" current location in heap down */
heap->heap[loc].val=heap->heap[loc/2].val;
heap->heap[loc].obj=heap->heap[loc/2].obj;
/* Update heap location for object which moved */
heap->heap[loc].obj->heap_loc=loc;
/* Move to location "above" current location */
loc=loc/2;
} /* end while */
/* Put object into heap at correct location */
heap->heap[loc].val=val;
heap->heap[loc].obj=obj;
/* Update heap location for object */
heap->heap[loc].obj->heap_loc=loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_swim_min() */
/*--------------------------------------------------------------------------
NAME
H5HP_sink_max
PURPOSE
Restore heap condition by moving an object downward
USAGE
herr_t H5HP_sink_max(heap, loc)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
size_t loc; IN: Location to start from
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Restore the heap condition for the heap's array by "sinking" the object
at a location downward.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
This routine is for "maximum" value heaps.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
H5HP_sink_max(H5HP_t *heap, size_t loc)
{
int val; /* Temporary copy value of object to move in heap */
void *obj; /* Temporary pointer to object to move in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5HP_sink_max);
/* Get copies of the information about the object to move in the heap */
val=heap->heap[loc].val;
obj=heap->heap[loc].obj;
/* Move object up in heap until it's reached the maximum location possible */
while((2*loc)<=heap->nobjs) {
size_t new_loc=loc*2; /* New object's potential location area */
/* Get the greater of the two objects below the location in heap */
if(new_loc<heap->nobjs && (heap->heap[new_loc].val < heap->heap[new_loc+1].val))
new_loc++;
/* Check if the object is smaller than the larger of the objects below it */
/* If so, its in the correct location now, and we can get out */
if(val >= heap->heap[new_loc].val)
break;
/* Move the greater of the two objects below the current location up */
heap->heap[loc].val=heap->heap[new_loc].val;
heap->heap[loc].obj=heap->heap[new_loc].obj;
/* Update heap location for object which moved */
heap->heap[loc].obj->heap_loc=loc;
/* Move to location "below" current location */
loc=new_loc;
} /* end while */
/* Put object into heap at correct location */
heap->heap[loc].val=val;
heap->heap[loc].obj=obj;
/* Update heap location for object */
heap->heap[loc].obj->heap_loc=loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_sink_max() */
/*--------------------------------------------------------------------------
NAME
H5HP_sink_min
PURPOSE
Restore heap condition by moving an object downward
USAGE
herr_t H5HP_sink_min(heap, loc)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
size_t loc; IN: Location to start from
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Restore the heap condition for the heap's array by "sinking" the object
at a location downward.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
This routine is for "minimum" value heaps.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
H5HP_sink_min(H5HP_t *heap, size_t loc)
{
int val; /* Temporary copy value of object to move in heap */
void *obj; /* Temporary pointer to object to move in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5HP_sink_min);
/* Get copies of the information about the object to move in the heap */
val=heap->heap[loc].val;
obj=heap->heap[loc].obj;
/* Move object up in heap until it's reached the maximum location possible */
while((2*loc)<=heap->nobjs) {
size_t new_loc=loc*2; /* New object's potential location area */
/* Get the lesser of the two objects below the location in heap */
if(new_loc<heap->nobjs && (heap->heap[new_loc].val > heap->heap[new_loc+1].val))
new_loc++;
/* Check if the object is greater than the larger of the objects below it */
/* If so, its in the correct location now, and we can get out */
if(val <= heap->heap[new_loc].val)
break;
/* Move the greater of the two objects below the current location up */
heap->heap[loc].val=heap->heap[new_loc].val;
heap->heap[loc].obj=heap->heap[new_loc].obj;
/* Update heap location for object which moved */
heap->heap[loc].obj->heap_loc=loc;
/* Move to location "below" current location */
loc=new_loc;
} /* end while */
/* Put object into heap at correct location */
heap->heap[loc].val=val;
heap->heap[loc].obj=obj;
/* Update heap location for object */
heap->heap[loc].obj->heap_loc=loc;
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_sink_min() */
/*--------------------------------------------------------------------------
NAME
H5HP_create
PURPOSE
Create a heap
USAGE
H5HP_t *H5HP_create(heap_type)
H5HP_type_t heap_type; IN: Type of heap to create
RETURNS
Returns a pointer to a heap on success, NULL on failure.
DESCRIPTION
Create a priority queue. The SIZE is used to set the initial number of
entries allocated.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
H5HP_t *
H5HP_create(H5HP_type_t heap_type)
{
H5HP_t *new_heap=NULL; /* Pointer to new heap object created */
H5HP_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HP_create,NULL);
/* Check args */
assert(heap_type==H5HP_MIN_HEAP || heap_type==H5HP_MAX_HEAP);
/* Allocate ref-counted string structure */
if((new_heap=H5FL_MALLOC(H5HP_t))==NULL)
HGOTO_ERROR(H5E_HEAP,H5E_NOSPACE,NULL,"memory allocation failed");
/* Allocate the array to store the heap entries */
if((new_heap->heap=H5FL_ARR_MALLOC(H5HP_ent_t, H5HP_START_SIZE+1))==NULL)
HGOTO_ERROR(H5E_HEAP,H5E_NOSPACE,NULL,"memory allocation failed");
/* Set the internal fields */
new_heap->type=heap_type;
new_heap->nobjs=0;
new_heap->nalloc=H5HP_START_SIZE+1;
/* Set the information in the 0'th location based on the type of heap */
if(heap_type==H5HP_MIN_HEAP) {
/* Set the value in the '0' location to be the minimum value, to
* simplify the algorithms
*/
new_heap->heap[0].val=INT_MIN;
new_heap->heap[0].obj=NULL;
} /* end if */
else {
/* Set the value in the '0' location to be the maximum value, to
* simplify the algorithms
*/
new_heap->heap[0].val=INT_MAX;
new_heap->heap[0].obj=NULL;
} /* end else */
/* Set the return value */
ret_value=new_heap;
done:
/* Error cleanup */
if(ret_value==NULL) {
if(new_heap!=NULL) {
if(new_heap->heap!=NULL)
H5FL_ARR_FREE(H5HP_ent_t,new_heap->heap);
H5FL_FREE(H5HP_t,new_heap);
} /* end if */
} /* end if */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_create() */
/*--------------------------------------------------------------------------
NAME
H5HP_count
PURPOSE
Check the number of elements in a heap
USAGE
ssize_t H5HP_count(heap)
const H5HP_t *heap; IN: Pointer to heap to query
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Checks the number of elements in heap
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
ssize_t
H5HP_count(const H5HP_t *heap)
{
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HP_count,FAIL);
/* Check args */
assert(heap);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Return the number of objects in the heap */
ret_value=heap->nobjs;
done:
/* No post-condition check necessary, since heap is constant */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_count() */
/*--------------------------------------------------------------------------
NAME
H5HP_insert
PURPOSE
Insert an object into a heap, with an initial value
USAGE
herr_t H5HP_insert(heap, val, obj)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
int val; IN: Initial value for object in heap
void *obj; IN: Pointer to object to insert into heap
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Inserts a OBJ into a HEAP, with an initial VALue.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_insert(H5HP_t *heap, int val, void *obj)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_insert,FAIL);
/* Check args */
assert(heap);
assert(obj);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Increment number of objects in heap */
heap->nobjs++;
/* Check if we need to allocate more room for heap array */
if(heap->nobjs>=heap->nalloc) {
size_t n = MAX(H5HP_START_SIZE, 2*(heap->nalloc-1)) + 1;
H5HP_ent_t *new_heap = H5FL_ARR_REALLOC(H5HP_ent_t,heap->heap, n);
if (!new_heap)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend heap array");
heap->heap = new_heap;
heap->nalloc = n;
} /* end if */
/* Insert new object at end of heap */
heap->heap[heap->nobjs].val=val;
heap->heap[heap->nobjs].obj=obj;
heap->heap[heap->nobjs].obj->heap_loc=heap->nobjs;
/* Restore heap condition */
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_swim_max(heap,heap->nobjs)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_swim_min(heap,heap->nobjs)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "unable to restore heap condition");
} /* end else */
done:
/* Check internal consistency */
/* (Post-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_insert() */
/*--------------------------------------------------------------------------
NAME
H5HP_top
PURPOSE
Check the value of the top object in the heap
USAGE
herr_t H5HP_top(heap, val)
const H5HP_t *heap; IN: Pointer to heap to modify
int val; IN/OUT: Initial value for object in heap
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Checks the value of the top object in a heap
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_top(const H5HP_t *heap, int *val)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_top,FAIL);
/* Check args */
assert(heap);
assert(val);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Get value of the top object in the heap */
*val=heap->heap[1].val;
done:
/* No post-condition check necessary, since heap is constant */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_top() */
/*--------------------------------------------------------------------------
NAME
H5HP_remove
PURPOSE
Remove an object into a heap
USAGE
herr_t H5HP_remove(heap, val, obj)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
int *val; OUT: Pointer to value of object removed from heap
void **obj; OUT: Pointer to object removed from heap
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Removes the top object on a heap, returning its value and object pointer
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_remove(H5HP_t *heap, int *val, void **obj)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_remove,FAIL);
/* Check args */
assert(heap);
assert(val);
assert(obj);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Check if there are any objects on the heap to remove */
if(heap->nobjs==0)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "heap is empty");
/* Get the information for the top object on the heap */
assert(heap->heap[1].obj->heap_loc==1);
*val=heap->heap[1].val;
*obj=heap->heap[1].obj;
/* Move the last element in the heap to the top */
heap->heap[1].val=heap->heap[heap->nobjs].val;
heap->heap[1].obj=heap->heap[heap->nobjs].obj;
heap->heap[1].obj->heap_loc=1;
/* Decrement number of objects in heap */
heap->nobjs--;
/* Restore heap condition, if there are objects on the heap */
if(heap->nobjs>0) {
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_sink_max(heap,1)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_sink_min(heap,1)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "unable to restore heap condition");
} /* end else */
} /* end if */
done:
/* Check internal consistency */
/* (Post-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_remove() */
/*--------------------------------------------------------------------------
NAME
H5HP_change
PURPOSE
Change the priority of an object on a heap
USAGE
herr_t H5HP_change(heap, val, obj)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
int val; IN: New priority value for object
void *obj; IN: Pointer to object to modify
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Changes the priority of an object on a heap.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_change(H5HP_t *heap, int val, void *_obj)
{
H5HP_info_t *obj=(H5HP_info_t *)_obj; /* Alias for object */
size_t obj_loc; /* Location of object in heap */
int old_val; /* Object's old priority value */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_change,FAIL);
/* Check args */
assert(heap);
assert(obj);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Get the location of the object in the heap */
obj_loc=obj->heap_loc;
assert(obj_loc>0 && obj_loc<=heap->nobjs);
/* Change the heap object's priority */
old_val=heap->heap[obj_loc].val;
heap->heap[obj_loc].val=val;
/* Restore heap condition */
if(val<old_val) {
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_sink_max(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_swim_min(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end else */
} /* end if */
else {
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_swim_max(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_sink_min(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end else */
} /* end else */
done:
/* Check internal consistency */
/* (Post-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_change() */
/*--------------------------------------------------------------------------
NAME
H5HP_incr
PURPOSE
Increment the priority of an object on a heap
USAGE
herr_t H5HP_incr(heap, amt, obj)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
unsigned amt; IN: Amount to increase priority by
void *obj; IN: Pointer to object to modify
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Increments the priority of an object on a heap by one.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_incr(H5HP_t *heap, unsigned amt, void *_obj)
{
H5HP_info_t *obj=(H5HP_info_t *)_obj; /* Alias for object */
size_t obj_loc; /* Location of object in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_incr,FAIL);
/* Check args */
assert(heap);
assert(obj);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Get the location of the object in the heap */
obj_loc=obj->heap_loc;
assert(obj_loc>0 && obj_loc<=heap->nobjs);
/* Change the heap object's priority */
heap->heap[obj_loc].val+=amt;
/* Restore heap condition */
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_swim_max(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_sink_min(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end else */
done:
/* Check internal consistency */
/* (Post-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_incr() */
/*--------------------------------------------------------------------------
NAME
H5HP_decr
PURPOSE
Decrement the priority of an object on a heap
USAGE
herr_t H5HP_dec(heap, amt, obj)
H5HP_t *heap; IN/OUT: Pointer to heap to modify
unsigned amt; IN: Amount to decrease priority by
void *obj; IN: Pointer to object to modify
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Decrements the priority of an object on a heap by one.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_decr(H5HP_t *heap, unsigned amt, void *_obj)
{
H5HP_info_t *obj=(H5HP_info_t *)_obj; /* Alias for object */
size_t obj_loc; /* Location of object in heap */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_decr,FAIL);
/* Check args */
assert(heap);
assert(obj);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Get the location of the object in the heap */
obj_loc=obj->heap_loc;
assert(obj_loc>0 && obj_loc<=heap->nobjs);
/* Change the heap object's priority */
heap->heap[obj_loc].val-=amt;
/* Restore heap condition */
if(heap->type==H5HP_MAX_HEAP) {
if(H5HP_sink_max(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end if */
else {
if(H5HP_swim_min(heap,obj_loc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCHANGE, FAIL, "unable to restore heap condition");
} /* end else */
done:
/* Check internal consistency */
/* (Post-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_decr() */
/*--------------------------------------------------------------------------
NAME
H5HP_close
PURPOSE
Close a heap, deallocating it.
USAGE
herr_t H5HP_close(heap)
H5HP_t *heap; IN/OUT: Pointer to heap to close
RETURNS
Returns non-negative on success, negative on failure.
DESCRIPTION
Close a heap, freeing all internal information. Any objects left in
the heap are not deallocated.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5HP_close(H5HP_t *heap)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HP_close,FAIL);
/* Check args */
assert(heap);
/* Check internal consistency */
/* (Pre-condition) */
assert(heap->nobjs<heap->nalloc);
assert(heap->heap);
assert((heap->type==H5HP_MAX_HEAP && heap->heap[0].val==INT_MAX) ||
(heap->type==H5HP_MIN_HEAP && heap->heap[0].val==INT_MIN));
assert(heap->heap[0].obj==NULL);
/* Free internal structures for heap */
H5FL_ARR_FREE(H5HP_ent_t,heap->heap);
/* Free actual heap object */
H5FL_FREE(H5HP_t,heap);
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HP_close() */

70
src/H5HPprivate.h Normal file
View File

@ -0,0 +1,70 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 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. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* This file contains private information about the H5HP module
*/
#ifndef _H5HPprivate_H
#define _H5HPprivate_H
/**************************************/
/* Public headers needed by this file */
/**************************************/
#ifdef LATER
#include "H5HPpublic.h"
#endif /* LATER */
/***************************************/
/* Private headers needed by this file */
/***************************************/
#include "H5private.h"
/************/
/* Typedefs */
/************/
/* Typedef for heap struct (defined in H5HP.c) */
typedef struct H5HP_t H5HP_t;
/* Typedef for objects which can be inserted into heaps */
/* This _must_ be the first field in objects which can be inserted into heaps */
typedef struct H5HP_info_t {
size_t heap_loc; /* Location of object in heap */
}H5HP_info_t;
/* Typedef for type of heap to create */
typedef enum {
H5HP_MIN_HEAP, /* Minimum values in heap are at the "top" */
H5HP_MAX_HEAP /* Maximum values in heap are at the "top" */
} H5HP_type_t;
/**********/
/* Macros */
/**********/
/********************/
/* Private routines */
/********************/
H5_DLL H5HP_t *H5HP_create(H5HP_type_t heap_type);
H5_DLL herr_t H5HP_insert(H5HP_t *heap, int val, void *obj);
H5_DLL ssize_t H5HP_count(const H5HP_t *heap);
H5_DLL herr_t H5HP_top(const H5HP_t *heap, int *val);
H5_DLL herr_t H5HP_remove(H5HP_t *heap, int *val, void **ptr);
H5_DLL herr_t H5HP_change(H5HP_t *heap, int val, void *obj);
H5_DLL herr_t H5HP_incr(H5HP_t *heap, unsigned amt, void *obj);
H5_DLL herr_t H5HP_decr(H5HP_t *heap, unsigned amt, void *obj);
H5_DLL herr_t H5HP_close(H5HP_t *heap);
#endif /* _H5HPprivate_H */

View File

@ -33,12 +33,12 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \
H5FDfphdf5.c H5FDgass.c H5FDlog.c H5FDmpio.c H5FDmpiposix.c \
H5FDmulti.c H5FDsec2.c H5FDsrb.c H5FDstdio.c H5FDstream.c H5FL.c \
H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c H5G.c H5Gent.c \
H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c \
H5Obogus.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c \
H5Omtime.c H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c \
H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5HP.c H5I.c H5MF.c H5MM.c H5O.c \
H5Oattr.c H5Obogus.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c \
H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c \
H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c \
H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
H5Sselect.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c \
H5Spoint.c H5Sselect.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c H5Tfixed.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \
@ -62,10 +62,11 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5FLprivate.h \
H5FOprivate.h H5FPprivate.h H5FSprivate.h H5Gprivate.h H5Gpkg.h \
H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h H5MMprivate.h \
H5Oprivate.h H5Pprivate.h H5Ppkg.h H5Rprivate.h H5RSprivate.h \
H5Sprivate.h H5STprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h \
H5TSprivate.h H5Vprivate.h H5Zprivate.h H5config.h
H5HGprivate.h H5HLprivate.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \
H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \
H5Rprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h \
H5Tprivate.h H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \
H5Zprivate.h H5config.h
## Number format detection
## The LD_LIBRARY_PATH setting is a klutch.

View File

@ -1541,6 +1541,19 @@ ttbbt.lo: \
$(top_srcdir)/src/H5Epublic.h \
$(top_srcdir)/src/H5Ipublic.h \
$(top_srcdir)/src/H5TBprivate.h
theap.lo: \
$(srcdir)/theap.c \
$(srcdir)/testhdf5.h \
$(top_srcdir)/src/H5private.h \
$(top_srcdir)/src/H5public.h \
$(top_builddir)/src/H5pubconf.h \
$(top_srcdir)/src/H5api_adpt.h \
$(top_srcdir)/src/H5MPprivate.h \
$(top_srcdir)/src/H5FSprivate.h \
$(top_srcdir)/src/H5Eprivate.h \
$(top_srcdir)/src/H5Epublic.h \
$(top_srcdir)/src/H5Ipublic.h \
$(top_srcdir)/src/H5HPprivate.h
ttst.lo: \
$(srcdir)/ttst.c \
$(srcdir)/testhdf5.h \

View File

@ -1,10 +1,18 @@
##
## 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.
##
## HDF5 Library Test Makefile(.in)
##
## Copyright (C) 1997, 2002
## National Center for Supercomputing Applications.
## All rights reserved.
##
##
top_srcdir=@top_srcdir@
top_builddir=..
srcdir=@srcdir@
@ -65,8 +73,8 @@ TEST_SRC=big.c bittests.c cmpd_dset.c dsets.c dtypes.c extend.c \
external.c fillval.c flush1.c flush2.c gheap.c h5test.c hyperslab.c \
istore.c lheap.c links.c mount.c mtime.c ohdr.c stab.c tarray.c \
tattr.c tconfig.c testhdf5.c testmeta.c tfile.c tgenprop.c th5s.c \
titerate.c tmeta.c trefer.c trefstr.c tselect.c ttime.c ttbbt.c \
ttst.c tvltypes.c tvlstr.c tmisc.c unlink.c enum.c ttsafe.c \
theap.c titerate.c tmeta.c trefer.c trefstr.c tselect.c ttime.c \
ttbbt.c ttst.c tvltypes.c tvlstr.c tmisc.c unlink.c enum.c ttsafe.c \
ttsafe_dcreate.c ttsafe_error.c ttsafe_cancel.c ttsafe_acreate.c \
gass_write.c gass_read.c gass_append.c srb_read.c srb_write.c \
srb_append.c stream_test.c set_extent.c getname.c file_handle.c \
@ -90,11 +98,11 @@ timings _timings: $(TIMINGS)
## How to build the tests... They all depend on the test and hdf5 libraries.
$(TEST_PROGS): $(LIB) $(LIBHDF5)
TESTHDF5_OBJ=testhdf5.lo tarray.lo tattr.lo tconfig.lo tfile.lo tgenprop.lo \
th5s.lo titerate.lo tmeta.lo ttime.lo trefer.lo trefstr.lo tselect.lo \
ttbbt.lo ttst.lo tvltypes.lo tvlstr.lo tmisc.lo
TESTHDF5_OBJ=testhdf5.lo tarray.lo tattr.lo tconfig.lo tfile.lo tgenprop.lo \
th5s.lo theap.lo titerate.lo tmeta.lo ttime.lo trefer.lo trefstr.lo \
tselect.lo ttbbt.lo ttst.lo tvltypes.lo tvlstr.lo tmisc.lo
TTS_OBJ=ttsafe.lo ttsafe_dcreate.lo ttsafe_error.lo ttsafe_cancel.lo \
TTS_OBJ=ttsafe.lo ttsafe_dcreate.lo ttsafe_error.lo ttsafe_cancel.lo \
ttsafe_acreate.lo
testhdf5: $(TESTHDF5_OBJ)

View File

@ -158,6 +158,7 @@ main(int argc, char *argv[])
InitTest("metadata", test_metadata, cleanup_metadata, "Encode/decode metadata code");
InitTest("tbbt", test_tbbt, NULL, "Threaded, Balanced, Binary Trees");
InitTest("tst", test_tst, NULL, "Ternary Search Trees");
InitTest("heap", test_heap, NULL, "Memory Heaps");
InitTest("refstr", test_refstr, NULL, "Reference Counted Strings");
InitTest("file", test_file, cleanup_file, "Low-Level File I/O");
InitTest("h5s", test_h5s, cleanup_h5s, "Dataspaces");

1057
test/theap.c Normal file

File diff suppressed because it is too large Load Diff