diff --git a/source/toy_array.h b/source/toy_array.h index 0665765..47da53b 100644 --- a/source/toy_array.h +++ b/source/toy_array.h @@ -21,26 +21,6 @@ TOY_API Toy_Array* Toy_resizeArray(Toy_Array* array, unsigned int capacity); #define TOY_ARRAY_EXPANSION_RATE 2 #endif -//quick allocate -#ifndef TOY_ARRAY_ALLOCATE -#define TOY_ARRAY_ALLOCATE() Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY) -#endif - -//quick free -#ifndef TOY_ARRAY_FREE -#define TOY_ARRAY_FREE(array) (array = Toy_resizeArray(array, 0)) -#endif - -//one line to expand the array -#ifndef TOY_ARRAY_EXPAND -#define TOY_ARRAY_EXPAND(array) (array = (array != NULL && (array)->count + 1 > (array)->capacity ? Toy_resizeArray(array, (array)->capacity * TOY_ARRAY_EXPANSION_RATE) : array)) -#endif - -//quick push back -#ifndef TOY_ARRAY_PUSHBACK -#define TOY_ARRAY_PUSHBACK(array, value) (TOY_ARRAY_EXPAND(array), (array)->data[(array)->count++] = (value)) -#endif - //TODO: array.getLength() //TODO: array.pushFront(x) //TODO: array.pushBack(x) diff --git a/source/toy_stack.c b/source/toy_stack.c index 6356ab5..22d12e2 100644 --- a/source/toy_stack.c +++ b/source/toy_stack.c @@ -31,7 +31,7 @@ void Toy_freeStack(Toy_Stack* stack) { void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value) { //don't go overboard - if ((*stackHandle)->count >= TOY_STACK_OVERFLOW) { + if ((*stackHandle)->count >= TOY_STACK_OVERFLOW_THRESHOLD) { fprintf(stderr, TOY_CC_ERROR "ERROR: Stack overflow\n" TOY_CC_RESET); exit(-1); } @@ -72,9 +72,9 @@ Toy_Value Toy_popStack(Toy_Stack** stackHandle) { } //shrink if possible - if ((*stackHandle)->count > TOY_STACK_INITIAL_CAPACITY && (*stackHandle)->count < (*stackHandle)->capacity * TOY_STACK_CONTRACTION_THRESHOLD) { - (*stackHandle)->capacity /= 2; - unsigned int newCapacity = (*stackHandle)->capacity; + if ((*stackHandle)->capacity > TOY_STACK_INITIAL_CAPACITY && (*stackHandle)->count <= (*stackHandle)->capacity / TOY_STACK_CONTRACTION_THRESHOLD) { + (*stackHandle)->capacity /= TOY_STACK_CONTRACTION_THRESHOLD; + unsigned int newCapacity = (*stackHandle)->capacity; //cache for the msg (*stackHandle) = realloc((*stackHandle), (*stackHandle)->capacity * sizeof(Toy_Value) + sizeof(Toy_Stack)); diff --git a/source/toy_stack.h b/source/toy_stack.h index 9d10d57..423e28d 100644 --- a/source/toy_stack.h +++ b/source/toy_stack.h @@ -26,10 +26,10 @@ TOY_API Toy_Value Toy_popStack(Toy_Stack** stackHandle); #endif #ifndef TOY_STACK_CONTRACTION_THRESHOLD -#define TOY_STACK_CONTRACTION_THRESHOLD (1 / 4) +#define TOY_STACK_CONTRACTION_THRESHOLD 4 // this integer means 'shrink when count drops below one-forth of capacity' #endif //prevent an infinite expansion, limited to 1MB -#ifndef TOY_STACK_OVERFLOW -#define TOY_STACK_OVERFLOW (1024 * 1024 / sizeof(Toy_Value)) +#ifndef TOY_STACK_OVERFLOW_THRESHOLD +#define TOY_STACK_OVERFLOW_THRESHOLD (1024 * 1024 / sizeof(Toy_Value) - sizeof(Toy_Stack)) #endif diff --git a/source/toy_table.c b/source/toy_table.c index d0a12e8..6f5ed2a 100644 --- a/source/toy_table.c +++ b/source/toy_table.c @@ -107,7 +107,7 @@ void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) { } //expand the capacity - if ((*tableHandle)->count > (*tableHandle)->capacity * TOY_TABLE_EXPANSION_THRESHOLD) { + if ((*tableHandle)->count >= (*tableHandle)->capacity * TOY_TABLE_EXPANSION_THRESHOLD) { (*tableHandle) = Toy_private_adjustTableCapacity((*tableHandle), (*tableHandle)->capacity * TOY_TABLE_EXPANSION_RATE); } diff --git a/source/toy_table.h b/source/toy_table.h index 72cc280..d395bfd 100644 --- a/source/toy_table.h +++ b/source/toy_table.h @@ -38,7 +38,7 @@ TOY_API Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned #define TOY_TABLE_EXPANSION_RATE 2 #endif -//expand when the contents passes a certain percentage of the capacity +//expand when the contents passes a certain percentage (80%) of the capacity #ifndef TOY_TABLE_EXPANSION_THRESHOLD -#define TOY_TABLE_EXPANSION_THRESHOLD 0.8 +#define TOY_TABLE_EXPANSION_THRESHOLD 0.8f #endif diff --git a/source/toy_value.c b/source/toy_value.c index 746158d..a78ae32 100644 --- a/source/toy_value.c +++ b/source/toy_value.c @@ -139,7 +139,7 @@ void Toy_freeValue(Toy_Value value) { Toy_freeValue(ptr->data[i]); } - TOY_ARRAY_FREE(ptr); + Toy_resizeArray(ptr, 0); break; } diff --git a/tests/cases/test_array.c b/tests/cases/test_array.c index 21a2c77..28ab371 100644 --- a/tests/cases/test_array.c +++ b/tests/cases/test_array.c @@ -6,30 +6,30 @@ int test_array(void) { //test allocation and free { - Toy_Array* array = TOY_ARRAY_ALLOCATE(); - TOY_ARRAY_FREE(array); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); + array = Toy_resizeArray(array, 0); } //test initial data { - Toy_Array* array = TOY_ARRAY_ALLOCATE(); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); //check you can access the memory array->data[1] = TOY_VALUE_FROM_INTEGER(42); - TOY_ARRAY_FREE(array); + array = Toy_resizeArray(array, 0); } //test multiple arrays (no overlaps or conflicts) { - Toy_Array* array1 = TOY_ARRAY_ALLOCATE(); - Toy_Array* array2 = TOY_ARRAY_ALLOCATE(); + Toy_Array* array1 = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); + Toy_Array* array2 = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); array1->data[1] = TOY_VALUE_FROM_INTEGER(42); array2->data[1] = TOY_VALUE_FROM_INTEGER(42); - TOY_ARRAY_FREE(array1); - TOY_ARRAY_FREE(array2); + Toy_resizeArray(array1, 0); + Toy_resizeArray(array2, 0); } return 0; diff --git a/tests/cases/test_stack.c b/tests/cases/test_stack.c index cb3e611..ac0bee6 100644 --- a/tests/cases/test_stack.c +++ b/tests/cases/test_stack.c @@ -83,11 +83,11 @@ int test_stack_basics(void) { } int test_stack_stress(void) { - //stress the stack's contents + //stress the stack { Toy_Stack* stack = Toy_allocateStack(); - //allocate 500 values + //push 500 values for (int i = 0; i < 500; i++) { Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(i)); } @@ -98,11 +98,28 @@ int test_stack_stress(void) { stack->capacity != 512 || stack->count != 500) { - fprintf(stderr, TOY_CC_ERROR "ERROR: failed to stress the Toy_Stack\n" TOY_CC_RESET); + fprintf(stderr, TOY_CC_ERROR "ERROR: failed to stress push the Toy_Stack\n" TOY_CC_RESET); Toy_freeStack(stack); return -1; } + //pop each value + while(stack->count > 0) { + Toy_popStack(&stack); //ignore the results + } + + //check if it worked + if ( + stack == NULL || + stack->capacity != TOY_STACK_INITIAL_CAPACITY || //reset to initial capacity + stack->count != 0) + { + fprintf(stderr, TOY_CC_ERROR "ERROR: failed to stress pop the Toy_Stack\n" TOY_CC_RESET); + Toy_freeStack(stack); + return -1; + } + + //cleanup Toy_freeStack(stack); } diff --git a/tests/cases/test_value.c b/tests/cases/test_value.c index 4dad104..4759334 100644 --- a/tests/cases/test_value.c +++ b/tests/cases/test_value.c @@ -9,6 +9,10 @@ #include #include +//util macros +#define TOY_ARRAY_EXPAND(array) (array = (array != NULL && (array)->count + 1 > (array)->capacity ? Toy_resizeArray(array, (array)->capacity * TOY_ARRAY_EXPANSION_RATE) : array)) +#define TOY_ARRAY_PUSHBACK(array, value) (TOY_ARRAY_EXPAND(array), (array)->data[(array)->count++] = (value)) + int test_value_creation(void) { //test for the correct size { @@ -68,7 +72,7 @@ int test_value_creation(void) { //test creating arrays { //setup - Toy_Array* array = TOY_ARRAY_ALLOCATE(); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(8891)); @@ -84,12 +88,12 @@ int test_value_creation(void) { ) { fprintf(stderr, TOY_CC_ERROR "ERROR: 'array' value failed\n" TOY_CC_RESET); - TOY_ARRAY_FREE(array); + Toy_resizeArray(array, 0); return -1; } //cleanup - TOY_ARRAY_FREE(array); + Toy_resizeArray(array, 0); } return 0; @@ -139,7 +143,7 @@ int test_value_copying(void) { //test copy arrays { //setup - Toy_Array* array = TOY_ARRAY_ALLOCATE(); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(8891)); @@ -186,7 +190,7 @@ int test_value_hashing(void) { //skip float Toy_Value s = TOY_VALUE_FROM_STRING(Toy_createString(&bucket, "Hello world")); - Toy_Array* array = TOY_ARRAY_ALLOCATE(); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(8891)); @@ -202,13 +206,13 @@ int test_value_hashing(void) { ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unexpected hash of a value\n" TOY_CC_RESET); - TOY_ARRAY_FREE(array); + Toy_resizeArray(array, 0); Toy_freeBucket(&bucket); return -1; } //cleanup - TOY_ARRAY_FREE(array); + Toy_resizeArray(array, 0); Toy_freeBucket(&bucket); } @@ -259,14 +263,14 @@ int test_value_equality(void) { //again with arrays { //setup - Toy_Array* array1 = TOY_ARRAY_ALLOCATE(); + Toy_Array* array1 = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array1, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array1, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array1, TOY_VALUE_FROM_INTEGER(8891)); Toy_Value value1 = TOY_VALUE_FROM_ARRAY(array1); - Toy_Array* array2 = TOY_ARRAY_ALLOCATE(); + Toy_Array* array2 = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array2, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array2, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array2, TOY_VALUE_FROM_INTEGER(8891)); @@ -512,7 +516,7 @@ int test_value_stringify(void) { Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_SMALL); //setup - Toy_Array* array = TOY_ARRAY_ALLOCATE(); + Toy_Array* array = Toy_resizeArray(NULL, TOY_ARRAY_INITIAL_CAPACITY); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(42)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(69)); TOY_ARRAY_PUSHBACK(array, TOY_VALUE_FROM_INTEGER(8891)); @@ -525,14 +529,14 @@ int test_value_stringify(void) { { fprintf(stderr, TOY_CC_ERROR "ERROR: stringify array '[42,69,8891]' failed\n" TOY_CC_RESET); free(buffer); - TOY_ARRAY_FREE(array); + array = Toy_resizeArray(array, 0); Toy_freeBucket(&bucket); return -1; } //cleanup free(buffer); - TOY_ARRAY_FREE(array); + Toy_resizeArray(array, 0); Toy_freeBucket(&bucket); }