contrib/champ/list.c (238 lines of code) (raw):

/* A* ------------------------------------------------------------------- B* This file contains source code for the PyMOL computer program C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific. D* ------------------------------------------------------------------- E* It is unlawful to modify or remove this copyright notice. F* ------------------------------------------------------------------- G* Please see the accompanying LICENSE file for further information. H* ------------------------------------------------------------------- I* Additional authors of this source file include: -* -* -* Z* ------------------------------------------------------------------- */ #include"os_std.h" #include"os_memory.h" #include"mac.h" #include"vla.h" #include"list.h" /* TEST */ #ifdef _LIST_UT int main(int argc, char *argv[]) { ListInt *int_list,*l; List *hl; int a,b,c,pass,n_cycles; int list[256]; int_list = (ListInt*)ListNew(10,sizeof(ListInt)); hl = (List*)int_list; c = hl->next_avail; l = int_list + c; while(l->link) { printf(" record %p %d link %d\n",int_list,c,l->link); c = l->link; l = int_list + c; } printf(" record %p %d link %d\n",int_list,c,l->link); for(a=0;a<100;a++) { c = ListElemNew(&int_list); printf(" ListElemNew %p %d\n",int_list,c); fflush(stdout); } for(a=0;a<256;a++) list[a]=0; for(pass=0;pass<20;pass++) { printf("pass %d\n",pass); n_cycles = 10000*pass*pass; for(a=0;a<n_cycles;a++) { b = rand()&0xFF; if(rand()&0x1) { c = ListElemNew(&int_list); int_list[c].link = list[b]; list[b] = c; } else { c = list[b]; if(c) { list[b]=int_list[c].link; ListElemFree(int_list,c); } } } printf(" cleaning up\n"); hl = (List*)int_list; c = ListLen(int_list,hl->next_avail); printf(" available %d\n",c); for(a=0;a<256;a++) { b = ListLen(int_list,list[a]); c+=b; ListElemFreeChain(int_list,list[a]); list[a]=0; printf(" list %d len %d exp %d actual %d \n", a,b,c,ListLen(int_list,hl->next_avail)); } } return 0; } #endif /* end unit test */ int ListLen(void *list,int start) { List *I; ListElem *hle = NULL; register int rec_size,len; if(start) { len = 1; I=(List*)list; rec_size = I->rec_size; hle = (ListElem*)(((char*)I)+rec_size*start); while(hle->link) { hle = (ListElem*)(((char*)I)+rec_size*hle->link); len++; } } else len = 0; return len; } void ListPrime(void *list,int start,int stop); int ListGetNAlloc(void *list) { List *I; I = ((List*)list); return(vla_get_size(I)); } int ListElemPush(void *list_ptr_ptr,int elem) { List *I; ListElem *hle; int start,stop; int next; I=*((List**)list_ptr_ptr); if(!I->next_avail) { start = vla_get_size(I); vla_check(I,List,start+1); (*((List**)list_ptr_ptr))=I; stop = vla_get_size(I); ListPrime(I,start,stop); } next = I->next_avail; hle = (ListElem*)(((char*)I)+I->rec_size*next); I->next_avail = hle->link; hle->link = elem; return next; } int ListElemPushInt(ListInt **list,int elem,int value) { elem = ListElemPush(list,elem); (*list)[elem].value=value; return(elem); } int ListElemPopInt(ListInt *list,int elem,int *value) { *value = list[elem].value; elem = ListElemPop(list,elem); return(elem); } int ListElemGetInt(ListInt *list,int elem,int *value) { *value = list[elem].value; elem = list[elem].link; return(elem); } int ListElemPurgeInt(ListInt *list,int start,int value) { int last = 0; int result = start; while(start) { if(list[start].value==value) { if(!last) { result = list[start].link; } else { list[last].link = list[start].link; } ListElemFree(list,start); break; } start = list[start].link; } return(result); } int ListElemNew(void *list_ptr_ptr) { return(ListElemPush(list_ptr_ptr,0)); } int ListElemNewZero(void *list_ptr) { List *I; ListElem *hle; int start,stop; int next; I=*((List**)list_ptr); if(!I->next_avail) { start = vla_get_size(I); vla_check(I,List,start+1); (*((List**)list_ptr))=I; stop = vla_get_size(I); ListPrime(I,start,stop); } next = I->next_avail; hle = (ListElem*)(((char*)I)+I->rec_size*next); I->next_avail = hle->link; os_zero((char*)hle,((char*)hle)+I->rec_size); return next; } void *ListNew(int init_size,int rec_size) { List *I; I = (List*)VLAMalloc(init_size+1,rec_size,5,0); I->rec_size = rec_size; I->next_avail = 0; ListPrime(I,1,init_size+1); return I; } void ListPrime(void *list,int start,int stop) { /* sets up next free entry */ List *I; ListElem *hle; int a,next,rec_size; I = ((List*)list); rec_size = I->rec_size; next = I->next_avail; hle = (ListElem*)(((char*)I)+I->rec_size*(stop-1)); for(a=stop-1;a>=start;a--) { hle->link = next; next = a; hle = (ListElem*)(((char*)hle)-rec_size); } I->next_avail = next; } int ListElemPop(void *list,int elem) { List *I; ListElem *hle; int result; if(elem) { I=(List*)list; hle = (ListElem*)(((char*)I)+I->rec_size*elem); result = hle->link; hle->link = I->next_avail; I->next_avail = elem; } else result=0; return(result); } void ListElemFree(void *list,int elem) { List *I; ListElem *hle; if(elem) { I=(List*)list; hle = (ListElem*)(((char*)I)+I->rec_size*elem); hle->link = I->next_avail; I->next_avail = elem; } } void ListElemFreeChain(void *list,int start) { List *I; ListElem *hle = NULL; register int rec_size; if(start) { I=(List*)list; rec_size = I->rec_size; hle = (ListElem*)(((char*)I)+rec_size*start); while(hle->link) { hle = (ListElem*)(((char*)I)+rec_size*hle->link); } hle->link = I->next_avail; I->next_avail = start; } } void ListFree(void *list) { VLAFree(list); }