/* -*- mode: C; tab-width:8; c-basic-offset:8 -*- * vi:set ts=8: * * al_rctree.h * * Stuff related to the rctree data structure. */ #include "al_debug.h" #include "al_config.h" #include "al_rctree.h" #include "al_siteconfig.h" #include #include #include /* * AL_RcTreeNodes are used to help manage AL_rctrees. */ typedef struct _AL_RcTreeNode { ALuint size; ALuint freeslots; AL_rctree **data; } AL_RcTreeNode; /* * rlist is the data structure we use to manage AL_rcTreeNodes. */ static AL_RcTreeNode rlist = { 0, 0, NULL }; /* * rlist_add_rctree( AL_rctree *node ) * * Adds a reference to node to the rlist. */ static void rlist_add_rctree(AL_rctree *node); /* * rlist_delete_rctree( AL_rctree *node ) * * Removes a reference to node from the rlist. */ static void rlist_delete_rctree( AL_rctree *node ); /* * rlist_realloc( void ) * * Increases the size of rlist. */ static void rlist_realloc( void ); /* * _alRcTreeAlloc( void ) * * Creates, initializes and returns an AL_rctree. */ AL_rctree *_alRcTreeAlloc( void ) { AL_rctree *retval; retval = malloc( sizeof *retval ); if(retval == NULL) { /* _alDCSetError(AL_NO_MEMORY); */ return NULL; } memset(retval, 0, sizeof *retval); rlist_add_rctree( retval ); retval->type = ALRC_INVALID; retval->data.proc = 0; retval->data.ccell.car = NULL; retval->data.ccell.cdr = NULL; return retval; } /* * _alRcTreeFree( AL_rctree *node ) * * Finalizes and deallocates an AL_rctree node, removing the rlist reference * at the same time. */ void _alRcTreeFree( AL_rctree *node ) { if(node == NULL) { return; } if( node->type == ALRC_CONSCELL ) { _alRcTreeFree( node->data.ccell.car ); _alRcTreeFree( node->data.ccell.cdr ); } /* remove reference from our list */ rlist_delete_rctree( node ); free( node ); return; } /* * _alRcTreeDestroyAll( void ) * * Deallocates any and all AL_rctree objects creates thus far. */ void _alRcTreeDestroyAll( void ) { ALuint i; for(i = 0; i < rlist.size; i++) { if(rlist.data[i] == NULL) { continue; } free(rlist.data[i]); } free(rlist.data); rlist.data = NULL; rlist.size = 0; rlist.freeslots = 0; return; } /* * rlist_add_rctree( AL_rctree *node ) * * Adds a reference to node to the rlist. */ static void rlist_add_rctree( AL_rctree *node ) { ALuint i; if(rlist.freeslots <= 0) { rlist_realloc(); } for(i = 0; i < rlist.size; i++) { if(rlist.data[i] == NULL) { rlist.freeslots--; rlist.data[i] = node; return; } } /* weird. Do something here. */ assert(0); return; } /* * rlist_add_rctree( AL_rctree *node ) * * Adds a reference to node to the rlist. */ static void rlist_delete_rctree( AL_rctree *node ) { ALuint i; for(i = 0; i < rlist.size; i++) { if(rlist.data[i] == node) { rlist.freeslots++; rlist.data[i] = NULL; return; } } /* not found */ return; } /* * rlist_realloc( void ) * * Increases the size of rlist. */ static void rlist_realloc( void ) { ALuint newsize = rlist.size * 2 + 1; ALuint i; void *temp; temp = realloc( rlist.data, newsize * sizeof *rlist.data ); if(temp == NULL) { assert(0); return; } rlist.data = temp; for(i = rlist.size; i < newsize; i++) { rlist.data[i] = NULL; } rlist.freeslots += newsize - rlist.size; rlist.size = newsize; return; }