/* listmanip.c */
#include "../IVL.h"
#define MYDEBUG 0
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------------------
fills size of and pointer to the entries of a list
set *psize = size of list ilist
set *pivec = base address of list ilist
use as follows :
IVL_listAndSize(ivl, ilist, &isize, &ivec) ;
for ( i = 0 ; i < isize ; i++ ) {
do something with ivec[i] ;
}
created -- 95sep22, cca
----------------------------------------------------------------
*/
void
IVL_listAndSize (
IVL *ivl,
int ilist,
int *psize,
int **pivec
) {
/*
---------------
check the input
---------------
*/
if ( ivl == NULL || ilist < 0 || ilist >= ivl->nlist
|| psize == NULL || pivec == NULL ) {
fprintf(stderr, "\n fatal error in IVL_listAndSize(%p,%d,%p,%p)"
"\n bad input\n", ivl, ilist, psize, pivec) ;
if ( ivl != NULL ) {
fprintf(stderr, "\n ilist = %d, nlist = %d",
ilist, ivl->nlist) ;
IVL_writeForHumanEye(ivl, stderr) ;
}
exit(-1) ;
}
/*
--------------------------
set the two pointer fields
--------------------------
*/
*psize = ivl->sizes[ilist] ;
*pivec = ivl->p_vec[ilist] ;
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------
returns a pointer to the first element in list ilist
to be used as a general iterator, e.g.,
for ( pi = IVL_firstInList(ivl, ilist) ;
pi != NULL ;
pi = IVL_nextInList(ivl, ilist, pi) ) {
do something ;
}
created -- 95sep27, cca
----------------------------------------------------
*/
int *
IVL_firstInList (
IVL *ivl,
int ilist
) {
/*
---------------
check the input
---------------
*/
if ( ivl == NULL ) {
fprintf(stderr, "\n fatal error in IVL_firstInList(%p,%d)"
"\n bad input, ivl is NULL\n", ivl, ilist) ;
exit(-1) ;
}
if ( ilist < 0 || ilist >= ivl->nlist ) {
fprintf(stderr, "\n fatal error in IVL_firstInList(%p,%d)"
"\n bad input, ilist = %d, must be in [0,%d) \n",
ivl, ilist, ilist, ivl->nlist) ;
exit(-1) ;
}
if ( ivl->sizes[ilist] == 0 ) {
return(NULL) ;
} else if ( ivl->p_vec[ilist] != NULL ) {
return(ivl->p_vec[ilist]) ;
} else {
fprintf(stderr, "\n fatal error in IVL_firstInList(%p,%d)"
"\n size > 0 but list is NULL\n", ivl, ilist) ;
exit(-1) ;
}
}
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------
returns a pointer to the next element in list ilist
to be used as a general iterator, e.g.,
for ( pi = IVL_firstInList(ivl, ilist) ;
pi != NULL ;
pi = IVL_nextInList(ivl, ilist, pi) ) {
do something ;
}
created -- 95sep27, cca
----------------------------------------------------
*/
int *
IVL_nextInList (
IVL *ivl,
int ilist,
int *pi
) {
int offset ;
/*
---------------
check the input
---------------
*/
if ( ivl == NULL ) {
fprintf(stderr, "\n fatal error in IVL_nextInList(%p,%d,%p)"
"\n bad input, ivl is NULL\n", ivl, ilist, pi) ;
exit(-1) ;
}
if ( ilist < 0 || ilist >= ivl->nlist ) {
fprintf(stderr, "\n fatal error in IVL_nextInList(%p,%d,%p)"
"\n bad input, ilist = %d, must be in [0,%d) \n",
ivl, ilist, pi, ilist, ivl->nlist) ;
exit(-1) ;
}
if ( (pi == NULL)
|| ((offset = pi - ivl->p_vec[ilist]) < 0)
|| offset >= ivl->sizes[ilist] ) {
fprintf(stderr, "\n fatal error in IVL_nextInList(%p,%d,%p)"
"\n bad pointer\n", ivl, ilist, pi) ;
exit(-1) ;
} else if ( offset == ivl->sizes[ilist] - 1 ) {
return(NULL) ;
} else {
return(pi+1) ;
}
}
/*--------------------------------------------------------------------*/
/*
-----------------------------------------------------------------
purpose -- to set or reset a list.
ilist -- list id to set or reset
isize -- size of the list
if the present size of list ilist is smaller than isize,
the old list is free'd (if ivl->type = IVL_SOLO)
or lost (if ivl->type = IVL_CHUNKED)
or un-set (if ivl->type = IVL_UNKNOWN)
and new storage is allocated (for IVL_SOLO and IVL_CHUNKED)
ivec -- list vector
if ivl->type is IVL_UNKNOWN then
if ivec != NULL then
we set the ivl list pointer to be ivec
endif
else if ivec != NULL
we copy ivec[] into ivl's storage for the list
endif
created -- 95sep27, cca
last mods -- 95oct06, cca
type = IVL_UNKNOWN, p_vec[ilist] set to ivec
only when ivec is not NULL
bug fixed, ivl->sizes[ilist] = isize ;
-----------------------------------------------------------------
*/
void
IVL_setList (
IVL *ivl,
int ilist,
int isize,
int ivec[]
) {
/*
---------------
check the input
---------------
*/
if ( ivl == NULL ) {
fprintf(stderr, "\n fatal error in IVL_setList(%p,%d,%d,%p)"
"\n bad input, ivl is NULL\n", ivl, ilist, isize, ivec) ;
exit(-1) ;
}
if ( ilist < 0 ) {
fprintf(stderr, "\n fatal error in IVL_setList(%p,%d,%d,%p)"
"\n bad input, ilist < 0", ivl, ilist, isize, ivec) ;
exit(-1) ;
}
if ( ilist >= ivl->maxnlist ) {
int newmaxnlist = (int) 1.25*ivl->maxnlist ;
if ( newmaxnlist < 10 ) {
newmaxnlist = 10 ;
}
if ( ilist >= newmaxnlist ) {
newmaxnlist = ilist + 1 ;
}
IVL_setMaxnlist(ivl, newmaxnlist) ;
}
if ( ilist >= ivl->nlist ) {
ivl->nlist = ilist + 1 ;
}
if ( isize == 0 ) {
/*
------------------------------------------
new list is empty, free storage if present
------------------------------------------
*/
if ( ivl->type == IVL_SOLO ) {
if ( ivl->p_vec[ilist] != NULL ) {
IVfree(ivl->p_vec[ilist]) ;
}
}
ivl->tsize -= ivl->sizes[ilist] ;
ivl->sizes[ilist] = 0 ;
ivl->p_vec[ilist] = NULL ;
} else if ( ivl->type == IVL_UNKNOWN ) {
/*
-------------------------------
simply set the size and pointer
-------------------------------
*/
ivl->tsize += isize - ivl->sizes[ilist] ;
ivl->sizes[ilist] = isize ;
if ( ivec != NULL ) {
ivl->p_vec[ilist] = ivec ;
}
} else {
/*
--------------------------------------------------
the list entries will be copied into ivl's storage
--------------------------------------------------
*/
if ( ivl->sizes[ilist] < isize ) {
/*
--------------------------------------------
old size (might be zero) is not large enough
switch over the storage types
--------------------------------------------
*/
switch ( ivl->type ) {
case IVL_SOLO :
if ( ivl->p_vec[ilist] != NULL ) {
/*
---------------------------------------
free old storage before allocating more
and decrement the total list size
---------------------------------------
*/
IVfree(ivl->p_vec[ilist]) ;
}
ivl->p_vec[ilist] = IVinit(isize, -1) ;
break ;
case IVL_CHUNKED : {
Ichunk *chunk ;
if ( (chunk = ivl->chunk) == NULL
|| (chunk->size - chunk->inuse) < isize ) {
/*
-------------------------------
allocate a new chunk of storage
-------------------------------
*/
ALLOCATE(chunk, struct _Ichunk, 1) ;
if ( isize < ivl->incr ) {
chunk->size = ivl->incr ;
} else {
chunk->size = isize ;
}
chunk->inuse = 0 ;
chunk->base = IVinit(chunk->size, -1) ;
chunk->next = ivl->chunk ;
ivl->chunk = chunk ;
}
/*
--------------------------
set pointer for list ilist
--------------------------
*/
ivl->p_vec[ilist] = chunk->base + chunk->inuse ;
chunk->inuse += isize ;
} break ;
default :
fprintf(stderr, "\n fatal error in IVL_setList(%p,%d,%d,%p)"
"\n you are trying to grow a list but type = %d"
"\n type must be IVL_CHUNKED = 1 or IVL_SOLO = 2\n",
ivl, ilist, isize, ivec, ivl->type) ;
exit(-1) ;
}
}
ivl->tsize += isize - ivl->sizes[ilist] ;
ivl->sizes[ilist] = isize ;
if ( ivec != NULL ) {
/*
--------------------------------
copy the list into ivl's storage
--------------------------------
*/
IVcopy(isize, ivl->p_vec[ilist], ivec) ;
}
}
return ; }
/*--------------------------------------------------------------------*/
/*
----------------------------------------------------------------
set a pointer to a list but don't allocate storage for the list.
this method was needed when we form a subgraph with a boundary.
lists for the interior vertices point into the parent graph,
but lists for the boundary vertices must be allocated and owned.
used only for type = IVL_CHUNKED. at some point in the future we
should rethink the storage semantics for the IVL object.
created -- 95nov11, cca
----------------------------------------------------------------
*/
void
IVL_setPointerToList (
IVL *ivl,
int ilist,
int isize,
int ivec[]
) {
/*
---------------
check the input
---------------
*/
if ( ivl == NULL ) {
fprintf(stderr, "\n fatal error in IVL_setPointerToList(%p,%d,%d,%p)"
"\n bad input, ivl is NULL\n", ivl, ilist, isize, ivec) ;
exit(-1) ;
}
if ( ivl->type != IVL_CHUNKED ) {
fprintf(stderr, "\n fatal error in IVL_setPointerToList(%p,%d,%d,%p)"
"\n this method is only used with type IVL_CHUNKED\n",
ivl, ilist, isize, ivec) ;
exit(-1) ;
}
if ( ilist < 0 ) {
fprintf(stderr, "\n fatal error in IVL_setPointerToList(%p,%d,%d,%p)"
"\n bad input, ilist < 0", ivl, ilist, isize, ivec) ;
exit(-1) ;
}
if ( ilist >= ivl->maxnlist ) {
int newmaxnlist = (int) 1.25*ivl->maxnlist ;
if ( newmaxnlist < 10 ) {
newmaxnlist = 10 ;
}
if ( ilist >= newmaxnlist ) {
newmaxnlist = ilist + 1 ;
}
IVL_setMaxnlist(ivl, newmaxnlist) ;
}
if ( ilist >= ivl->nlist ) {
ivl->nlist = ilist + 1 ;
}
if ( ivl->type == IVL_SOLO && ivl->p_vec[ilist] != NULL ) {
IVfree(ivl->p_vec[ilist]) ;
}
ivl->tsize += isize - ivl->sizes[ilist] ;
ivl->sizes[ilist] = isize ;
ivl->p_vec[ilist] = ivec ;
return ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1