diff --git a/source/toy_array.h b/source/toy_array.h index 3deef1e..9c1d370 100644 --- a/source/toy_array.h +++ b/source/toy_array.h @@ -11,3 +11,22 @@ typedef struct Toy_Array { //32 | 64 BITNESS } Toy_Array; //8 | 8 TOY_API Toy_Array* Toy_resizeArray(Toy_Array* array, unsigned int capacity); + +//some useful sizes, could be swapped out as needed +#ifndef TOY_ARRAY_INITIAL_CAPACITY +#define TOY_ARRAY_INITIAL_CAPACITY 8 +#endif + +#ifndef TOY_ARRAY_EXPANSION_RATE +#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 + +//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 diff --git a/source/toy_bucket.h b/source/toy_bucket.h index f5b61f5..90db8cc 100644 --- a/source/toy_bucket.h +++ b/source/toy_bucket.h @@ -20,13 +20,27 @@ TOY_API Toy_Bucket* Toy_allocateBucket(unsigned int capacity); TOY_API void* Toy_partitionBucket(Toy_Bucket** bucketHandle, unsigned int amount); TOY_API void Toy_freeBucket(Toy_Bucket** bucketHandle); -//some useful bucket sizes, could be swapped or ifdef'd as needed +//some useful sizes, could be swapped out as needed +#ifndef TOY_BUCKET_TINY #define TOY_BUCKET_TINY (1024 * 2) +#endif + +#ifndef TOY_BUCKET_SMALL #define TOY_BUCKET_SMALL (1024 * 4) +#endif + +#ifndef TOY_BUCKET_MEDIUM #define TOY_BUCKET_MEDIUM (1024 * 8) +#endif + +#ifndef TOY_BUCKET_LARGE #define TOY_BUCKET_LARGE (1024 * 16) +#endif + +#ifndef TOY_BUCKET_HUGE #define TOY_BUCKET_HUGE (1024 * 32) +#endif -//sizeof(Toy_Bucket) is added internally, so reverse it here +#ifndef TOY_BUCKET_IDEAL #define TOY_BUCKET_IDEAL (TOY_BUCKET_HUGE - sizeof(Toy_Bucket)) - +#endif diff --git a/source/toy_stack.c b/source/toy_stack.c index 04e2513..6e76755 100644 --- a/source/toy_stack.c +++ b/source/toy_stack.c @@ -4,18 +4,15 @@ #include #include -//a good chunk of space - 'count' actually tracks the number of values -#define MIN_CAPACITY 64 - Toy_Stack* Toy_allocateStack() { - Toy_Stack* stack = malloc(MIN_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); + Toy_Stack* stack = malloc(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack)); if (stack == NULL) { - fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, MIN_CAPACITY, (int)(MIN_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack))); + fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a 'Toy_Stack' of %d capacity (%d space in memory)\n" TOY_CC_RESET, TOY_STACK_INITIAL_CAPACITY, (int)(TOY_STACK_INITIAL_CAPACITY * sizeof(Toy_Value) + sizeof(Toy_Stack))); exit(1); } - stack->capacity = MIN_CAPACITY; + stack->capacity = TOY_STACK_INITIAL_CAPACITY; stack->count = 0; return stack; @@ -30,8 +27,8 @@ void Toy_freeStack(Toy_Stack* stack) { } void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value) { - //don't go overboard - limit to 1mb of capacity used - if ((*stackHandle)->count >= 1024 * 1024 / sizeof(Toy_Value)) { + //don't go overboard + if ((*stackHandle)->count >= TOY_STACK_OVERFLOW) { fprintf(stderr, TOY_CC_ERROR "ERROR: Stack overflow\n" TOY_CC_RESET); exit(-1); } @@ -39,7 +36,7 @@ void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value) { //expand the capacity if needed if ((*stackHandle)->count + 1 > (*stackHandle)->capacity) { while ((*stackHandle)->count + 1 > (*stackHandle)->capacity) { - (*stackHandle)->capacity = (*stackHandle)->capacity < MIN_CAPACITY ? MIN_CAPACITY : (*stackHandle)->capacity * 2; + (*stackHandle)->capacity = (*stackHandle)->capacity < TOY_STACK_INITIAL_CAPACITY ? TOY_STACK_INITIAL_CAPACITY : (*stackHandle)->capacity * TOY_STACK_EXPANSION_RATE; } unsigned int newCapacity = (*stackHandle)->capacity; @@ -72,7 +69,7 @@ Toy_Value Toy_popStack(Toy_Stack** stackHandle) { } //shrink if possible - if ((*stackHandle)->count > MIN_CAPACITY && (*stackHandle)->count < (*stackHandle)->capacity / 4) { + if ((*stackHandle)->count > TOY_STACK_INITIAL_CAPACITY && (*stackHandle)->count < (*stackHandle)->capacity * TOY_STACK_CONTRACTION_RATE) { (*stackHandle)->capacity /= 2; unsigned int newCapacity = (*stackHandle)->capacity; diff --git a/source/toy_stack.h b/source/toy_stack.h index 3a9a413..803260e 100644 --- a/source/toy_stack.h +++ b/source/toy_stack.h @@ -16,3 +16,20 @@ TOY_API void Toy_pushStack(Toy_Stack** stackHandle, Toy_Value value); TOY_API Toy_Value Toy_peekStack(Toy_Stack** stackHandle); TOY_API Toy_Value Toy_popStack(Toy_Stack** stackHandle); +//some useful sizes, could be swapped out as needed +#ifndef TOY_STACK_INITIAL_CAPACITY +#define TOY_STACK_INITIAL_CAPACITY 8 +#endif + +#ifndef TOY_STACK_EXPANSION_RATE +#define TOY_STACK_EXPANSION_RATE 2 +#endif + +#ifndef TOY_STACK_CONTRACTION_RATE +#define TOY_STACK_CONTRACTION_RATE (1 / 4) +#endif + +//prevent an infinite expansion, limited to 1MB +#ifndef TOY_STACK_OVERFLOW +#define TOY_STACK_OVERFLOW (1024 * 1024 / sizeof(Toy_Value)) +#endif diff --git a/source/toy_table.c b/source/toy_table.c index d3c14fb..5d1c3fb 100644 --- a/source/toy_table.c +++ b/source/toy_table.c @@ -6,9 +6,6 @@ #include #include -//'count' actually tracks the number of values -#define MIN_CAPACITY 16 - //utils static void probeAndInsert(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) { //make the entry @@ -88,7 +85,7 @@ Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int new } Toy_Table* Toy_allocateTable() { - return Toy_private_adjustTableCapacity(NULL, MIN_CAPACITY); + return Toy_private_adjustTableCapacity(NULL, TOY_TABLE_INITIAL_CAPACITY); } void Toy_freeTable(Toy_Table* table) { @@ -103,8 +100,8 @@ void Toy_insertTable(Toy_Table** tableHandle, Toy_Value key, Toy_Value value) { } //expand the capacity - if ((*tableHandle)->count > (*tableHandle)->capacity * 0.8) { - (*tableHandle) = Toy_private_adjustTableCapacity((*tableHandle), (*tableHandle)->capacity * 2); + if ((*tableHandle)->count > (*tableHandle)->capacity * TOY_TABLE_EXPANSION_THRESHOLD) { + (*tableHandle) = Toy_private_adjustTableCapacity((*tableHandle), (*tableHandle)->capacity * TOY_TABLE_EXPANSION_RATE); } probeAndInsert(tableHandle, key, value); diff --git a/source/toy_table.h b/source/toy_table.h index 4f8ec8e..3f91f07 100644 --- a/source/toy_table.h +++ b/source/toy_table.h @@ -27,3 +27,17 @@ TOY_API void Toy_removeTable(Toy_Table** tableHandle, Toy_Value key); //NOTE: exposed to skip unnecessary allocations within Toy_Scope TOY_API Toy_Table* Toy_private_adjustTableCapacity(Toy_Table* oldTable, unsigned int newCapacity); + +//some useful sizes, could be swapped out as needed +#ifndef TOY_TABLE_INITIAL_CAPACITY +#define TOY_TABLE_INITIAL_CAPACITY 8 +#endif + +#ifndef TOY_TABLE_EXPANSION_RATE +#define TOY_TABLE_EXPANSION_RATE 2 +#endif + +//expand when the contents passes a certain percentage of the capacity +#ifndef TOY_TABLE_EXPANSION_THRESHOLD +#define TOY_TABLE_EXPANSION_THRESHOLD 0.8 +#endif diff --git a/tests/cases/test_scope.c b/tests/cases/test_scope.c index d061df4..ab8a16c 100644 --- a/tests/cases/test_scope.c +++ b/tests/cases/test_scope.c @@ -21,7 +21,7 @@ int test_scope_allocation() { if (scope == NULL || scope->next != NULL || scope->table == NULL || - scope->table->capacity != 16 || + scope->table->capacity != 8 || scope->refCount != 1 || false) @@ -54,27 +54,27 @@ int test_scope_allocation() { scope == NULL || scope->next == NULL || scope->table == NULL || - scope->table->capacity != 16 || + scope->table->capacity != 8 || scope->refCount != 1 || scope->next->next == NULL || scope->next->table == NULL || - scope->next->table->capacity != 16 || + scope->next->table->capacity != 8 || scope->next->refCount != 2 || scope->next->next->next == NULL || scope->next->next->table == NULL || - scope->next->next->table->capacity != 16 || + scope->next->next->table->capacity != 8 || scope->next->next->refCount != 3 || scope->next->next->next->next == NULL || scope->next->next->next->table == NULL || - scope->next->next->next->table->capacity != 16 || + scope->next->next->next->table->capacity != 8 || scope->next->next->next->refCount != 4 || scope->next->next->next->next->next != NULL || scope->next->next->next->next->table == NULL || - scope->next->next->next->next->table->capacity != 16 || + scope->next->next->next->next->table->capacity != 8 || scope->next->next->next->next->refCount != 5 || //refCount includes all ancestors false) @@ -115,17 +115,17 @@ int test_scope_allocation() { scope == NULL || scope->next == NULL || scope->table == NULL || - scope->table->capacity != 16 || + scope->table->capacity != 8 || scope->refCount != 1 || scope->next->next == NULL || scope->next->table == NULL || - scope->next->table->capacity != 16 || + scope->next->table->capacity != 8 || scope->next->refCount != 2 || scope->next->next->next != NULL || scope->next->next->table == NULL || - scope->next->next->table->capacity != 16 || + scope->next->next->table->capacity != 8 || scope->next->next->refCount != 3 || false) @@ -160,19 +160,19 @@ int test_scope_allocation() { scopeBase == NULL || scopeBase->next != NULL || scopeBase->table == NULL || - scopeBase->table->capacity != 16 || + scopeBase->table->capacity != 8 || scopeBase->refCount != 3 || scopeA == NULL || scopeA->next != scopeBase || scopeA->table == NULL || - scopeA->table->capacity != 16 || + scopeA->table->capacity != 8 || scopeA->refCount != 1 || scopeB == NULL || scopeB->next != scopeBase || scopeB->table == NULL || - scopeB->table->capacity != 16 || + scopeB->table->capacity != 8 || scopeB->refCount != 1 || scopeA->next != scopeB->next || //double check @@ -212,20 +212,20 @@ int test_scope_allocation() { scopeA == NULL || scopeA->next != NULL || scopeA->table == NULL || - scopeA->table->capacity != 16 || + scopeA->table->capacity != 8 || scopeA->refCount != 2 || //scopeB still exists in memory until scopeC is popped scopeB == NULL || scopeB->next != scopeA || scopeB->table == NULL || - scopeB->table->capacity != 16 || + scopeB->table->capacity != 8 || scopeB->refCount != 1 || scopeC == NULL || scopeC->next != scopeB || scopeC->table == NULL || - scopeC->table->capacity != 16 || + scopeC->table->capacity != 8 || scopeC->refCount != 1 || false) @@ -259,19 +259,19 @@ int test_scope_allocation() { scopeA == NULL || scopeA->next != NULL || scopeA->table == NULL || - scopeA->table->capacity != 16 || + scopeA->table->capacity != 8 || scopeA->refCount != 3 || scopeB == NULL || scopeB->next != scopeA || scopeB->table == NULL || - scopeB->table->capacity != 16 || + scopeB->table->capacity != 8 || scopeB->refCount != 1 || scopeB == NULL || scopeB->next != scopeA || scopeB->table == NULL || - scopeB->table->capacity != 16 || + scopeB->table->capacity != 8 || scopeB->refCount != 1 || scopeB == scopeCopy || @@ -335,7 +335,7 @@ int test_scope_elements() { if (scope == NULL || scope->next != NULL || scope->table == NULL || - scope->table->capacity != 16 || + scope->table->capacity != 8 || scope->refCount != 1 || TOY_VALUE_IS_INTEGER(result) != true || @@ -360,7 +360,7 @@ int test_scope_elements() { if (scope == NULL || scope->next != NULL || scope->table == NULL || - scope->table->capacity != 16 || + scope->table->capacity != 8 || scope->refCount != 1 || TOY_VALUE_IS_FLOAT(resultTwo) != true || diff --git a/tests/cases/test_stack.c b/tests/cases/test_stack.c index 2d8da2b..1b84ef5 100644 --- a/tests/cases/test_stack.c +++ b/tests/cases/test_stack.c @@ -11,7 +11,7 @@ int test_stack_basics() { //check if it worked if ( stack == NULL || - stack->capacity != 64 || + stack->capacity != 8 || stack->count != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: failed to allocate Toy_Stack\n" TOY_CC_RESET); @@ -32,7 +32,7 @@ int test_stack_basics() { Toy_pushStack(&stack, TOY_VALUE_FROM_INTEGER(420)); if ( stack == NULL || - stack->capacity != 64 || + stack->capacity != 8 || stack->count != 3) { fprintf(stderr, TOY_CC_ERROR "ERROR: failed to push Toy_Stack\n" TOY_CC_RESET); @@ -55,7 +55,7 @@ int test_stack_basics() { Toy_Value top2 = Toy_popStack(&stack); if ( stack == NULL || - stack->capacity != 64 || + stack->capacity != 8 || stack->count != 2 || TOY_VALUE_IS_INTEGER(top2) != true || TOY_VALUE_AS_INTEGER(top2) != 420) diff --git a/tests/cases/test_table.c b/tests/cases/test_table.c index 93a3853..a5e3429 100644 --- a/tests/cases/test_table.c +++ b/tests/cases/test_table.c @@ -36,7 +36,7 @@ int test_table_simple_insert_lookup_and_remove() { //insert Toy_insertTable(&table, key, value); if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 1) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to insert into a table\n" TOY_CC_RESET); @@ -49,7 +49,7 @@ int test_table_simple_insert_lookup_and_remove() { //check lookup if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 1 || TOY_VALUE_AS_INTEGER(result) != 42) { @@ -63,7 +63,7 @@ int test_table_simple_insert_lookup_and_remove() { //check remove if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to remove from a table\n" TOY_CC_RESET); @@ -97,7 +97,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 1 || TEST_ENTRY_STATE(7, 1, 42, 0) @@ -124,7 +124,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 3 || TEST_ENTRY_STATE(7, 1, 42, 0) || @@ -154,7 +154,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 4 || TEST_ENTRY_STATE(7, 1, 42, 0) || @@ -184,7 +184,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 3 || TEST_ENTRY_STATE(15, 17, 42, 0) || @@ -216,7 +216,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 3 || TOY_VALUE_IS_INTEGER(result) != true || @@ -245,7 +245,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 4 || TEST_ENTRY_STATE(15, 17, 42, 0) || @@ -279,7 +279,7 @@ int test_table_contents_no_expansion() { //check the state if (table == NULL || - table->capacity != 16 || + table->capacity != 8 || table->count != 3 || TEST_ENTRY_STATE(15, 17, 42, 0) || diff --git a/.notes/hash_generator_1.c b/tests/standalone/hash_generator_1.c similarity index 73% rename from .notes/hash_generator_1.c rename to tests/standalone/hash_generator_1.c index 0265cfa..9555537 100644 --- a/.notes/hash_generator_1.c +++ b/tests/standalone/hash_generator_1.c @@ -1,4 +1,4 @@ -https://www.programiz.com/c-programming/online-compiler/ +//https://www.programiz.com/c-programming/online-compiler/ #include static unsigned int hashUInt(unsigned int x) { @@ -11,8 +11,8 @@ static unsigned int hashUInt(unsigned int x) { int main() { //print the index/hash pairs for (unsigned int i = 0; i < 100; i++) { - printf("{%u:%u}\n", i, hashUInt(i) % 16); + printf("{%u:%u}\n", i, hashUInt(i)); } return 0; -} \ No newline at end of file +} diff --git a/.notes/hash_generator_2.c b/tests/standalone/hash_generator_2.c similarity index 90% rename from .notes/hash_generator_2.c rename to tests/standalone/hash_generator_2.c index ebe0bc9..0244104 100644 --- a/.notes/hash_generator_2.c +++ b/tests/standalone/hash_generator_2.c @@ -1,4 +1,4 @@ -https://www.programiz.com/c-programming/online-compiler/ +//https://www.programiz.com/c-programming/online-compiler/ #include static unsigned int hashUInt(unsigned int x) { @@ -20,4 +20,4 @@ int main() { } return 0; -} \ No newline at end of file +}