# HG changeset patch # User Me # Date 1288501952 25200 # Node ID f35e64d7a42be29c1c5f56166e07912c9b1fd0c9 # Parent 8473c52c6f0e47c87b7eac0e3d1ec8174798cc77 Working version used for probes in Master Env diff -r 8473c52c6f0e -r f35e64d7a42b DynArray.c --- a/DynArray.c Sun Sep 12 12:10:25 2010 -0700 +++ b/DynArray.c Sat Oct 30 22:12:32 2010 -0700 @@ -9,61 +9,137 @@ #include #include +#include "DynArray.h" -/*make a struct with the sizes and a pointer to the - * array, but hide a reverse pointer at the front of the array that - * points back to the vector struct -- that way, can pass around the - * array when doing work on elements, but when need to increase size, - * get pointer to vector struct and use that, which will change the - * ptr to the array in the vector struc, and return the new pointer.. - * so from the point of changing size on, have the correct array ptr, - * and also all other places that initiate a sequence later will get - * the array ptr from the vector struct at the sequence start.. - */ -bool8 -addToVect( Vector *vect, void *ptrToElem ) - { int32 numPtrsInVect, sizeOfVect; -/* - numPtrsInVect = *(vect -1); //num ptrs is "hidden" in front - sizeOfVect = *(vect -2); -*/ - numPtrsInVect = vect->numPtrsInArray; - sizeOfVect = vect->sizeOfArray; +DynArrayInfo * +makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ) + { DynArrayInfo *info; - if( numPtrsInVect >= sizeOfVect ) return FALSE; + info = malloc( sizeof(DynArrayInfo) ); - vect->arrayOfPtrs[numPtrsInVect] = ptrToElem; - vect->numPtrsInArray++; + info->addrOfPtrToArray = addrOfPtrToArray; + info->sizeOfArray = sizeOfArray; + info->numInArray = 0; } -void ** -increaseSizeOfVect( Vector *vect ) - { int32 oldSizeOfArray, newSizeOfArray, i; +DynArrayInfo * +makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ) + { DynArrayInfo *info; + + info = malloc( sizeof(DynArrayInfo) ); + + info->addrOfPtrToArray = addrOfPtrToArray; + + *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) ); + info->sizeOfArray = sizeOfArray; + info->numInArray = 0; + } + + +/*A dynamic array is same as any other array, but add a DynArrayInfo next + * to it. Accesses and updates of array indexes are done normally, it's + * only when add a new element into array that use the extra info. + * An add can cause the pointer to the normal array to change.. so must + * be protected to single VP at a time. + * + *Only need to use this Fn when need a new index, higher than any previous + */ +int32 +addToDynArray( void *value, DynArrayInfo *info ) + { int32 numInArray, sizeOfArray; + void **array; + + numInArray = info->numInArray; + sizeOfArray = info->sizeOfArray; + + if( numInArray >= sizeOfArray ) + { + increaseSizeOfDynArrayTo( info, sizeOfArray * 2 ); + } + + array = *(info->addrOfPtrToArray); + array[ numInArray ] = value; + info->numInArray++; + + return numInArray; //pre-incr value is the index put value into + } + + +/*Use this when know how many things going to add in -- then can do this + * once and use as normal array afterwards. If later add another chunk, + * do this again. Note, this makes new size be just big enough to hold + * highest index, so will do a linear number of copies if use only this. + *To cut down on number of copies, can use the increaseSizeTo Fn to + * exponentially increase size.. + */ +void +makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ) + { + if( info->sizeOfArray <= highestIndex ) + { + increaseSizeOfDynArrayTo( info, highestIndex + 1 ); + } + info->numInArray = highestIndex + 1; + } + + +/*Only use this if certain new size is bigger than current size + */ +void +increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ) + { int32 oldSizeOfArray, i; void **newArray, **oldArray; - oldSizeOfArray = vect->sizeOfArray; - newSizeOfArray = oldSizeOfArray * 2; - oldArray = vect->arrayOfPtrs; - newArray = malloc( (newSizeOfArray + 1) * sizeof(void *) ); - *newArray = vect; - newArray++; + oldSizeOfArray = info->sizeOfArray; + if( newSize <= oldSizeOfArray ) return; + + oldArray = *(info->addrOfPtrToArray); + newArray = malloc( newSize * sizeof(void *) ); + for( i = 0; i < oldSizeOfArray; i++ ) { newArray[i] = oldArray[i]; } - vect->arrayOfPtrs = newArray; - vect->sizeOfArray = newSizeOfArray; + *(info->addrOfPtrToArray) = newArray; //change location of array-ptr + info->sizeOfArray = newSize; - free( oldArray -1 ); - return newArray; + free( oldArray ); } -/* -bool8 -forAllInVectDo( ptrToFnTakesVectElemAsVoid* ) + +/* Frees the array, plus the info + */ +void +freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ) { - return success; + forAllInDynArrayDo( info, freeFnPtr ); + free( *(info->addrOfPtrToArray) ); + free( info ); } -*/ + +/* Only frees the info + */ +void +freeDynArrayFlat( DynArrayInfo *info ) + { + free( info ); + } + + +/*The function has a fixed prototype: takes a void * returns void + * So, the function has to internally cast void * to whatever data struc.. + */ +void +forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ) + { int32 idx; + void **array; + + array = *(info->addrOfPtrToArray); + for( idx = 0; idx < info->numInArray; idx++ ) + { + (*fnPtr)(array[idx]); + } + } + diff -r 8473c52c6f0e -r f35e64d7a42b DynArray.h --- a/DynArray.h Sun Sep 12 12:10:25 2010 -0700 +++ b/DynArray.h Sat Oct 30 22:12:32 2010 -0700 @@ -5,23 +5,53 @@ * Created on May 14, 2010, 3:08 PM */ -#ifndef _VECTOR_H -#define _VECTOR_H +#ifndef _DYNARRAY_H +#define _DYNARRAY_H -//Doing one special cheat -- hiding a back-ptr in front of array +#include "../VMS_primitive_data_types.h" + + + //A dynamic array is same as any other array, but add a DynArrayInfo next + // to it. Accesses and updates of array indexes are done normally, it's + // only when add a new element into array that use the extra info. + // An add can cause the pointer to the normal array to change.. so must + // be protected to single VP at a time. typedef struct { - void **arrayOfPtrs; - int numPtrsInArray; - int sizeOfArray; + void ***addrOfPtrToArray; //addr of array of ptrs == triple * + int32 numInArray; + int32 sizeOfArray; } -Vector; +DynArrayInfo; -Vector *createVect ( int32 initialSizeOfArray ); -Vector *increaseSizeOfVect( Vector *vect ); -bool8 addToVect ( void *ptrToAdd, Vector *vect ); -bool8 removeLastInVect ( Vector *vect ); +DynArrayInfo * +makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ); +DynArrayInfo * +makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ); -#endif /* _VECTOR_H */ +int32 +addToDynArray( void *value, DynArrayInfo *info ); +void +makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ); + +void +increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ); + +typedef void (*FreeFnPtr) ( void * ); //fn has to cast void * to whatever + +void +freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ); + +void +freeDynArrayFlat( DynArrayInfo *info ); + + +typedef void (*DynArrayFnPtr) ( void * ); //fn has to cast void * + +void +forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ); + +#endif /* _DYNARRAY_H */ +