Reworking structures for easy testing, read more

I was reworking bits of the containers to address issue #131, then
realized that the table's tests depended on a specific initial size. I'm
too buggered to finish it tonight, so I'll fix it tomorrow.
This commit is contained in:
2024-10-18 20:48:33 +11:00
parent c3ee92fcef
commit 98ea0e5884
11 changed files with 115 additions and 57 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -4,18 +4,15 @@
#include <stdio.h>
#include <stdlib.h>
//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;

View File

@@ -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

View File

@@ -6,9 +6,6 @@
#include <stdlib.h>
#include <string.h>
//'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);

View File

@@ -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