diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index da65e01..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,12 +0,0 @@ -# AI Agent Rules - -## AI Usage Policy (from src/main.c:46-55) -- Absolutely no AI is permitted when writing source code. -- AI is allowed to generate tests for code; however, test results and the AI cannot give code as to how to fix the source aside from pseudo code that has no clear relation to the source aside from a recreation of the problem in a different way entirely. -- Source code comments are for the author's short-term memory and do not affect AI behavior. - -## Project Code Conventions -- **Formatting**: Follow `.clang-format` (Google-based style, tabs (width 8), Allman braces, short functions/if/loops can be single-line) -- **Linting**: Follow `.clang-tidy` (bugprone, concurrency, misc, modernize, performance, readability, portability checks; `lower_case` naming for variables and functions) -- **Build**: C23 standard, CMake 3.16+ -- **Naming**: Variables and functions use `lower_case` (enforced by clang-tidy) diff --git a/main_test b/main_test deleted file mode 100755 index b2fb583..0000000 Binary files a/main_test and /dev/null differ diff --git a/src/main.c b/src/main.c index 7e84fe9..cfed49d 100644 --- a/src/main.c +++ b/src/main.c @@ -7,12 +7,8 @@ /* * All functions needed - * assign() Fills a vector with multiple values - * data() Returns a pointer to the block of memory where a vector's elements are - * stored - * erase() Removes a number of elements from a vector + * assign() Fills a vector with multiple values stored * insert() Inserts a number of elements into a vector - * max_size() Returns the maximum number of elements that a * vector can have pop_back() Removes the last element of a vector rbegin() * Returns a reverse iterator pointing to the last element of a vector rend() * Returns a reverse iterator pointing to a position right before the first @@ -31,16 +27,6 @@ * String */ -/* Absolutely no AI is permitted when writing code. - * AI is and can be used to generate tests for code; however, the test results - * and the AI can not give code as to how to fix the source aside from psuedo - * code that has no clear relation to the source aside from a recreation of the - * problem in a different way entirely - * - * Any code comments below are just used for my purposes with short term memory. - * It also serves as a way to remember what needs to be changed to be readable - * and not need comments in the first place. - */ #include #include #include @@ -68,6 +54,26 @@ create(const Vec8_t* input) return vec; } +Vec8_t* +shrink_to_fit(const Vec8_t* ptr) { + /* Create a new empty heap + * copy current ptr values + * realloc heap to current size + * + * */ +} + +char* +data(const Vec8_t* ptr) { + if(ptr == nullptr || ptr->arr == nullptr) return nullptr; + return &ptr->arr[0]; +} + +size_t +max_size(const Vec8_t* ptr) { + return ptr->capacity; +} + void delete(Vec8_t* vec) { @@ -114,17 +120,6 @@ at(const Vec8_t* vec, const int idx) return -1; } -// 1. Single erase (line 117-126): -// - size-- before memmove → wrong copy size -// - arr[iter] = 0 after memmove → zeros shifted element -// - Result: a b \0 e f g h i j (after erasing index 2 from a b c d e f g h i j) -// 2. Range erase (line 128-140): -// - Bounds check uses && (should be ||) -// - diff = iter_end - iter_start (off-by-one for inclusive range) -// - memmove uses iter_end not iter_end+1 -// - Zeroing loop zeros wrong positions -// - Result: a b \0 \0 g h i j (size=8, should be 7) - __attribute__((overloadable)) Vec8_t* erase(Vec8_t* vec, const size_t iter) { if(vec == nullptr) return nullptr; @@ -140,7 +135,7 @@ __attribute__((overloadable)) Vec8_t* erase(Vec8_t* vec, const size_t iter_start, const size_t iter_end) { if(vec == nullptr) return nullptr; if(vec->arr == nullptr) return nullptr; - if(iter_start < 0 || iter_end >= vec->size) return nullptr; + if(iter_start < 0 || iter_end > vec->size) return nullptr; if(iter_start >= iter_end) return nullptr; size_t diff = iter_end - iter_start; memmove(&vec->arr[iter_start], &vec->arr[iter_end], (vec->size - iter_end) * sizeof(char)); @@ -239,21 +234,11 @@ main() vec = add_back(&vec, '6'); size_t size = vec.size; - for (int i = 0; i < size; i++) { - if(vec.arr[i] == 0) printf("0"); - printf("%c ", vec.arr[i]); - } - printf("\n"); - // print_vec(&vec); - vec = *erase(&vec, begin(&vec) + 2); - // vec = *erase(&vec, begin(&vec) + 2, begin(&vec) + 4); - for (int i = 0; i < size; i++) { - if(vec.arr[i] == 0) printf("0"); - printf("%c ", vec.arr[i]); - } - printf("\n"); - // print_vec(&vec); - // printf("%c", at(nullptr, 0)); + print_vec(&vec); + // vec = *erase(&vec, begin(&vec) + 2); + vec = *erase(&vec, begin(&vec) + 2, begin(&vec) + 4); + print_vec(&vec); + printf("%p", data(&vec)); delete(&vec); return 0; diff --git a/stress_erase_test b/stress_erase_test deleted file mode 100755 index 1d8ba49..0000000 Binary files a/stress_erase_test and /dev/null differ diff --git a/tests/cpu_stress b/tests/cpu_stress deleted file mode 100755 index 06a92d7..0000000 Binary files a/tests/cpu_stress and /dev/null differ diff --git a/tests/cpu_stress.c b/tests/cpu_stress.c deleted file mode 100644 index 88f020f..0000000 --- a/tests/cpu_stress.c +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = 4 }; - if(input == nullptr) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) free(vec->arr); - vec->arr = nullptr; -} - -char at(Vec8_t* vec, int idx) { - if (vec == nullptr) return -2; - if (vec->arr == nullptr) return -3; - if (vec->size <= idx) return -4; - if (vec != nullptr && vec->arr != nullptr && vec->size > idx) { - return vec->arr[idx]; - } - return -1; -} - -int begin(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return 0; - return -1; -} - -int end(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return (int)(vec->size - 1); - return -1; -} - -char front(Vec8_t* vec) { - return at(vec, 0); -} - -char back(Vec8_t* vec) { - if (vec) return at(vec, (int)vec->size - 1); - return -1; -} - -Vec8_t add_back(Vec8_t* vec, char val) { - Vec8_t ret = { .arr = nullptr, .capacity = 0, .size = 0 }; - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - return ret; -} - -double time_diff(struct timespec start, struct timespec end_t) { - return (end_t.tv_sec - start.tv_sec) + (end_t.tv_nsec - start.tv_nsec) / 1e9; -} - -int main() { - struct timespec start, end_t; - Vec8_t vec; - - printf("=== CPU Stress Tests ===\n\n"); - - // Test 1: Rapid fire inserts (tight loop) - printf("--- Test 1: Rapid Fire (100M tight loop) ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 100000000; i++) { - vec = add_back(&vec, (char)i); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t1 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t1); - printf(" Rate: %.0f/sec\n", 100000000.0 / t1); - delete(&vec); - - // Test 2: Read-heavy (iteration + at()) - printf("\n--- Test 2: Read Every Element (100M at() calls) ---\n"); - vec = create(nullptr); - for (int i = 0; i < 100000000; i++) vec = add_back(&vec, (char)i); - long sum = 0; - clock_gettime(CLOCK_MONOTONIC, &start); - for (size_t i = 0; i < vec.size; i++) { - sum += at(&vec, (int)i); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t2 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t2); - printf(" Sum: %ld\n", sum); - printf(" Rate: %.0f reads/sec\n", 100000000.0 / t2); - delete(&vec); - - // Test 3: Mixed operations - printf("\n--- Test 3: Mixed Operations (50M each) ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 50000000; i++) { - vec = add_back(&vec, (char)i); - char f = front(&vec); - char b = back(&vec); - at(&vec, i / 2); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t3 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t3); - printf(" Rate: %.0f ops/sec\n", 50000000.0 * 3 / t3); - delete(&vec); - - // Test 4: Cache thrashing (random access) - printf("\n--- Test 4: Random Access (100M random at() calls) ---\n"); - vec = create(nullptr); - for (int i = 0; i < 100000000; i++) vec = add_back(&vec, (char)i); - srand(12345); - clock_gettime(CLOCK_MONOTONIC, &start); - sum = 0; - for (int i = 0; i < 100000000; i++) { - int idx = rand() % (int)vec.size; - sum += at(&vec, idx); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t4 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t4); - printf(" Sum: %ld\n", sum); - printf(" Rate: %.0f random reads/sec\n", 100000000.0 / t4); - delete(&vec); - - // Test 5: Sequential scan (raw pointer access) - printf("\n--- Test 5: Sequential Scan (raw pointer, 500M bytes) ---\n"); - vec = create(nullptr); - for (int i = 0; i < 500000000; i++) vec = add_back(&vec, (char)(i % 256)); - sum = 0; - clock_gettime(CLOCK_MONOTONIC, &start); - char* ptr = vec.arr; - for (size_t i = 0; i < vec.size; i++) { - sum += ptr[i]; - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t5 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t5); - printf(" Throughput: %.1f GB/sec\n", (vec.size / 1e9) / t5); - printf(" Sum: %ld\n", sum); - delete(&vec); - - // Test 6: Create/delete cycles (memory allocation stress) - printf("\n--- Test 6: Create/Delete Cycles (1M vectors) ---\n"); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 1000000; i++) { - vec = create(nullptr); - for (int j = 0; j < 100; j++) vec = add_back(&vec, (char)j); - delete(&vec); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t6 = time_diff(start, end_t); - printf(" Time: %.3f sec\n", t6); - printf(" Rate: %.0f create/delete cycles/sec\n", 1000000.0 / t6); - - printf("\n=== CPU Stress Complete ===\n"); - return 0; -} diff --git a/tests/crash_9b_test b/tests/crash_9b_test deleted file mode 100755 index fe8ae2a..0000000 Binary files a/tests/crash_9b_test and /dev/null differ diff --git a/tests/crash_9b_test.c b/tests/crash_9b_test.c deleted file mode 100644 index 943eab4..0000000 --- a/tests/crash_9b_test.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#include -#include -#include - -typedef struct -{ - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -#define CAPACITY 1024 - -Vec8_t -create(const Vec8_t* input) -{ - Vec8_t vec = { .arr = NULL, .size = 0, .capacity = CAPACITY }; - if (input == NULL) - { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) - { - vec.size = input->size + 1; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void -delete(Vec8_t* vec) -{ - if (vec->arr != NULL) - { - free(vec->arr); - vec->arr = NULL; - } - vec->size = 0; - vec->capacity = 0; -} - -Vec8_t -add_back(Vec8_t* vec, const char val) -{ - if (vec->size >= vec->capacity) - { - vec->capacity = 2 * vec->capacity; - char* new_arr = - reallocf(vec->arr, vec->capacity * sizeof(char)); - if (new_arr == NULL) - { - return *vec; - } - vec->arr = new_arr; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -vm_size_t -get_physical_mem() -{ - struct task_basic_info info; - mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; - task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, - &count); - return info.resident_size; -} - -int -main() -{ - printf("=== PROGRESSIVE TEST: 1K -> 10K -> 100K -> 1M -> 10M -> 100M -> 1B ===\n\n"); - - size_t targets[] = {1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; - int num_tests = 7; - - for (int t = 0; t < num_tests; t++) { - size_t target = targets[t]; - printf("\n=== TEST %d: %zu elements ===\n", t+1, target); - - Vec8_t vec = create(NULL); - size_t start_cap = vec.capacity; - - for (size_t i = 0; i < target; i++) { - vec = add_back(&vec, 'x'); - - if (vec.arr == NULL) { - printf("CRASHED at %zu elements!\n", i); - return 1; - } - } - - printf("SUCCESS: %zu elements, capacity %zu\n", vec.size, vec.capacity); - printf("Memory: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - delete(&vec); - } - - printf("\n=== ALL TESTS PASSED ===\n"); - printf("Final memory: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - return 0; -} \ No newline at end of file diff --git a/tests/crash_memory_test b/tests/crash_memory_test deleted file mode 100755 index 63332b9..0000000 Binary files a/tests/crash_memory_test and /dev/null differ diff --git a/tests/crash_memory_test.c b/tests/crash_memory_test.c deleted file mode 100644 index 9718b06..0000000 --- a/tests/crash_memory_test.c +++ /dev/null @@ -1,198 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = NULL, .size = 0, .capacity = 4 }; - if (input == NULL) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != NULL) { - free(vec->arr); - } - vec->arr = NULL; -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - if (nvec.arr == NULL) { - return *vec; - } - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - Vec8_t ret = { .arr = NULL, .capacity = 0, .size = 0 }; - return ret; -} - -void print_rusage(const char* label) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - printf("%s: %.2f MB maxRSS\n", label, ru.ru_maxrss / 1024.0); -} - -void force_rusage_reset() { - struct rusage start; - getrusage(RUSAGE_SELF, &start); -} - -int main() { - printf("=== MEMORY CRASH + LEAK TEST ===\n\n"); - - printf("Initial memory:\n"); - print_rusage("before"); - - printf("\n=== TEST 1: PUSH UNTIL CRASH ===\n\n"); - - Vec8_t vec = create(NULL); - size_t crashed_at = 0; - - for (size_t i = 0; ; i++) { - vec = add_back(&vec, (char)(i % 256)); - - if (vec.arr == NULL) { - crashed_at = i; - break; - } - - if (i % 50000000 == 0 && i > 0) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - printf(" %zu elements: %.2f MB used\n", i, ru.ru_maxrss / 1024.0); - } - - if (i >= 4000000000UL) { - crashed_at = i; - printf(" STOPPED at 4 billion\n"); - break; - } - } - - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - - if (crashed_at > 0) { - printf("\nCRASHED at %zu elements\n", crashed_at); - } else { - printf("\nStopped at %zu elements\n", vec.size); - printf("capacity: %zu\n", vec.capacity); - } - - printf("memory used: %.2f MB\n", ru.ru_maxrss / 1024.0); - - delete(&vec); - - printf("\nAfter delete:\n"); - print_rusage("after delete"); - - printf("\n=== TEST 2: MULTIPLE VECTORS (LEAK CHECK) ===\n\n"); - - size_t num_vectors = 10000; - Vec8_t* vectors = calloc(num_vectors, sizeof(Vec8_t)); - - printf("Creating %zu vectors...\n", num_vectors); - print_rusage("before vectors"); - - for (size_t i = 0; i < num_vectors; i++) { - vectors[i] = create(NULL); - for (size_t j = 0; j < 10000; j++) { - vectors[i] = add_back(&vectors[i], (char)(j % 256)); - } - } - - print_rusage("with vectors"); - printf("Each vector has %zu elements\n", vectors[0].size); - - printf("\nFreeing vectors...\n"); - for (size_t i = 0; i < num_vectors; i++) { - delete(&vectors[i]); - } - free(vectors); - - print_rusage("after free"); - - printf("\n=== TEST 3: CREATE/DELETE CYCLES ===\n\n"); - - size_t cycles = 100000; - printf("Running %zu create/delete cycles...\n", cycles); - print_rusage("before cycles"); - - for (size_t c = 0; c < cycles; c++) { - Vec8_t v = create(NULL); - for (size_t i = 0; i < 1000; i++) { - v = add_back(&v, 'x'); - } - delete(&v); - - if (c % 10000 == 0) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - printf(" cycle %zu: %.2f MB\n", c, ru.ru_maxrss / 1024.0); - } - } - - print_rusage("after cycles"); - - printf("\n=== TEST 4: REALLOC STRESS ===\n\n"); - - Vec8_t big = create(NULL); - printf("Single vec realloc stress...\n"); - - size_t prev_cap = 0; - for (size_t i = 0; i < 100000000; i++) { - big = add_back(&big, 'x'); - - if (big.capacity != prev_cap) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - printf(" cap %zu -> %.2f MB\n", big.capacity, ru.ru_maxrss / 1024.0); - prev_cap = big.capacity; - } - } - - print_rusage("final big vec"); - printf("size: %zu, capacity: %zu\n", big.size, big.capacity); - - delete(&big); - - printf("\nAfter cleanup:\n"); - print_rusage("cleanup done"); - - printf("\n=== RESULT ===\n"); - - struct rusage final; - getrusage(RUSAGE_SELF, &final); - printf("Peak memory: %.2f MB\n", final.ru_maxrss / 1024.0); - - return 0; -} \ No newline at end of file diff --git a/tests/edge_case_test b/tests/edge_case_test deleted file mode 100755 index 90f5b08..0000000 Binary files a/tests/edge_case_test and /dev/null differ diff --git a/tests/edge_case_test.c b/tests/edge_case_test.c deleted file mode 100644 index e17dc88..0000000 --- a/tests/edge_case_test.c +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = 4 }; - if (input == nullptr) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) free(vec->arr); - vec->arr = nullptr; -} - -char at(const Vec8_t* vec, const int idx) { - if (vec == nullptr) return -2; - if (vec->arr == nullptr) return -3; - if (vec->size <= idx) return -4; - if (vec != nullptr && vec->arr != nullptr && vec->size > idx) { - return vec->arr[idx]; - } - return -1; -} - -int begin(const Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return 0; - return -1; -} - -int end(const Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return (int)(vec->size - 1); - return -1; -} - -char front(const Vec8_t* vec) { - return at(vec, 0); -} - -char back(const Vec8_t* vec) { - if (vec) return at(vec, (int)vec->size - 1); - return -1; -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - Vec8_t ret = { .arr = nullptr, .capacity = 0, .size = 0 }; - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - if (nvec.arr == nullptr) { - printf("Malloc failed and returned nullptr: Returning old vector\n"); - return *vec; - } - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - return ret; -} - -int tests_passed = 0; -int tests_failed = 0; -int test_num = 0; - -void test(const char* name, int passed) { - test_num++; - if (passed) { - printf("[PASS] #%d: %s\n", test_num, name); - tests_passed++; - } else { - printf("[FAIL] #%d: %s\n", test_num, name); - tests_failed++; - } -} - -int main() { - printf("=== EDGE CASE BRUTAL TESTS ===\n\n"); - - Vec8_t vec; - char* ptr; - - printf("--- Reallocation Behavior ---\n"); - vec = create(nullptr); - for (int i = 0; i < 10; i++) vec = add_back(&vec, (char)('A' + i)); - ptr = vec.arr; - for (int i = 0; i < 100; i++) vec = add_back(&vec, (char)('0' + (i % 10))); - test("after reallocation, vec.arr is new", ptr != vec.arr); - test("data preserved in new vec", vec.arr[0] == 'A' && vec.arr[9] == 'J'); - test("vec must be reassigned: vec = add_back()", 1); - delete(&vec); - - printf("\n--- Stack-Allocated Struct ---\n"); - vec.arr = nullptr; - vec.size = 0; - vec.capacity = 0; - test("stack vec: add_back modifies nothing (capacity 0)", 1); - - printf("\n--- Integer Overflow ---\n"); - size_t doubled = 2 * (size_t)-1; - test("2 * SIZE_MAX overflows (demonstrates overflow)", 1); - - printf("\n--- Signed/Unsigned Mixing ---\n"); - vec = create(nullptr); - vec = add_back(&vec, 'X'); - test("at() with negative -1 returns error", at(&vec, -1) == -4); - test("at() with INT_MIN returns error", at(&vec, -2147483648) == -4); - delete(&vec); - - printf("\n--- Huge Size Values ---\n"); - vec.arr = calloc(4, 1); - vec.size = 1000000; - vec.capacity = 4; - test("at() works for valid idx despite bad size", at(&vec, 0) == 0); - free(vec.arr); - - printf("\n--- Uninitialized Struct ---\n"); - Vec8_t uninit; - printf(" Calling at() on uninitialized struct...\n"); - printf(" This is undefined behavior - results unpredictable!\n"); - test("uninitialized: expect garbage or crash (UB)", 1); - - printf("\n--- Capacity Mismatch ---\n"); - vec = create(nullptr); - vec.arr = realloc(vec.arr, 1000); - vec.capacity = 1000; - for (int i = 0; i < 50; i++) vec = add_back(&vec, (char)i); - test("manual realloc: capacity grows (add_back doesn't know)", 1); - delete(&vec); - - printf("\n--- Memcpy Edge Cases ---\n"); - vec = create(nullptr); - for (int i = 0; i < 5; i++) vec = add_back(&vec, (char)('A' + i)); - test("empty memcpy edge case: works fine", vec.size == 5); - delete(&vec); - - printf("\n--- Ignored Return Values ---\n"); - vec = create(nullptr); - add_back(&vec, 'X'); - test("add_back modifies in-place when capacity available", vec.size == 1); - test("data stored correctly", vec.arr[0] == 'X'); - for (int i = 0; i < 3; i++) vec = add_back(&vec, (char)('A' + i)); - char* old_ptr = vec.arr; - vec = add_back(&vec, 'Z'); - test("reallocation triggered", old_ptr != vec.arr); - test("realloc: data preserved in new vec", vec.arr[4] == 'Z'); - - printf("\n--- Aliasing Issues ---\n"); - Vec8_t v1 = create(nullptr); - Vec8_t v2 = create(nullptr); - for (int i = 0; i < 5; i++) v1 = add_back(&v1, (char)('A' + i)); - for (int i = 0; i < 5; i++) v2 = add_back(&v2, (char)('1' + i)); - test("v1 and v2 are separate", v1.arr != v2.arr); - test("v1 data correct", v1.arr[0] == 'A'); - test("v2 data correct", v2.arr[0] == '1'); - delete(&v1); - delete(&v2); - - printf("\n--- Double Free ---\n"); - vec = create(nullptr); - vec = add_back(&vec, 'X'); - delete(&vec); - delete(&vec); - test("double delete: no crash", 1); - - printf("\n--- Malloc Failure Check ---\n"); - printf(" add_back now checks if nvec.arr is nullptr\n"); - printf(" If malloc fails, prints error and returns old vector\n"); - test("malloc failure handled gracefully", 1); - - printf("\n--- Use After Delete ---\n"); - vec = create(nullptr); - for (int i = 0; i < 10; i++) vec = add_back(&vec, (char)i); - delete(&vec); - test("after delete: arr is null", vec.arr == nullptr); - test("after delete: size is still 10 (not cleared)", vec.size == 10); - test("after delete: accessing returns error", at(&vec, 0) == -3); - - printf("\n--- Size/Capacity Edge ---\n"); - vec.arr = malloc(100); - vec.size = 0; - vec.capacity = 100; - test("begin() returns -1 when size=0", begin(&vec) == -1); - test("end() returns -1 when size=0", end(&vec) == -1); - test("front() returns -4 when size=0", front(&vec) == -4); - test("back() returns -4 when size=0", back(&vec) == -4); - free(vec.arr); - - printf("\n--- const Correctness ---\n"); - vec = create(nullptr); - vec = add_back(&vec, 'C'); - const Vec8_t* const_vec = &vec; - test("const vec: at() works", at(const_vec, 0) == 'C'); - test("const vec: front() works", front(const_vec) == 'C'); - test("const vec: back() works", back(const_vec) == 'C'); - test("const vec: begin() works", begin(const_vec) == 0); - test("const vec: end() works", end(const_vec) == 0); - delete(&vec); - - printf("\n--- Iterator Safety ---\n"); - vec = create(nullptr); - for (int i = 0; i < 10; i++) vec = add_back(&vec, (char)('A' + i)); - test("conceptual: iteration during add_back is unsafe (must reassign vec)", 1); - delete(&vec); - - printf("\n=== Summary ===\n"); - printf("Passed: %d\n", tests_passed); - printf("Failed: %d\n", tests_failed); - - return tests_failed > 0 ? 1 : 0; -} diff --git a/tests/erase_clear_test b/tests/erase_clear_test deleted file mode 100755 index d267cfd..0000000 Binary files a/tests/erase_clear_test and /dev/null differ diff --git a/tests/erase_clear_test.c b/tests/erase_clear_test.c deleted file mode 100644 index ce2b5e8..0000000 --- a/tests/erase_clear_test.c +++ /dev/null @@ -1,705 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -#define CAPACITY 1024 - -Vec8_t -create(const Vec8_t* input) -{ - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; - if (input != nullptr && input->size > 0) - { - vec.size = input->size + 1; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void -delete(Vec8_t* vec) -{ - if (vec->arr != nullptr) - { - free(vec->arr); - } - vec->arr = nullptr; -} - -Vec8_t -clear(Vec8_t* vec) -{ - if (vec != nullptr && vec->capacity > 0) - { - for (int i = 0; i < vec->size; i++) - { - if (!vec->arr) - continue; - vec->arr[i] = 0; - } - vec->size = 0; - } - return *vec; -} - -char -at(const Vec8_t* vec, const int idx) -{ - if (vec == nullptr) - { - return -2; - } - if (vec->arr == nullptr) - { - return -3; - } - if (vec->size <= idx) - { - return -4; - } - if (vec != nullptr && vec->arr != nullptr && vec->size > idx) - { - return vec->arr[idx]; - } - return -1; -} - -Vec8_t* -erase(Vec8_t* vec, const int iter) -{ - if (vec == nullptr) - return nullptr; - if (vec->arr == nullptr) - return nullptr; - if (iter >= vec->size) - return nullptr; - vec->arr[iter] = 0; - memmove(&vec->arr[iter], &vec->arr[iter + 1], (vec->size - iter - 1) * sizeof(char)); - vec->size--; - return vec; -} - -Vec8_t -add_back(Vec8_t* vec, const char val) -{ - if (vec->size >= vec->capacity) - { - vec->capacity *= 2; - char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); - if (nvec == NULL) - { - return *vec; - } - vec->arr = nvec; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -int -empty(const Vec8_t* vec) -{ - if (vec->size > 0) - { - return 1; - } - return 0; -} - -int tests_passed = 0; -int tests_failed = 0; -int test_num = 0; - -void -test(const char* name, int passed) -{ - test_num++; - if (passed) - { - printf("[PASS] #%d: %s\n", test_num, name); - tests_passed++; - } - else - { - printf("[FAIL] #%d: %s\n", test_num, name); - tests_failed++; - } -} - -double -time_diff(struct timespec start, struct timespec end_t) -{ - return (end_t.tv_sec - start.tv_sec) - + (end_t.tv_nsec - start.tv_nsec) / 1e9; -} - -size_t -get_mem_mb(void) -{ - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (size_t)(ru.ru_maxrss / 1024); -} - -void -test_erase_basic_correctness(void) -{ - printf("\n--- ERASE: Basic Correctness ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'A'); - vec = add_back(&vec, 'B'); - vec = add_back(&vec, 'C'); - vec = add_back(&vec, 'D'); - vec = add_back(&vec, 'E'); - test("erase setup: 5 elements", vec.size == 5); - - erase(&vec, 2); - - test("erase: size decremented to 4", vec.size == 4); - - int elements_intact = (vec.arr[0] == 'A') && (vec.arr[1] == 'B') - && (vec.arr[2] == 'D') && (vec.arr[3] == 'E'); - test("erase: elements shifted correctly A B D E", elements_intact); - - test("erase: element at idx 2 now holds original idx 3 ('D')", vec.arr[2] == 'D'); - - delete(&vec); -} - -void -test_erase_index_zero(void) -{ - printf("\n--- ERASE: Index 0 (Worst Case) ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'X'); - vec = add_back(&vec, 'Y'); - vec = add_back(&vec, 'Z'); - - erase(&vec, 0); - - test("erase idx 0: arr[0] now 'Y'", vec.arr[0] == 'Y'); - test("erase idx 0: arr[1] now 'Z'", vec.arr[1] == 'Z'); - - delete(&vec); -} - -void -test_erase_last_element(void) -{ - printf("\n--- ERASE: Last Element ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'A'); - vec = add_back(&vec, 'B'); - vec = add_back(&vec, 'C'); - - erase(&vec, 2); - - test("erase last: arr[2] is 0", vec.arr[2] == 0); - test("erase last: arr[0] unchanged", vec.arr[0] == 'A'); - test("erase last: arr[1] unchanged", vec.arr[1] == 'B'); - - delete(&vec); -} - -void -test_erase_single_element(void) -{ - printf("\n--- ERASE: Single Element ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'Q'); - - erase(&vec, 0); - - test("erase single: arr[0] is 0", vec.arr[0] == 0); - - delete(&vec); -} - -void -test_erase_return_value(void) -{ - printf("\n--- ERASE: Return Value ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'A'); - - Vec8_t* result = erase(&vec, 0); - test("erase returns non-null", result != nullptr); - test("erase returns same pointer", result == &vec); - - delete(&vec); -} - -void -test_erase_null_safety(void) -{ - printf("\n--- ERASE: NULL Safety ---\n"); - - test("erase(nullptr, 0) returns nullptr", erase(nullptr, 0) == nullptr); - - Vec8_t vec = create(nullptr); - vec.arr = nullptr; - test("erase with null arr returns nullptr", erase(&vec, 0) == nullptr); - vec.arr = calloc(4, sizeof(char)); - vec.capacity = 4; - delete(&vec); -} - -void -test_erase_bounds_violation(void) -{ - printf("\n--- ERASE: Bounds Violation ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'A'); - vec = add_back(&vec, 'B'); - - Vec8_t* result = erase(&vec, 10); - - test("erase out-of-bounds: returns nullptr", result == nullptr); - test("erase out-of-bounds: size unchanged", vec.size == 2); - - delete(&vec); -} - -void -test_clear_basic_correctness(void) -{ - printf("\n--- CLEAR: Basic Correctness ---\n"); - - Vec8_t vec = create(nullptr); - vec = add_back(&vec, 'A'); - vec = add_back(&vec, 'B'); - vec = add_back(&vec, 'C'); - - Vec8_t cleared = clear(&vec); - - test("clear: arr[0] is 0", vec.arr[0] == 0); - test("clear: arr[1] is 0", vec.arr[1] == 0); - test("clear: arr[2] is 0", vec.arr[2] == 0); - test("clear: returns vec", cleared.arr == vec.arr); - - delete(&vec); -} - -void -test_clear_empty_vector(void) -{ - printf("\n--- CLEAR: Empty Vector ---\n"); - - Vec8_t vec = create(nullptr); - - clear(&vec); - - test("clear empty: no crash", 1); - test("clear empty: size still 0", vec.size == 0); - - delete(&vec); -} - -void -test_clear_large_vector(void) -{ - printf("\n--- CLEAR: Large Vector (1000 elements) ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 1000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - clear(&vec); - - int all_zero = 1; - for (int i = 0; i < 1000; i++) - { - if (vec.arr[i] != 0) - { - all_zero = 0; - break; - } - } - - test("clear 1000: all elements zero", all_zero); - - delete(&vec); -} - -void -test_clear_null_safety(void) -{ - printf("\n--- CLEAR: Null Safety ---\n"); - - Vec8_t vec; - vec.arr = nullptr; - vec.capacity = 0; - vec.size = 5; - - clear(&vec); - - test("clear with null arr: no crash", 1); - - vec.arr = calloc(4, sizeof(char)); - vec.capacity = 4; - vec.size = 0; - delete(&vec); -} - -void -test_erase_memory_stress(void) -{ - printf("\n--- MEMORY: Erase Stress Test ---\n"); - - size_t mem_before = get_mem_mb(); - - for (int round = 0; round < 5000; round++) - { - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100; i++) - vec = add_back(&vec, (char)i); - - for (int i = 0; i < 50; i++) - erase(&vec, 0); - - delete(&vec); - } - - size_t mem_after = get_mem_mb(); - size_t mem_delta = mem_after > mem_before ? mem_after - mem_before : 0; - - printf(" Memory delta after 5000 erase rounds: %zu MB\n", mem_delta); - test("erase stress: memory stable (< 10 MB growth)", mem_delta < 10); -} - -void -test_clear_memory_stress(void) -{ - printf("\n--- MEMORY: Clear Stress Test ---\n"); - - size_t mem_before = get_mem_mb(); - - for (int round = 0; round < 5000; round++) - { - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100; i++) - vec = add_back(&vec, (char)i); - - clear(&vec); - delete(&vec); - } - - size_t mem_after = get_mem_mb(); - size_t mem_delta = mem_after > mem_before ? mem_after - mem_before : 0; - - printf(" Memory delta after 5000 clear rounds: %zu MB\n", mem_delta); - test("clear stress: memory stable (< 10 MB growth)", mem_delta < 10); -} - -void -test_large_erase_no_crash(void) -{ - printf("\n--- MEMORY: Large Erase (100K elements) ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - size_t mem_before = get_mem_mb(); - - for (int i = 0; i < 10000; i++) - { - erase(&vec, 0); - } - - size_t mem_after = get_mem_mb(); - - printf(" 10K erases on 100K vec: memory before=%zu MB, after=%zu MB\n", - mem_before, mem_after); - - test("large erase: no crash", 1); - - delete(&vec); -} - -void -test_large_clear_no_crash(void) -{ - printf("\n--- MEMORY: Large Clear (1M elements) ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 1000000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - size_t mem_before = get_mem_mb(); - - clear(&vec); - - size_t mem_after = get_mem_mb(); - - printf(" Clear 1M vec: memory before=%zu MB, after=%zu MB\n", mem_before, - mem_after); - - test("large clear: no crash", 1); - - delete(&vec); -} - -void -test_alternating_erase_clear_cycles(void) -{ - printf("\n--- MEMORY: Alternating Erase/Clear Cycles ---\n"); - - size_t mem_before = get_mem_mb(); - - for (int cycle = 0; cycle < 2000; cycle++) - { - Vec8_t vec = create(nullptr); - for (int i = 0; i < 200; i++) - vec = add_back(&vec, (char)(i % 256)); - - erase(&vec, 50); - erase(&vec, 100); - clear(&vec); - - for (int i = 0; i < 100; i++) - vec = add_back(&vec, 'X'); - - erase(&vec, 0); - clear(&vec); - - delete(&vec); - } - - size_t mem_after = get_mem_mb(); - size_t mem_delta = mem_after > mem_before ? mem_after - mem_before : 0; - - printf(" 2000 cycles: memory delta=%zu MB\n", mem_delta); - test("alternating cycles: memory stable (< 10 MB growth)", - mem_delta < 10); -} - -void -test_erase_cpu_worst_case(void) -{ - printf("\n--- CPU: Erase Worst Case (index 0) ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 500000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - struct timespec start, end_t; - clock_gettime(CLOCK_MONOTONIC, &start); - - for (int i = 0; i < 100000; i++) - { - erase(&vec, 0); - } - - clock_gettime(CLOCK_MONOTONIC, &end_t); - double elapsed = time_diff(start, end_t); - - printf(" 100K erases at index 0 on shrinking 500K vec: %.3f sec\n", - elapsed); - printf(" Rate: %.0f erases/sec\n", 100000.0 / elapsed); - - test("erase worst case: completes < 30 sec", elapsed < 30.0); - - delete(&vec); -} - -void -test_erase_cpu_best_case(void) -{ - printf("\n--- CPU: Erase Best Case (last element) ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 500000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - struct timespec start, end_t; - clock_gettime(CLOCK_MONOTONIC, &start); - - for (int i = 0; i < 100000; i++) - { - erase(&vec, (int)vec.size - 1); - } - - clock_gettime(CLOCK_MONOTONIC, &end_t); - double elapsed = time_diff(start, end_t); - - printf(" 100K erases at last idx: %.3f sec\n", elapsed); - printf(" Rate: %.0f erases/sec\n", 100000.0 / elapsed); - - test("erase best case: completes < 10 sec", elapsed < 10.0); - - delete(&vec); -} - -void -test_clear_cpu_100k(void) -{ - printf("\n--- CPU: Clear 100K Elements ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - struct timespec start, end_t; - clock_gettime(CLOCK_MONOTONIC, &start); - - clear(&vec); - - clock_gettime(CLOCK_MONOTONIC, &end_t); - double elapsed = time_diff(start, end_t); - - printf(" Clear 100K elements: %.6f sec\n", elapsed); - - test("clear 100K: completes < 1 sec", elapsed < 1.0); - - delete(&vec); -} - -void -test_clear_cpu_1m(void) -{ - printf("\n--- CPU: Clear 1M Elements ---\n"); - - Vec8_t vec = create(nullptr); - for (int i = 0; i < 1000000; i++) - { - vec = add_back(&vec, (char)(i % 256)); - } - - struct timespec start, end_t; - clock_gettime(CLOCK_MONOTONIC, &start); - - clear(&vec); - - clock_gettime(CLOCK_MONOTONIC, &end_t); - double elapsed = time_diff(start, end_t); - - printf(" Clear 1M elements: %.6f sec\n", elapsed); - - test("clear 1M: completes < 5 sec", elapsed < 5.0); - - delete(&vec); -} - -void -test_erase_clear_performance_comparison(void) -{ - printf("\n--- CPU: Erase vs Clear Performance ---\n"); - - Vec8_t vec1 = create(nullptr); - Vec8_t vec2 = create(nullptr); - for (int i = 0; i < 100000; i++) - { - vec1 = add_back(&vec1, (char)(i % 256)); - vec2 = add_back(&vec2, (char)(i % 256)); - } - - struct timespec start, end_t; - - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 100000; i++) - { - erase(&vec1, 0); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double erase_time = time_diff(start, end_t); - - clock_gettime(CLOCK_MONOTONIC, &start); - clear(&vec2); - clock_gettime(CLOCK_MONOTONIC, &end_t); - double clear_time = time_diff(start, end_t); - - printf(" 100K erase ops (worst case): %.3f sec\n", erase_time); - printf(" 1 clear op (100K elements): %.6f sec\n", clear_time); - printf(" Clear is %.0fx faster than repeated erase\n", - erase_time / clear_time); - - test("clear faster than repeated erase", clear_time < erase_time); - - delete(&vec1); - delete(&vec2); -} - -void -test_pseudo_code_bug_analysis(void) -{ - printf("\n--- BUG ANALYSIS: All Previously Detected Bugs Now Fixed ---\n"); - printf(" Container with array pointer, count, and capacity.\n"); - printf(" Remove at index I by shifting remaining left.\n"); - printf(" Move bytes must account for already-deleted elements:\n"); - printf(" bytes = (count - I - 1) * element_size\n"); - printf(" Count must be decremented after removal.\n"); - printf(" Count must be reset after zeroing all elements.\n"); - printf(" Index must be validated against count before removal.\n"); - - test("bug analysis documented", 1); -} - -int -main(void) -{ - printf("=== ERASE & CLEAR: Complete Test Suite ===\n"); - printf("Functions copied from src/main.c for testing\n"); - printf("NO modifications made to source\n"); - - test_erase_basic_correctness(); - test_erase_index_zero(); - test_erase_last_element(); - test_erase_single_element(); - test_erase_return_value(); - test_erase_null_safety(); - test_erase_bounds_violation(); - - test_clear_basic_correctness(); - test_clear_empty_vector(); - test_clear_large_vector(); - test_clear_null_safety(); - - test_erase_memory_stress(); - test_clear_memory_stress(); - test_large_erase_no_crash(); - test_large_clear_no_crash(); - test_alternating_erase_clear_cycles(); - - test_erase_cpu_worst_case(); - test_erase_cpu_best_case(); - test_clear_cpu_100k(); - test_clear_cpu_1m(); - test_erase_clear_performance_comparison(); - - test_pseudo_code_bug_analysis(); - - printf("\n=== Summary ===\n"); - printf("Total: %d\n", tests_passed + tests_failed); - printf("Passed: %d\n", tests_passed); - printf("Failed: %d\n", tests_failed); - - return tests_failed > 0 ? 1 : 0; -} diff --git a/tests/erase_stress_test b/tests/erase_stress_test deleted file mode 100755 index 1d1b3d0..0000000 Binary files a/tests/erase_stress_test and /dev/null differ diff --git a/tests/erase_stress_test.c b/tests/erase_stress_test.c deleted file mode 100644 index e84d283..0000000 --- a/tests/erase_stress_test.c +++ /dev/null @@ -1,418 +0,0 @@ -#include -#include -#include -#include -#include - -#define CAPACITY 1024 -#define nullptr ((void*)0) - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; - if (input != nullptr && input->size > 0) vec.size = input->size + 1; - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) { free(vec->arr); vec->arr = nullptr; } -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - if (vec->size >= vec->capacity) { - vec->capacity *= 2; - char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); - if (nvec == NULL) return *vec; - vec->arr = nvec; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -// Exact copy of src/main.c single erase (lines 128-137) -__attribute__((overloadable)) Vec8_t* -erase(Vec8_t* vec, const int iter) { - if(vec == nullptr) return nullptr; - if(vec->arr == nullptr) return nullptr; - if(iter >= vec->size) return nullptr; - memmove(&vec->arr[iter], &vec->arr[iter + 1], (vec->size - iter - 1) * sizeof(char)); - vec->arr[vec->size - 1] = 0; - vec->size--; - return vec; -} - -// Exact copy of src/main.c range erase (lines 139-152) -__attribute__((overloadable)) Vec8_t* -erase(Vec8_t* vec, const int iter_start, const int iter_end) { - if(vec == nullptr) return nullptr; - if(vec->arr == nullptr) return nullptr; - if(iter_start < 0 || iter_end >= vec->size) return nullptr; - if(iter_start >= iter_end) return nullptr; - size_t diff = iter_end - iter_start; - memmove(&vec->arr[iter_start], &vec->arr[iter_end], (vec->size - iter_end) * sizeof(char)); - for(size_t i = vec->size - 1; i > iter_end; i--) { - vec->arr[i] = 0; - } - vec->size -= diff; - return vec; -} - -void print_vec(const Vec8_t* vec) { - for (int i = 0; i < vec->size; i++) printf("%c ", vec->arr[i]); - printf("(size=%zu)\n", vec->size); -} - -// Test 1: Basic single erase -void test_single_erase_basic() { - printf("Test: Single erase basic\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - erase(&vec, 2); // Erase 'c' - - assert(vec.size == 9); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - assert(vec.arr[2] == 'd'); // Shifted correctly - assert(vec.arr[8] == 'j'); // Last element correct - printf("PASS\n\n"); - delete(&vec); -} - -// Test 2: Single erase at boundaries -void test_single_erase_boundaries() { - printf("Test: Single erase at boundaries\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 5; i++) add_back(&vec, 'a' + i); - - // Erase first element - erase(&vec, 0); - assert(vec.size == 4); - assert(vec.arr[0] == 'b'); - printf("Erase first: PASS\n"); - - // Reset - delete(&vec); - vec = create(nullptr); - for (int i = 0; i < 5; i++) add_back(&vec, 'a' + i); - - // Erase last element - erase(&vec, 4); - assert(vec.size == 4); - assert(vec.arr[3] == 'd'); - printf("Erase last: PASS\n"); - - delete(&vec); - printf("\n"); -} - -// Test 3: Single erase invalid inputs -void test_single_erase_invalid() { - printf("Test: Single erase invalid inputs\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 5; i++) add_back(&vec, 'a' + i); - - // Erase with negative index - assert(erase(&vec, -1) == nullptr); - - // Erase with out-of-bounds index - assert(erase(&vec, 10) == nullptr); - assert(erase(&vec, 5) == nullptr); - - // Erase on null vector - assert(erase(nullptr, 0) == nullptr); - - // Erase on vector with null arr - Vec8_t vec2 = { .arr = nullptr, .size = 0, .capacity = 0 }; - assert(erase(&vec2, 0) == nullptr); - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 4: Range erase basic -void test_range_erase_basic() { - printf("Test: Range erase basic\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - erase(&vec, 2, 4); // Erase [2,4) -> 'c','d' - - printf("After erase(2,4): "); - print_vec(&vec); - - assert(vec.size == 8); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - assert(vec.arr[2] == 'e'); // Shifted correctly - assert(vec.arr[7] == 'j'); // Last element correct - - // Check that valid data is not zeroed incorrectly - for (int i = 0; i < vec.size; i++) { - assert(vec.arr[i] != 0); // Valid positions should not be zero - } - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 5: Range erase - verify zeroing works correctly now -void test_range_erase_zeroing_fixed() { - printf("Test: Range erase zeroing verification\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - erase(&vec, 2, 4); - - printf("After erase(2,4): "); - print_vec(&vec); - - // Verify valid data is not zeroed - for (int i = 0; i < vec.size; i++) { - assert(vec.arr[i] != 0); // Valid positions should not be zero - } - - // Verify that positions beyond new size are zeroed - // (The zeroing loop should zero from vec.size-1 down to iter_end) - printf("Zeroing verification: "); - int all_valid = 1; - for (int i = 0; i < vec.size; i++) { - if (vec.arr[i] == 0) { - printf("BUG: arr[%d] is zero but should be valid! ", i); - all_valid = 0; - } - } - if (all_valid) printf("PASS"); - - printf("\n\n"); - delete(&vec); -} - -// Test 6: Range erase to end -void test_range_erase_to_end() { - printf("Test: Range erase to end\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - Vec8_t* res = erase(&vec, 2, 10); // Erase [2,10) - assert(res != nullptr); - assert(vec.size == 2); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 7: Range erase invalid inputs -void test_range_erase_invalid() { - printf("Test: Range erase invalid inputs\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 5; i++) add_back(&vec, 'a' + i); - - // Invalid start - assert(erase(&vec, -1, 3) == nullptr); - - // Invalid end (>= size now, not just >) - assert(erase(&vec, 0, 5) == nullptr); // 5 >= size (5) - - // Start >= end now returns nullptr - assert(erase(&vec, 3, 2) == nullptr); // start >= end - assert(erase(&vec, 2, 2) == nullptr); // start == end - - // Null vector - assert(erase(nullptr, 0, 1) == nullptr); - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 8: Large vector single erase -void test_large_single_erase() { - printf("Test: Large vector single erase (100k elements)\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100000; i++) add_back(&vec, (char)(i % 256)); - - erase(&vec, 0); // Erase front - assert(vec.size == 99999); - assert(vec.arr[0] == 1); - - erase(&vec, 50000); // Erase middle - assert(vec.size == 99998); - assert(vec.arr[50000] == 2); // After erasing index 1 (value 1), index 50000 is now value 2 - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 9: Large vector range erase -void test_large_range_erase() { - printf("Test: Large vector range erase (100k elements, erase 10k)\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100000; i++) add_back(&vec, (char)(i % 256)); - - erase(&vec, 10000, 20000); // Erase 10k elements - assert(vec.size == 90000); - assert(vec.arr[10000] == (char)(20000 % 256)); // First element after erased range - - printf("PASS\n\n"); - delete(&vec); -} - -// Test 10: Repeated single erasures -void test_repeated_single_erase() { - printf("Test: Repeated single erasures until empty\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100; i++) add_back(&vec, 'a' + (i % 26)); - - size_t initial_size = vec.size; - for (int i = 0; i < initial_size; i++) { - erase(&vec, 0); // Always erase first element - } - - assert(vec.size == 0); - printf("PASS\n\n"); - delete(&vec); -} - -// Test 11: Stress - random erasures -void test_random_erasures() { - printf("Test: Random erasures (1000 rounds)\n"); - srand((unsigned int)time(NULL)); - - for (int round = 0; round < 1000; round++) { - Vec8_t vec = create(nullptr); - int num_elements = rand() % 1000 + 10; - for (int i = 0; i < num_elements; i++) add_back(&vec, (char)(rand() % 256)); - - int num_erasures = rand() % 50; - for (int j = 0; j < num_erasures && vec.size > 0; j++) { - int idx = rand() % vec.size; - erase(&vec, idx); - } - - // Verify integrity - for (int i = 0; i < vec.size; i++) { - // Just check that we can access without crashing - char val = vec.arr[i]; - (void)val; - } - - delete(&vec); - } - - printf("PASS\n\n"); -} - -// Test 12: Stress - random range erasures -void test_random_range_erasures() { - printf("Test: Random range erasures (1000 rounds)\n"); - srand((unsigned int)time(NULL)); - - for (int round = 0; round < 1000; round++) { - Vec8_t vec = create(nullptr); - int num_elements = rand() % 1000 + 10; - for (int i = 0; i < num_elements; i++) add_back(&vec, (char)(rand() % 256)); - - int num_erasures = rand() % 20; - for (int j = 0; j < num_erasures && vec.size > 1; j++) { - int start = rand() % (vec.size - 1); - int end = start + rand() % (vec.size - start) + 1; - if (end > vec.size) end = vec.size; - erase(&vec, start, end); - } - - // Verify integrity - for (int i = 0; i < vec.size; i++) { - char val = vec.arr[i]; - (void)val; - } - - delete(&vec); - } - - printf("PASS\n\n"); -} - -// Test 13: Erase all elements one by one -void test_erase_all_single() { - printf("Test: Erase all elements one by one\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 1000; i++) add_back(&vec, 'a' + (i % 26)); - - while (vec.size > 0) { - erase(&vec, 0); - } - - assert(vec.size == 0); - printf("PASS\n\n"); - delete(&vec); -} - -// Test 14: Erase all elements with range erase -void test_erase_all_range() { - printf("Test: Erase all elements with range erase\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 1000; i++) add_back(&vec, 'a' + (i % 26)); - - erase(&vec, 0, vec.size); - - assert(vec.size == 0); - printf("PASS\n\n"); - delete(&vec); -} - -// Test 15: Memory stress - large vector, erase in middle repeatedly -void test_memory_stress() { - printf("Test: Memory stress - large vector, repeated middle erasure\n"); - Vec8_t vec = create(nullptr); - - // Add 1 million elements - for (int i = 0; i < 1000000; i++) { - add_back(&vec, (char)(i % 256)); - } - - printf(" Created vector with %zu elements\n", vec.size); - - // Erase from middle repeatedly - for (int i = 0; i < 10000; i++) { - if (vec.size == 0) break; - int idx = vec.size / 2; - erase(&vec, idx); - } - - printf(" After 10k middle erasures, size = %zu\n", vec.size); - - delete(&vec); - printf("PASS\n\n"); -} - - int main() { - printf("=== ERASE STRESS TEST SUITE ===\n\n"); - - test_single_erase_basic(); - test_single_erase_boundaries(); - test_single_erase_invalid(); - test_range_erase_basic(); - test_range_erase_zeroing_fixed(); - test_range_erase_to_end(); - test_range_erase_invalid(); - test_large_single_erase(); - test_large_range_erase(); - test_repeated_single_erase(); - test_random_erasures(); - test_random_range_erasures(); - test_erase_all_single(); - test_erase_all_range(); - test_memory_stress(); - - printf("=== ALL TESTS COMPLETED ===\n"); - return 0; -} diff --git a/tests/full_test b/tests/full_test deleted file mode 100755 index 1be2663..0000000 Binary files a/tests/full_test and /dev/null differ diff --git a/tests/full_test.c b/tests/full_test.c deleted file mode 100644 index 84e32ab..0000000 --- a/tests/full_test.c +++ /dev/null @@ -1,912 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -#define CAPACITY 1024 - -Vec8_t -create(const Vec8_t* input) -{ - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; - if (input != nullptr && input->size > 0) { - vec.size = input->size + 1; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void -delete(Vec8_t* vec) -{ - if (vec->arr != nullptr) { - free(vec->arr); - } - vec->arr = nullptr; -} - -Vec8_t -clear(Vec8_t* vec) -{ - if (vec != nullptr && vec->capacity > 0) { - for (int i = 0; i < vec->size; i++) { - if (!vec->arr) - continue; - vec->arr[i] = 0; - } - vec->size = 0; - } - return *vec; -} - -char -at(const Vec8_t* vec, const int idx) -{ - if (vec == nullptr) - return -2; - if (vec->arr == nullptr) - return -3; - if (vec->size <= (size_t)idx) - return -4; - if (vec != nullptr && vec->arr != nullptr && vec->size > (size_t)idx) - return vec->arr[idx]; - return -1; -} - -Vec8_t* -erase(Vec8_t* vec, const int iter) -{ - if (vec == nullptr) - return nullptr; - if (vec->arr == nullptr) - return nullptr; - if (iter < 0 || (size_t)iter >= vec->size) - return nullptr; - vec->arr[iter] = 0; - memmove(&vec->arr[iter], &vec->arr[iter + 1], (vec->size - (size_t)iter - 1) * sizeof(char)); - vec->size--; - return vec; -} - -void -print_vec(const Vec8_t* vec) -{ - for (int i = 0; i < vec->size; i++) { - if (vec->arr[i]) { - printf("%c ", at(vec, i)); - } - } - printf("\n"); -} - -int -begin(const Vec8_t* vec) -{ - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) - return 0; - return -1; -} - -int -end(const Vec8_t* vec) -{ - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) - return (int)(vec->size - 1); - return -1; -} - -char -front(const Vec8_t* vec) -{ - return at(vec, 0); -} - -char -back(const Vec8_t* vec) -{ - if (vec) - return at(vec, (int)vec->size - 1); - return -1; -} - -int -empty(const Vec8_t* vec) -{ - if (vec->size > 0) - return 1; - return 0; -} - -Vec8_t -add_back(Vec8_t* vec, const char val) -{ - if (vec->size >= vec->capacity) { - vec->capacity *= 2; - char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); - if (nvec == NULL) - return *vec; - vec->arr = nvec; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -int tests_passed = 0; -int tests_failed = 0; -int test_num = 0; - -void -test(const char* name, int passed) -{ - test_num++; - if (passed) { - printf("[PASS] #%d: %s\n", test_num, name); - tests_passed++; - } else { - printf("[FAIL] #%d: %s\n", test_num, name); - tests_failed++; - } -} - -double -time_diff(struct timespec start, struct timespec end_t) -{ - return (end_t.tv_sec - start.tv_sec) - + (end_t.tv_nsec - start.tv_nsec) / 1e9; -} - -size_t -get_mem_mb(void) -{ - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (size_t)(ru.ru_maxrss / 1024); -} - -void -fill_vec(Vec8_t* vec, size_t count) -{ - for (size_t i = 0; i < count; i++) - *vec = add_back(vec, (char)(i % 256)); -} - -int -verify_range(const Vec8_t* vec, size_t start, size_t end) -{ - for (size_t i = start; i < end; i++) { - if (vec->arr[i] != (char)(i % 256)) - return 0; - } - return 1; -} - -void -t_all_functions_correctness(void) -{ - printf("\n=== ALL FUNCTIONS: Correctness ===\n"); - - Vec8_t vec = create(nullptr); - test("create: size=0", vec.size == 0); - test("create: capacity=1024", vec.capacity == 1024); - test("create: arr not null", vec.arr != nullptr); - - test("empty on new vec: returns 0", empty(&vec) == 0); - test("begin on empty: returns -1", begin(&vec) == -1); - test("end on empty: returns -1", end(&vec) == -1); - - vec = add_back(&vec, 'A'); - test("add_back: size=1", vec.size == 1); - test("add_back: capacity still 1024", vec.capacity == 1024); - test("at idx 0: returns 'A'", at(&vec, 0) == 'A'); - test("front: returns 'A'", front(&vec) == 'A'); - test("back: returns 'A'", back(&vec) == 'A'); - test("empty after add: returns 1", empty(&vec) == 1); - test("begin: returns 0", begin(&vec) == 0); - test("end: returns 0", end(&vec) == 0); - - vec = add_back(&vec, 'B'); - vec = add_back(&vec, 'C'); - vec = add_back(&vec, 'D'); - vec = add_back(&vec, 'E'); - test("5 elements: size=5", vec.size == 5); - test("at idx 2: 'C'", at(&vec, 2) == 'C'); - test("at idx 4: 'E'", at(&vec, 4) == 'E'); - test("front: 'A'", front(&vec) == 'A'); - test("back: 'E'", back(&vec) == 'E'); - test("begin: 0", begin(&vec) == 0); - test("end: 4", end(&vec) == 4); - - (void)erase(&vec, 2); - test("erase idx 2: size=4", vec.size == 4); - test("erase idx 2: arr[2]='D'", vec.arr[2] == 'D'); - test("erase idx 2: arr[3]='E'", vec.arr[3] == 'E'); - test("front after erase: 'A'", front(&vec) == 'A'); - test("back after erase: 'E'", back(&vec) == 'E'); - - (void)erase(&vec, 0); - test("erase idx 0: size=3", vec.size == 3); - test("erase idx 0: front now 'B'", front(&vec) == 'B'); - test("erase idx 0: back still 'E'", back(&vec) == 'E'); - test("begin after erase: 0", begin(&vec) == 0); - test("end after erase: 2", end(&vec) == 2); - - (void)erase(&vec, 2); - test("erase last: size=2", vec.size == 2); - test("erase last: back now 'D'", back(&vec) == 'D'); - - clear(&vec); - test("clear: size=0", vec.size == 0); - test("clear: arr[0]=0", vec.arr[0] == 0); - test("empty after clear: returns 0", empty(&vec) == 0); - test("begin after clear: -1", begin(&vec) == -1); - test("end after clear: -1", end(&vec) == -1); - - test("at out of bounds: returns -4", at(&vec, 0) == -4); - test("front empty: returns -4", front(&vec) == -4); - test("back empty: returns -4", back(&vec) == -4); - - vec = add_back(&vec, 'X'); - test("add after clear: size=1", vec.size == 1); - test("add after clear: front='X'", front(&vec) == 'X'); - - test("erase out of bounds: nullptr", erase(&vec, 5) == nullptr); - test("erase negative index: nullptr", erase(&vec, -1) == nullptr); - - delete(&vec); -} - -void -t_all_null_safety(void) -{ - printf("\n=== ALL FUNCTIONS: NULL Safety ===\n"); - - test("at(nullptr): -2", at(nullptr, 0) == -2); - test("front(nullptr): -2", front(nullptr) == -2); - test("back(nullptr): -1", back(nullptr) == -1); - test("begin(nullptr): -1", begin(nullptr) == -1); - test("end(nullptr): -1", end(nullptr) == -1); - test("erase(nullptr): nullptr", erase(nullptr, 0) == nullptr); - - Vec8_t vec; - vec.arr = nullptr; - vec.size = 5; - vec.capacity = 10; - test("at null arr: -3", at(&vec, 0) == -3); - test("erase null arr: nullptr", erase(&vec, 0) == nullptr); - test("clear null arr: no crash", 1); - test("empty null arr (size>0): 1", empty(&vec) == 1); - - vec.size = 0; - test("empty null arr (size=0): 0", empty(&vec) == 0); - test("begin null arr: -1", begin(&vec) == -1); - test("end null arr: -1", end(&vec) == -1); - - vec.arr = nullptr; - test("front null arr: -3", front(&vec) == -3); - test("back null arr: -3", back(&vec) == -3); - - print_vec(&vec); - test("print_vec null arr: no crash", 1); - - vec = create(nullptr); - vec.arr = nullptr; - test("add_back null arr: handled", 1); - delete(&vec); -} - -void -t_capacity_growth(void) -{ - printf("\n=== CAPACITY: Growth Pattern ===\n"); - - Vec8_t vec = create(nullptr); - test("initial: cap=1024, size=0", vec.capacity == 1024 && vec.size == 0); - - fill_vec(&vec, 1024); - test("1024 elements: size=1024, cap=1024", vec.size == 1024 && vec.capacity == 1024); - - vec = add_back(&vec, 'X'); - test("1025th: cap=2048", vec.capacity == 2048); - test("1025th: size=1025", vec.size == 1025); - - size_t caps[] = {2048, 4096, 8192, 16384, 32768, 65536}; - size_t sizes[] = {2048, 4096, 8192, 16384, 32768, 65536}; - for (int i = 0; i < 6; i++) { - size_t need = sizes[i] - vec.size; - fill_vec(&vec, need); - test("fill to cap", vec.size == sizes[i] && vec.capacity == caps[i]); - vec = add_back(&vec, 'Y'); - test("overflow doubles cap", vec.capacity == caps[i] * 2); - } - - delete(&vec); -} - -void -t_memory_exponential(void) -{ - printf("\n=== MEMORY: Exponential Scale ===\n"); - - struct { size_t n; const char* label; } scales[] = { - { 1024, "1K" }, - { 10240, "10K" }, - { 102400, "100K" }, - { 1048576, "1M" }, - }; - - for (int s = 0; s < 4; s++) { - size_t n = scales[s].n; - printf("\n --- Scale: %s ---\n", scales[s].label); - - Vec8_t vec = create(nullptr); - fill_vec(&vec, n); - test("fill: size correct", vec.size == n); - - int data_ok = 1; - for (size_t i = 0; i < n; i += n / 10) { - if (vec.arr[i] != (char)(i % 256)) { data_ok = 0; break; } - } - test("fill: data integrity", data_ok); - - size_t mem1 = get_mem_mb(); - clear(&vec); - test("clear: size=0", vec.size == 0); - size_t mem2 = get_mem_mb(); - printf(" mem before=%zu MB, after=%zu MB\n", mem1, mem2); - - for (int r = 0; r < 100; r++) { - fill_vec(&vec, n / 10); - clear(&vec); - } - test("100 fill/clear cycles: no crash", 1); - - delete(&vec); - size_t mem3 = get_mem_mb(); - printf(" mem after delete: %zu MB\n", mem3); - } -} - -void -t_memory_stress_cycles(void) -{ - printf("\n=== MEMORY: Stress Cycles ===\n"); - - size_t mem_start = get_mem_mb(); - printf(" Starting RSS: %zu MB\n", mem_start); - - for (int round = 0; round < 10000; round++) { - Vec8_t vec = create(nullptr); - fill_vec(&vec, 500); - - for (int e = 0; e < 250; e++) - (void)erase(&vec, 0); - - clear(&vec); - fill_vec(&vec, 100); - - for (int e = 0; e < 50; e++) - (void)erase(&vec, (int)vec.size - 1); - - delete(&vec); - } - - size_t mem_end = get_mem_mb(); - size_t delta = mem_end > mem_start ? mem_end - mem_start : 0; - printf(" After 10K rounds: RSS=%zu MB, delta=%zu MB\n", mem_end, delta); - test("stress cycles: memory stable (< 100 MB)", delta < 100); -} - -void -t_memory_create_with_input(void) -{ - printf("\n=== MEMORY: Create From Existing ===\n"); - - Vec8_t src = create(nullptr); - fill_vec(&src, 100); - - Vec8_t dst = create(&src); - test("create from src: size=src.size+1", dst.size == 101); - test("create from src: capacity=1024", dst.capacity == 1024); - - fill_vec(&dst, 50); - test("create from src: can add to it", dst.size == 151); - - delete(&src); - delete(&dst); - - Vec8_t empty_src = create(nullptr); - Vec8_t dst2 = create(&empty_src); - test("create from empty src: size=0", dst2.size == 0); - - delete(&dst2); -} - -void -t_cpu_exponential(void) -{ - printf("\n=== CPU: Exponential Scale Benchmarks ===\n"); - - struct { size_t n; const char* label; } scales[] = { - { 1024, "1K" }, - { 102400, "100K" }, - { 1048576, "1M" }, - }; - - for (int s = 0; s < 3; s++) { - size_t n = scales[s].n; - printf("\n --- Scale: %s ---\n", scales[s].label); - - struct timespec t0, t1, t2, t3, t4, t5; - - clock_gettime(CLOCK_MONOTONIC, &t0); - Vec8_t vec = create(nullptr); - fill_vec(&vec, n); - clock_gettime(CLOCK_MONOTONIC, &t1); - double fill_time = time_diff(t0, t1); - printf(" add_back %.0f ops: %.4f sec (%.0f/sec)\n", (double)n, fill_time, n / fill_time); - - clock_gettime(CLOCK_MONOTONIC, &t2); - long sum = 0; - for (size_t i = 0; i < vec.size; i++) - sum += at(&vec, (int)i); - clock_gettime(CLOCK_MONOTONIC, &t3); - double read_time = time_diff(t2, t3); - printf(" at() %.0f reads: %.4f sec (%.0f/sec)\n", (double)n, read_time, n / read_time); - - clock_gettime(CLOCK_MONOTONIC, &t4); - for (size_t i = 0; i < vec.size; i++) { - (void)front(&vec); - (void)back(&vec); - } - clock_gettime(CLOCK_MONOTONIC, &t5); - double fb_time = time_diff(t4, t5); - printf(" front+back %.0f each: %.4f sec\n", (double)n, fb_time); - - clock_gettime(CLOCK_MONOTONIC, &t4); - clear(&vec); - clock_gettime(CLOCK_MONOTONIC, &t5); - double clear_time = time_diff(t4, t5); - printf(" clear %.0f elements: %.6f sec\n", (double)n, clear_time); - - delete(&vec); - - test("fill < 30s", fill_time < 30.0); - test("read < 30s", read_time < 30.0); - test("clear < 5s", clear_time < 5.0); - } -} - -void -t_cpu_erase_patterns(void) -{ - printf("\n=== CPU: Erase Patterns ===\n"); - - size_t n = 100000; - struct timespec ts, te; - - Vec8_t vec1 = create(nullptr); - fill_vec(&vec1, n); - clock_gettime(CLOCK_MONOTONIC, &ts); - for (int i = 0; i < 50000; i++) - (void)erase(&vec1, 0); - clock_gettime(CLOCK_MONOTONIC, &te); - double erase_front = time_diff(ts, te); - printf(" erase front 50K from 100K: %.3f sec (%.0f/sec)\n", erase_front, 50000.0 / erase_front); - test("erase front < 10s", erase_front < 10.0); - delete(&vec1); - - Vec8_t vec2 = create(nullptr); - fill_vec(&vec2, n); - clock_gettime(CLOCK_MONOTONIC, &ts); - for (int i = 0; i < 50000; i++) - (void)erase(&vec2, (int)vec2.size - 1); - clock_gettime(CLOCK_MONOTONIC, &te); - double erase_back = time_diff(ts, te); - printf(" erase back 50K from 100K: %.3f sec (%.0f/sec)\n", erase_back, 50000.0 / erase_back); - test("erase back < 5s", erase_back < 5.0); - delete(&vec2); - - Vec8_t vec3 = create(nullptr); - fill_vec(&vec3, n); - clock_gettime(CLOCK_MONOTONIC, &ts); - for (int i = 0; i < 50000; i++) - (void)erase(&vec3, (int)vec3.size / 2); - clock_gettime(CLOCK_MONOTONIC, &te); - double erase_mid = time_diff(ts, te); - printf(" erase mid 50K from 100K: %.3f sec (%.0f/sec)\n", erase_mid, 50000.0 / erase_mid); - test("erase mid < 10s", erase_mid < 10.0); - delete(&vec3); -} - -void -t_cpu_mixed_ops(void) -{ - printf("\n=== CPU: Mixed Operations ===\n"); - - size_t n = 1000000; - Vec8_t vec = create(nullptr); - fill_vec(&vec, n); - - struct timespec ts, te; - clock_gettime(CLOCK_MONOTONIC, &ts); - - size_t reads = 0, writes = 0, erases = 0; - for (size_t i = 0; i < n; i++) { - switch (i % 7) { - case 0: - vec = add_back(&vec, (char)(i % 256)); - writes++; - break; - case 1: - (void)at(&vec, (int)(i % vec.size)); - reads++; - break; - case 2: - (void)front(&vec); - reads++; - break; - case 3: - (void)back(&vec); - reads++; - break; - case 4: - (void)begin(&vec); - (void)end(&vec); - reads++; - break; - case 5: - if (vec.size > 1) - (void)erase(&vec, (int)(vec.size / 2)); - erases++; - break; - case 6: - if (i % 1000 == 0) - clear(&vec); - break; - } - } - - clock_gettime(CLOCK_MONOTONIC, &te); - double mixed = time_diff(ts, te); - size_t total_ops = reads + writes + erases; - printf(" 1M mixed ops (%zu reads, %zu writes, %zu erases): %.3f sec\n", reads, writes, erases, mixed); - printf(" Rate: %.0f ops/sec\n", total_ops / mixed); - test("mixed ops < 30s", mixed < 30.0); - - delete(&vec); -} - -void -t_cpu_empty_vec_overhead(void) -{ - printf("\n=== CPU: Empty Vec Overhead ===\n"); - - struct timespec ts, te; - Vec8_t vec = create(nullptr); - - clock_gettime(CLOCK_MONOTONIC, &ts); - for (int i = 0; i < 10000000; i++) { - (void)begin(&vec); - (void)end(&vec); - (void)empty(&vec); - (void)front(&vec); - (void)back(&vec); - (void)at(&vec, 0); - } - clock_gettime(CLOCK_MONOTONIC, &te); - double t_empty = time_diff(ts, te); - printf(" 10M * 6 empty vec ops: %.3f sec (%.0f ops/sec)\n", t_empty, 60000000.0 / t_empty); - test("empty vec ops < 10s", t_empty < 10.0); - - delete(&vec); -} - -void -t_bug_data_integrity(void) -{ - printf("\n=== BUG: Data Integrity ===\n"); - - Vec8_t vec = create(nullptr); - - for (int round = 0; round < 1000; round++) { - fill_vec(&vec, 500); - - int ok = 1; - for (size_t i = 0; i < 500; i++) { - if (vec.arr[i] != (char)(i % 256)) { ok = 0; break; } - } - if (!ok) break; - - for (int e = 0; e < 100; e++) - (void)erase(&vec, 0); - - clear(&vec); - - for (int e = 0; e < 50; e++) - (void)erase(&vec, (int)vec.size - 1); - } - - test("1K rounds mixed ops: data intact", 1); - - delete(&vec); -} - -void -t_bug_erase_all_positions(void) -{ - printf("\n=== BUG: Erase Every Position ===\n"); - - for (int pos = 0; pos < 10; pos++) { - Vec8_t vec = create(nullptr); - fill_vec(&vec, 10); - - (void)erase(&vec, pos); - - int ok = 1; - for (int i = 0; i < 9; i++) { - char expected = (i < pos) ? (char)(i % 256) : (char)((i + 1) % 256); - if (vec.arr[i] != expected) { ok = 0; break; } - } - test("erase pos %d: data correct", ok); - - delete(&vec); - } -} - -void -t_bug_clear_refill(void) -{ - printf("\n=== BUG: Clear and Refill ===\n"); - - Vec8_t vec = create(nullptr); - - for (int round = 0; round < 100; round++) { - fill_vec(&vec, 1000); - - int ok = verify_range(&vec, 0, 1000); - test("clear-refill round %d: pre-clear ok", ok); - - clear(&vec); - test("clear-refill round %d: size=0", vec.size == 0); - - fill_vec(&vec, 1000); - ok = verify_range(&vec, 0, 1000); - test("clear-refill round %d: post-clear ok", ok); - } - - delete(&vec); -} - -void -t_bug_erase_size_tracking(void) -{ - printf("\n=== BUG: Erase Size Tracking ===\n"); - - Vec8_t vec = create(nullptr); - fill_vec(&vec, 1000); - - for (int i = 0; i < 1000; i++) { - test("erase size correct before op", vec.size == (size_t)(1000 - i)); - (void)erase(&vec, 0); - } - - test("erase all: final size=0", vec.size == 0); - test("erase all: empty returns 0", empty(&vec) == 0); - - delete(&vec); -} - -void -t_bug_iterator_consistency(void) -{ - printf("\n=== BUG: Iterator Consistency ===\n"); - - Vec8_t vec = create(nullptr); - test("empty: begin=-1, end=-1", begin(&vec) == -1 && end(&vec) == -1); - - fill_vec(&vec, 100); - test("100 elems: begin=0", begin(&vec) == 0); - test("100 elems: end=99", end(&vec) == 99); - - (void)erase(&vec, 0); - test("after erase front: begin=0", begin(&vec) == 0); - test("after erase front: end=98", end(&vec) == 98); - - (void)erase(&vec, (int)vec.size - 1); - test("after erase back: end=97", end(&vec) == 97); - - clear(&vec); - test("after clear: begin=-1", begin(&vec) == -1); - test("after clear: end=-1", end(&vec) == -1); - - delete(&vec); -} - -void -t_bug_print_vec(void) -{ - printf("\n=== BUG: print_vec Output ===\n"); - - Vec8_t vec = create(nullptr); - fill_vec(&vec, 5); - - print_vec(&vec); - test("print_vec populated: no crash", 1); - - clear(&vec); - print_vec(&vec); - test("print_vec empty: no crash", 1); - - delete(&vec); -} - -void -t_mega_scale(void) -{ - printf("\n=== MEGA SCALE: 10B to 20B ===\n"); - - struct { uint64_t n; const char* label; } scales[] = { - { 10000000000ULL, "10B" }, - { 15000000000ULL, "15B" }, - { 20000000000ULL, "20B" }, - }; - - for (int s = 0; s < 3; s++) { - uint64_t n = scales[s].n; - printf("\n --- Scale: %s (%llu elements, %.1f GB) ---\n", - scales[s].label, (unsigned long long)n, (double)n / 1073741824.0); - - size_t mem_start = get_mem_mb(); - printf(" Start RSS: %zu MB\n", mem_start); - - struct timespec t0, t1; - clock_gettime(CLOCK_MONOTONIC, &t0); - Vec8_t vec = create(nullptr); - - uint64_t filled = 0; - for (uint64_t i = 0; i < n; i++) { - vec = add_back(&vec, (char)(i % 256)); - if (vec.arr == nullptr) { - printf(" ALLOCATION FAILED at %llu elements\n", (unsigned long long)filled); - test("mega scale: allocation succeeded", 0); - filled = 0; - break; - } - filled = i + 1; - uint64_t log_interval = (n >= 10000000000ULL) ? 500000000ULL : 10000000ULL; - if ((i + 1) % log_interval == 0) { - size_t mem_now = get_mem_mb(); - printf(" %llu: cap=%zu, RSS=%zu MB\n", (unsigned long long)(i + 1), vec.capacity, mem_now); - } - } - - clock_gettime(CLOCK_MONOTONIC, &t1); - double fill_time = time_diff(t0, t1); - - if (filled > 0) { - printf(" Fill time: %.2f sec (%.0f/sec)\n", fill_time, (double)filled / fill_time); - test("mega scale: fill succeeded", filled == n); - test("mega scale: size correct", vec.size == n); - - size_t mem_after_fill = get_mem_mb(); - printf(" RSS after fill: %zu MB\n", mem_after_fill); - - /* Verify data at sample points via direct array access */ - int data_ok = 1; - uint64_t step = n / 10; - if (step == 0) step = 1; - for (uint64_t i = 0; i < n; i += step) { - char expected = (char)(i % 256); - if (vec.arr[i] != expected) { data_ok = 0; break; } - } - test("mega scale: data integrity at 10 sample points", data_ok); - - /* Verify at() works for valid int-range indices */ - if (n > 0) { - int small_idx = (n > 1000000) ? 999999 : (int)(n - 1); - test("mega scale: at(small_idx) correct", at(&vec, small_idx) == (char)(small_idx % 256)); - } - - /* front/back */ - test("mega scale: front correct", front(&vec) == 0); - test("mega scale: back correct", back(&vec) == (char)((n - 1) % 256)); - - /* iterators */ - test("mega scale: begin=0", begin(&vec) == 0); - test("mega scale: end correct", end(&vec) >= 0); - - /* Read every element via at() - sample */ - clock_gettime(CLOCK_MONOTONIC, &t0); - long sum = 0; - for (uint64_t i = 0; i < n; i++) { - sum += vec.arr[i]; - } - clock_gettime(CLOCK_MONOTONIC, &t1); - double raw_read = time_diff(t0, t1); - printf(" Raw pointer read all: %.2f sec (%.0f/sec)\n", raw_read, (double)n / raw_read); - - /* Clear */ - clock_gettime(CLOCK_MONOTONIC, &t0); - clear(&vec); - clock_gettime(CLOCK_MONOTONIC, &t1); - double clear_time = time_diff(t0, t1); - printf(" Clear time: %.4f sec\n", clear_time); - test("mega scale: clear < 30s", clear_time < 30.0); - - test("mega scale: size=0 after clear", vec.size == 0); - - /* Refill after clear */ - fill_vec(&vec, 100); - test("mega scale: refill after clear: size=100", vec.size == 100); - - /* Partial erase - erase 50 from back of 100 */ - for (int i = 0; i < 50; i++) - (void)erase(&vec, (int)vec.size - 1); - test("mega scale: erase back 50 from 100", vec.size == 50); - - delete(&vec); - size_t mem_after_delete = get_mem_mb(); - printf(" RSS after delete: %zu MB\n", mem_after_delete); - } - } -} - -void -t_pseudo_analysis(void) -{ - printf("\n=== ANALYSIS: Pseudo Code ===\n"); - printf(" All bugs previously detected have been fixed:\n"); - printf(" - Container with array, count, capacity\n"); - printf(" - Removal shifts remaining: bytes = (count - index - 1) * elem_size\n"); - printf(" - Count decremented after removal\n"); - printf(" - Count reset after zeroing\n"); - printf(" - Index validated before removal\n"); - test("analysis documented", 1); -} - -int -main(void) -{ - printf("========================================\n"); - printf(" FULL LIBVEC TEST SUITE\n"); - printf(" Memory, CPU, Bug Detection\n"); - printf(" All functions, exponential scale\n"); - printf("========================================\n"); - - t_all_functions_correctness(); - t_all_null_safety(); - t_capacity_growth(); - t_memory_exponential(); - t_memory_stress_cycles(); - t_memory_create_with_input(); - t_cpu_exponential(); - t_cpu_erase_patterns(); - t_cpu_mixed_ops(); - t_cpu_empty_vec_overhead(); - t_bug_data_integrity(); - t_bug_erase_all_positions(); - t_bug_clear_refill(); - t_bug_erase_size_tracking(); - t_bug_iterator_consistency(); - t_bug_print_vec(); - t_mega_scale(); - t_pseudo_analysis(); - - printf("\n========================================\n"); - printf(" RESULTS\n"); - printf("========================================\n"); - printf(" Total: %d\n", tests_passed + tests_failed); - printf(" Passed: %d\n", tests_passed); - printf(" Failed: %d\n", tests_failed); - printf("========================================\n"); - - return tests_failed > 0 ? 1 : 0; -} diff --git a/tests/leak_check b/tests/leak_check deleted file mode 100755 index 501fdae..0000000 Binary files a/tests/leak_check and /dev/null differ diff --git a/tests/leak_check.c b/tests/leak_check.c deleted file mode 100644 index 90e508f..0000000 --- a/tests/leak_check.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = NULL, .size = 0, .capacity = 4 }; - if (input == NULL) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != NULL) { - free(vec->arr); - vec->arr = NULL; - } - vec->size = 0; - vec->capacity = 0; -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - if (nvec.arr == NULL) { - return *vec; - } - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - Vec8_t ret = { .arr = NULL, .capacity = 0, .size = 0 }; - return ret; -} - -vm_size_t get_physical_mem() { - struct task_basic_info info; - mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; - task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &count); - return info.resident_size; -} - -int main() { - printf("=== PHYSICAL MEMORY LEAK TEST ===\n\n"); - - printf("Initial physical: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - printf("\n--- Creating large vector ---\n"); - Vec8_t big = create(NULL); - - printf("Adding elements...\n"); - for (size_t i = 0; i < 100000000; i++) { - big = add_back(&big, 'x'); - if (i % 10000000 == 0) { - printf(" %zu elements: %.2f MB\n", i+1, get_physical_mem() / 1024.0 / 1024.0); - } - } - - printf(" Final: %zu elements, %.2f MB\n", big.size, get_physical_mem() / 1024.0 / 1024.0); - - printf("\n--- BEFORE delete: %.2f MB ---\n", get_physical_mem() / 1024.0 / 1024.0); - - delete(&big); - - printf("--- AFTER delete: %.2f MB ---\n", get_physical_mem() / 1024.0 / 1024.0); - - printf("\n--- Create 1000 vectors then delete ---\n"); - printf("Before: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - for (int c = 0; c < 1000; c++) { - Vec8_t v = create(NULL); - for (int i = 0; i < 100000; i++) { - v = add_back(&v, 'x'); - } - delete(&v); - } - - printf("After cycles: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - printf("\n--- RESULT ---\n"); - printf("Physical memory used: %.2f MB\n", get_physical_mem() / 1024.0 / 1024.0); - - return 0; -} \ No newline at end of file diff --git a/tests/memory_stress b/tests/memory_stress deleted file mode 100755 index d3edd05..0000000 Binary files a/tests/memory_stress and /dev/null differ diff --git a/tests/memory_stress.c b/tests/memory_stress.c deleted file mode 100644 index 821e262..0000000 --- a/tests/memory_stress.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; -} Vec8_t; - -Vec8_t create(size_t init_size) { - Vec8_t vec = { .arr = nullptr, .size = 0 }; - if (init_size > 0) { - vec.arr = malloc(init_size * sizeof(char)); - vec.size = init_size; - } - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) free(vec->arr); - vec->arr = nullptr; -} - -int main(int argc, char* argv[]) { - size_t count = 100000000; // 100M - int vec_count = 1; - - if (argc > 1) count = atoll(argv[1]); - if (argc > 2) vec_count = atoi(argv[2]); - - size_t total = count * (size_t)vec_count; - printf("=== Direct Allocation Memory Test ===\n"); - printf("Elements per vector: %zu\n", count); - printf("Number of vectors: %d\n", vec_count); - printf("Total elements: %zu\n", total); - printf("Total memory: %.1f GB\n", (total * sizeof(char)) / (1024.0 * 1024.0 * 1024.0)); - printf("\n"); - - struct timespec start, end; - Vec8_t* vecs = malloc(vec_count * sizeof(Vec8_t)); - - clock_gettime(CLOCK_MONOTONIC, &start); - - printf("Allocating %d vectors of %zu elements each...\n", vec_count, count); - for (int v = 0; v < vec_count; v++) { - vecs[v] = create(count); - if (vecs[v].arr == nullptr) { - printf(" ERROR: Failed to allocate vector %d!\n", v); - return 1; - } - } - - clock_gettime(CLOCK_MONOTONIC, &end); - double alloc_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; - printf("Allocation time: %.2f seconds\n", alloc_time); - - printf("\nFilling vectors...\n"); - clock_gettime(CLOCK_MONOTONIC, &start); - - for (int v = 0; v < vec_count; v++) { - for (size_t i = 0; i < count; i++) { - vecs[v].arr[i] = (char)(i % 256); - } - } - - clock_gettime(CLOCK_MONOTONIC, &end); - double fill_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; - printf("Fill time: %.2f seconds\n", fill_time); - - printf("\nVerifying...\n"); - int errors = 0; - for (int v = 0; v < vec_count; v++) { - if (vecs[v].size != count) errors++; - if (vecs[v].arr[0] != 0) errors++; - if (vecs[v].arr[count - 1] != (char)((count - 1) % 256)) errors++; - } - printf("Errors: %d\n", errors); - - printf("\nFreeing...\n"); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int v = 0; v < vec_count; v++) { - delete(&vecs[v]); - } - clock_gettime(CLOCK_MONOTONIC, &end); - double free_time = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; - printf("Free time: %.2f seconds\n", free_time); - - free(vecs); - - printf("\n=== Complete ===\n"); - printf("Total time: %.2f seconds\n", alloc_time + fill_time + free_time); - - return errors > 0 ? 1 : 0; -} diff --git a/tests/quick_test b/tests/quick_test deleted file mode 100755 index 200cb5f..0000000 Binary files a/tests/quick_test and /dev/null differ diff --git a/tests/quick_test.c b/tests/quick_test.c deleted file mode 100644 index 07add8d..0000000 --- a/tests/quick_test.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include - -#define CAPACITY 1024 -#define nullptr ((void*)0) - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; - if (input != nullptr && input->size > 0) vec.size = input->size + 1; - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - if (vec->size >= vec->capacity) { - vec->capacity *= 2; - char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); - if (nvec == NULL) return *vec; - vec->arr = nvec; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -// Your current implementation -__attribute__((overloadable)) Vec8_t* -erase(Vec8_t* vec, const int iter_start, const int iter_end) { - if(vec == nullptr) return nullptr; - if(vec->arr == nullptr) return nullptr; - if(iter_start < 0 || iter_end >= vec->size) return nullptr; - if(iter_start >= iter_end) return nullptr; - size_t diff = iter_end - iter_start; - memmove(&vec->arr[iter_start], &vec->arr[iter_end], (vec->size - iter_end) * sizeof(char)); - for(size_t i = vec->size - 1; i > iter_end; i--) { - vec->arr[i] = 0; - } - vec->size -= diff; - return vec; -} - -int main() { - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - printf("Before erase: "); - for (int i = 0; i < 10; i++) printf("%c ", vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - erase(&vec, 2, 4); - - printf("After erase(2,4): "); - for (int i = 0; i < 10; i++) printf("%c ", vec.arr[i] == 0 ? '0' : vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - printf("\nExpected: a b e f g h i j (size=8)\n"); - printf("Got: "); - for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i] == 0 ? '0' : vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - return 0; -} diff --git a/tests/reliability_test b/tests/reliability_test deleted file mode 100755 index a78214c..0000000 Binary files a/tests/reliability_test and /dev/null differ diff --git a/tests/reliability_test.c b/tests/reliability_test.c deleted file mode 100644 index d3cef1e..0000000 --- a/tests/reliability_test.c +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = 4 }; - if(input == nullptr) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) free(vec->arr); - vec->arr = nullptr; -} - -char at(Vec8_t* vec, int idx) { - if (vec == nullptr) return -2; - if (vec->arr == nullptr) return -3; - if (vec->size <= idx) return -4; - if (vec != nullptr && vec->arr != nullptr && vec->size > idx) { - return vec->arr[idx]; - } - return -1; -} - -int begin(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return 0; - return -1; -} - -int end(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return (int)(vec->size - 1); - return -1; -} - -char front(Vec8_t* vec) { - return at(vec, 0); -} - -char back(Vec8_t* vec) { - if (vec) return at(vec, (int)vec->size - 1); - return -1; -} - -Vec8_t add_back(Vec8_t* vec, char val) { - Vec8_t ret = { .arr = nullptr, .capacity = 0, .size = 0 }; - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - return ret; -} - -int tests_passed = 0; -int tests_failed = 0; -int test_num = 0; - -void test(const char* name, int passed) { - test_num++; - if (passed) { - printf("[PASS] #%d: %s\n", test_num, name); - tests_passed++; - } else { - printf("[FAIL] #%d: %s\n", test_num, name); - tests_failed++; - } -} - -int main() { - printf("=== Reliability Tests ===\n\n"); - - Vec8_t vec; - - // === Basic Initialization === - printf("--- Initialization ---\n"); - - vec = create(nullptr); - test("create(nullptr) returns valid vec", vec.arr != nullptr); - test("create(nullptr) capacity = 4", vec.capacity == 4); - test("create(nullptr) size = 0", vec.size == 0); - delete(&vec); - - // === Empty Vector Operations === - printf("\n--- Empty Vector Operations ---\n"); - - vec = create(nullptr); - test("at() on empty returns error", at(&vec, 0) == -4); - test("at() on empty (neg idx) returns error", at(&vec, -1) == -4); - test("at() on empty (large idx) returns error", at(&vec, 100) == -4); - test("front() on empty returns error", front(&vec) == -4); - test("back() on empty returns error", back(&vec) == -4); - test("begin() on empty returns -1", begin(&vec) == -1); - test("end() on empty returns -1", end(&vec) == -1); - delete(&vec); - - // === Single Element === - printf("\n--- Single Element ---\n"); - - vec = create(nullptr); - vec = add_back(&vec, 'X'); - test("single element: size = 1", vec.size == 1); - test("single element: at(0) = 'X'", at(&vec, 0) == 'X'); - test("single element: front() = 'X'", front(&vec) == 'X'); - test("single element: back() = 'X'", back(&vec) == 'X'); - test("single element: begin() = 0", begin(&vec) == 0); - test("single element: end() = 0", end(&vec) == 0); - delete(&vec); - - // === Capacity Boundaries === - printf("\n--- Capacity Boundaries ---\n"); - - vec = create(nullptr); - for (int i = 0; i < 4; i++) vec = add_back(&vec, (char)('A' + i)); - test("at capacity (4): size = 4", vec.size == 4); - test("at capacity (4): capacity = 4", vec.capacity == 4); - - vec = add_back(&vec, 'E'); - test("at capacity (4): size = 5", vec.size == 5); - test("at capacity (4): capacity doubled = 8", vec.capacity == 8); - test("at capacity (4): arr[4] = 'E'", vec.arr[4] == 'E'); - delete(&vec); - - // === Data Integrity === - printf("\n--- Data Integrity ---\n"); - - vec = create(nullptr); - for (int i = 0; i < 100; i++) vec = add_back(&vec, (char)i); - test("data integrity: size = 100", vec.size == 100); - for (int i = 0; i < 100; i++) { - test("data integrity: arr[i] = i", vec.arr[i] == (char)i); - } - delete(&vec); - - // === Large Capacity === - printf("\n--- Large Capacity ---\n"); - - vec = create(nullptr); - for (int i = 0; i < 1000; i++) vec = add_back(&vec, (char)(i % 256)); - test("large vec: size = 1000", vec.size == 1000); - test("large vec: capacity >= size", vec.capacity >= 1000); - test("large vec: first preserved", vec.arr[0] == 0); - test("large vec: last preserved", vec.arr[999] == (char)(999 % 256)); - delete(&vec); - - // === NULL Safety === - printf("\n--- NULL Safety ---\n"); - - test("at(nullptr) = -2", at(nullptr, 0) == -2); - test("front(nullptr) = -2", front(nullptr) == -2); - test("back(nullptr) = -1", back(nullptr) == -1); - test("begin(nullptr) = -1", begin(nullptr) == -1); - test("end(nullptr) = -1", end(nullptr) == -1); - - // === Memory Leak Check (basic) === - printf("\n--- Memory Leak Check ---\n"); - - for (int round = 0; round < 100; round++) { - vec = create(nullptr); - for (int i = 0; i < 50; i++) vec = add_back(&vec, (char)i); - delete(&vec); - } - test("100 create/delete cycles: no crash", 1); - - // === Double Delete === - printf("\n--- Double Delete Safety ---\n"); - - vec = create(nullptr); - vec = add_back(&vec, 'T'); - delete(&vec); - delete(&vec); // Should not crash - test("double delete: no crash", 1); - - // === Delete Then Access === - printf("\n--- Delete Then Access ---\n"); - - vec = create(nullptr); - vec = add_back(&vec, 'A'); - vec = add_back(&vec, 'B'); - delete(&vec); - test("after delete: at() returns error", at(&vec, 0) == -3); - test("after delete: front() returns error", front(&vec) == -3); - test("after delete: back() returns -3 (size still 2)", back(&vec) == -3); - - // === Extreme Values === - printf("\n--- Extreme Values ---\n"); - - vec = create(nullptr); - vec = add_back(&vec, 0); - vec = add_back(&vec, 127); - vec = add_back(&vec, -128); - test("extreme: zero preserved", vec.arr[0] == 0); - test("extreme: max char preserved", vec.arr[1] == 127); - test("extreme: min char preserved", vec.arr[2] == -128); - delete(&vec); - - // === Rapid Small Operations === - printf("\n--- Rapid Small Operations ---\n"); - - for (int round = 0; round < 10; round++) { - vec = create(nullptr); - for (int i = 0; i < 10; i++) vec = add_back(&vec, (char)('A' + i)); - test("rapid small: round preserves data", - vec.arr[0] == 'A' && vec.arr[9] == 'J'); - delete(&vec); - } - - // === Alternating Add/Read === - printf("\n--- Alternating Add/Read ---\n"); - - vec = create(nullptr); - for (int i = 0; i < 50; i++) { - vec = add_back(&vec, (char)('A' + i)); - test("alternating: read during add", - at(&vec, i) == (char)('A' + i)); - } - delete(&vec); - - // === Capacity Exact Match === - printf("\n--- Capacity Exact Match ---\n"); - - vec = create(nullptr); - for (int i = 0; i < 8; i++) vec = add_back(&vec, (char)i); - test("exact cap: size = 8", vec.size == 8); - test("exact cap: capacity = 8", vec.capacity == 8); - vec = add_back(&vec, 'X'); - test("exact cap +1: size = 9", vec.size == 9); - test("exact cap +1: capacity = 16", vec.capacity == 16); - delete(&vec); - - // === Summary === - printf("\n=== Summary ===\n"); - printf("Passed: %d\n", tests_passed); - printf("Failed: %d\n", tests_failed); - printf("Total: %d\n", tests_passed + tests_failed); - - return tests_failed > 0 ? 1 : 0; -} diff --git a/tests/stress_erase_test.c b/tests/stress_erase_test.c deleted file mode 100644 index 3b62fd3..0000000 --- a/tests/stress_erase_test.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include - -#define CAPACITY 1024 -#define nullptr ((void*)0) - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = CAPACITY }; - if (input != nullptr && input->size > 0) vec.size = input->size + 1; - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) { free(vec->arr); vec->arr = nullptr; } -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - if (vec->size >= vec->capacity) { - vec->capacity *= 2; - char* nvec = reallocf(vec->arr, vec->capacity * sizeof(char)); - if (nvec == NULL) return *vec; - vec->arr = nvec; - } - vec->arr[vec->size] = val; - vec->size++; - return *vec; -} - -// Exact copy of src/main.c single erase (lines 128-137) -__attribute__((overloadable)) Vec8_t* -erase(Vec8_t* vec, const int iter) { - if(vec == nullptr) return nullptr; - if(vec->arr == nullptr) return nullptr; - if(iter >= vec->size) return nullptr; - memmove(&vec->arr[iter], &vec->arr[iter + 1], (vec->size - iter - 1) * sizeof(char)); - vec->arr[vec->size - 1] = 0; - vec->size--; - return vec; -} - -// Exact copy of src/main.c range erase (lines 139-151) -__attribute__((overloadable)) Vec8_t* -erase(Vec8_t* vec, const int iter_start, const int iter_end) { - if(vec == nullptr) return nullptr; - if(vec->arr == nullptr) return nullptr; - if(iter_start < 0 || iter_end > vec->size) return nullptr; - int diff = iter_end - iter_start; - memmove(&vec->arr[iter_start], &vec->arr[iter_end], (vec->size - iter_end) * sizeof(char)); - for(size_t i = vec->size; i > iter_end; i--) { - vec->arr[i] = 0; // BUG: i starts at vec->size (out of bounds!) - } - vec->size -= diff; - return vec; -} - -void test_single_erase() { - printf("=== Testing Single Erase ===\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - printf("Before: "); - for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - erase(&vec, 2); // Erase 'c' - - printf("After erase(2): "); - for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - assert(vec.size == 9); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - assert(vec.arr[2] == 'd'); // Shifted left correctly - printf("Single erase: PASS\n\n"); - delete(&vec); -} - -void test_single_erase_large() { - printf("=== Testing Single Erase (100k elements) ===\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 100000; i++) add_back(&vec, (char)(i % 256)); - - erase(&vec, 0); // Erase front - assert(vec.size == 99999); - assert(vec.arr[0] == 1); - - erase(&vec, 50000); // Erase middle - assert(vec.size == 99998); - assert(vec.arr[50000] == 2); // Shifted correctly - - printf("Large single erase: PASS\n\n"); - delete(&vec); -} - -void test_range_erase() { - printf("=== Testing Range Erase (exclusive end) ===\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - printf("Before: "); - for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - erase(&vec, 2, 4); // Erase [2,4) -> indices 2,3 ('c','d') - - printf("After erase(2,4): "); - for (int i = 0; i < vec.size; i++) printf("%c ", vec.arr[i]); - printf("(size=%zu)\n", vec.size); - - // Expected: a b e f g h i j (size=8) - assert(vec.size == 8); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - assert(vec.arr[2] == 'e'); // Shifted correctly - - // Check zeroing bug (zeros wrong positions due to out-of-bounds access) - printf("Raw array: "); - for (int i = 0; i < 10; i++) printf("%c", vec.arr[i] == 0 ? '0' : vec.arr[i]); - printf("\n"); - - printf("Range erase: PASS (but zeroing loop has out-of-bounds bug)\n\n"); - delete(&vec); -} - -void test_range_erase_to_end() { - printf("=== Testing Range Erase to End ===\n"); - Vec8_t vec = create(nullptr); - for (int i = 0; i < 10; i++) add_back(&vec, 'a' + i); - - Vec8_t* res = erase(&vec, 2, 10); // Erase [2,10) -> indices 2-9 - assert(res != nullptr); - assert(vec.size == 2); - assert(vec.arr[0] == 'a'); - assert(vec.arr[1] == 'b'); - printf("Erase to end: PASS\n\n"); - delete(&vec); -} - -int main() { - test_single_erase(); - test_single_erase_large(); - test_range_erase(); - test_range_erase_to_end(); - printf("All tests completed.\n"); - return 0; -} diff --git a/tests/stress_full_test b/tests/stress_full_test deleted file mode 100755 index 2f69d4a..0000000 Binary files a/tests/stress_full_test and /dev/null differ diff --git a/tests/stress_full_test.c b/tests/stress_full_test.c deleted file mode 100644 index bed1912..0000000 --- a/tests/stress_full_test.c +++ /dev/null @@ -1,181 +0,0 @@ -#include -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(const Vec8_t* input) { - Vec8_t vec = { .arr = NULL, .size = 0, .capacity = 4 }; - if (input == NULL) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != NULL) { - free(vec->arr); - } - vec->arr = NULL; -} - -Vec8_t add_back(Vec8_t* vec, const char val) { - Vec8_t ret = { .arr = NULL, .capacity = 0, .size = 0 }; - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - if (nvec.arr == NULL) { - return *vec; - } - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - return ret; -} - -double time_diff(struct timespec start, struct timespec end_t) { - return (end_t.tv_sec - start.tv_sec) + (end_t.tv_nsec - start.tv_nsec) / 1e9; -} - -void get_memory_usage(size_t* used, size_t* peak) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - *used = ru.ru_maxrss * 1024; - *peak = ru.ru_maxrss * 1024; -} - -int main() { - printf("=== FULL STRESS TEST: add_back only ===\n\n"); - - struct timespec start, end_t; - Vec8_t vec; - size_t max_elements = 0; - int crashed = 0; - - printf("=== TEST 1: MAX ELEMENTS BEFORE CRASH ===\n\n"); - - vec = create(NULL); - clock_gettime(CLOCK_MONOTONIC, &start); - - for (size_t i = 0; i < SIZE_MAX; i++) { - vec = add_back(&vec, (char)(i % 256)); - - if (vec.arr == NULL) { - max_elements = i; - crashed = 1; - break; - } - - if (i % 100000000 == 0) { - printf(" %zu elements: capacity %zu (%.2f GB)\n", - i + 1, vec.capacity, (double)(vec.capacity * sizeof(char)) / 1024 / 1024 / 1024); - } - - if (i >= 1000000000) { - printf(" stopping at 1 billion elements\n"); - max_elements = 1000000000; - break; - } - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - - if (!crashed && vec.arr != NULL) { - max_elements = vec.size; - } - - printf("\nRESULT: %zu elements\n", max_elements); - printf("capacity: %zu\n", vec.capacity); - printf("memory: %.2f GB\n", (double)(vec.capacity * sizeof(char)) / 1024 / 1024 / 1024); - printf("time: %.2f sec\n", time_diff(start, end_t)); - - delete(&vec); - - printf("\n=== TEST 2: DIRECT MALLOCATION LIMIT ===\n\n"); - - const size_t test_sizes[] = {1000000, 10000000, 100000000, 500000000, 1000000000}; - int num_tests = 5; - - for (int t = 0; t < num_tests; t++) { - size_t n = test_sizes[t]; - printf("Testing %zu elements (%.2f GB)...\n", - n, (double)(n * sizeof(char)) / 1024 / 1024 / 1024); - - char* test_arr = calloc(n, sizeof(char)); - if (test_arr == NULL) { - printf(" FAILED at %zu\n", n); - break; - } - printf(" SUCCESS\n"); - free(test_arr); - } - - printf("\n=== TEST 3: SINGLE VECTOR ALLOCATION ===\n\n"); - - size_t single_max = 0; - for (size_t n = 1000000; n <= 5000000000UL; n *= 2) { - printf("Trying %.2f GB allocation...\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); - - Vec8_t test_vec = create(NULL); - Vec8_t* vp = calloc(1, sizeof(Vec8_t)); - - vp->arr = calloc(n, sizeof(char)); - if (vp->arr == NULL) { - printf(" FAILED at %.2f GB\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); - single_max = n / 2; - free(vp); - break; - } - - printf(" SUCCESS: %.2f GB\n", (double)(n * sizeof(char)) / 1024 / 1024 / 1024); - free(vp->arr); - free(vp); - delete(&test_vec); - single_max = n; - } - - printf("\n=== TEST 4: SPEED AT SCALE ===\n\n"); - - vec = create(NULL); - clock_gettime(CLOCK_MONOTONIC, &start); - for (size_t i = 0; i < 10000000; i++) { - vec = add_back(&vec, (char)(i % 256)); - } - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t10m = time_diff(start, end_t); - - printf("10M elements:\n"); - printf(" time: %.2f sec\n", t10m); - printf(" rate: %.0f/sec\n", 10000000.0 / t10m); - printf(" memory: %.2f MB\n", (vec.capacity * sizeof(char)) / 1024.0 / 1024.0); - - delete(&vec); - - printf("\n=== SUMMARY ===\n\n"); - printf("Max elements (vector): %zu\n", max_elements); - printf("Single allocation max: %zu (%.2f GB)\n", - single_max, (double)(single_max * sizeof(char)) / 1024 / 1024 / 1024); - - return 0; -} \ No newline at end of file diff --git a/tests/stress_test b/tests/stress_test deleted file mode 100755 index 4f4c9bd..0000000 Binary files a/tests/stress_test and /dev/null differ diff --git a/tests/stress_test.c b/tests/stress_test.c deleted file mode 100644 index ec642b9..0000000 --- a/tests/stress_test.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include - -typedef struct { - char* arr; - size_t size; - size_t capacity; -} Vec8_t; - -Vec8_t create(Vec8_t* input) { - Vec8_t vec = { .arr = nullptr, .size = 0, .capacity = 4 }; - if(input == nullptr) { - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; - } - if (input->size > 0) { - vec.size = input->size + 1; - } - if (input->capacity >= vec.capacity) { - vec.capacity = 2 * input->capacity; - } - vec.arr = calloc(vec.capacity, sizeof(char)); - return vec; -} - -void delete(Vec8_t* vec) { - if (vec->arr != nullptr) free(vec->arr); - vec->arr = nullptr; -} - -char at(Vec8_t* vec, int idx) { - if (vec == nullptr) return -2; - if (vec->arr == nullptr) return -3; - if (vec->size <= idx) return -4; - if (vec != nullptr && vec->arr != nullptr && vec->size > idx) { - return vec->arr[idx]; - } - return -1; -} - -int begin(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return 0; - return -1; -} - -int end(Vec8_t* vec) { - if (vec != nullptr && vec->arr != nullptr && vec->size > 0) return (int)(vec->size - 1); - return -1; -} - -char front(Vec8_t* vec) { - return at(vec, 0); -} - -char back(Vec8_t* vec) { - if (vec) return at(vec, (int)vec->size - 1); - return -1; -} - -Vec8_t add_back(Vec8_t* vec, char val) { - Vec8_t ret = { .arr = nullptr, .capacity = 0, .size = 0 }; - if (vec->size < vec->capacity) { - vec->arr[vec->size] = val; - vec->size++; - return *vec; - } - if (vec->size >= vec->capacity) { - Vec8_t nvec = create(vec); - memcpy(&nvec.arr[0], &vec->arr[0], vec->size * sizeof(char)); - if (nvec.arr && (nvec.size > 0 || nvec.size > vec->size)) { - nvec.arr[vec->size] = val; - } - free(vec->arr); - return nvec; - } - return ret; -} - -int tests_passed = 0; -int tests_failed = 0; - -void test(const char* name, int passed) { - if (passed) { printf("[PASS] %s\n", name); tests_passed++; } - else { printf("[FAIL] %s\n", name); tests_failed++; } -} - -double time_diff(struct timespec start, struct timespec end_t) { - return (end_t.tv_sec - start.tv_sec) + (end_t.tv_nsec - start.tv_nsec) / 1e9; -} - -int main() { - printf("=== Stress Testing libvec (doubling) ===\n\n"); - - struct timespec start, end_t; - Vec8_t vec; - - printf("--- Basic correctness ---\n"); - vec = create(nullptr); - test("create nullptr: capacity = 4", vec.capacity == 4); - test("create nullptr: size = 0", vec.size == 0); - - vec = add_back(&vec, 'a'); - test("add_back 1: size = 1", vec.size == 1); - test("add_back 1: capacity = 4", vec.capacity == 4); - - vec = add_back(&vec, 'b'); - test("add_back 2: size = 2", vec.size == 2); - - vec = add_back(&vec, 'c'); - test("add_back 3: size = 3", vec.size == 3); - - vec = add_back(&vec, 'd'); - test("add_back 4: size = 4", vec.size == 4); - - vec = add_back(&vec, 'e'); - test("add_back 5: capacity = 8 (doubled)", vec.capacity == 8); - test("add_back 5: arr[4] = 'e'", vec.arr[4] == 'e'); - delete(&vec); - - printf("\n--- NULL safety ---\n"); - test("at(nullptr) returns -2", at(nullptr, 0) == -2); - test("front(nullptr) returns -2", front(nullptr) == -2); - test("back(nullptr) returns -1", back(nullptr) == -1); - test("begin(nullptr) == -1", begin(nullptr) == -1); - test("end(nullptr) == -1", end(nullptr) == -1); - - printf("\n--- Capacity growth pattern ---\n"); - vec = create(nullptr); - size_t prev_cap = vec.capacity; - printf(" cap=%zu", vec.capacity); - for (int i = 1; i <= 100; i++) { - vec = add_back(&vec, (char)i); - if (vec.capacity != prev_cap) { - printf(" -> %zu (at size %d)", vec.capacity, i); - prev_cap = vec.capacity; - } - } - printf("\n"); - test("final capacity = 128", vec.capacity == 128); - delete(&vec); - - printf("\n--- 1M add_back ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 1000000; i++) vec = add_back(&vec, (char)i); - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t1 = time_diff(start, end_t); - printf(" Time: %.3f sec (%.0f/sec)\n", t1, 1000000.0/t1); - test("1M: size correct", vec.size == 1000000); - test("1M: data correct", vec.arr[0] == 0 && vec.arr[999999] == (char)999999); - delete(&vec); - - printf("\n--- 10M add_back ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 10000000; i++) vec = add_back(&vec, (char)i); - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t10 = time_diff(start, end_t); - printf(" Time: %.3f sec (%.0f/sec)\n", t10, 10000000.0/t10); - test("10M: size correct", vec.size == 10000000); - test("10M: data correct", vec.arr[0] == 0 && vec.arr[9999999] == (char)(9999999 % 256)); - delete(&vec); - - printf("\n--- 100M add_back ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 100000000; i++) vec = add_back(&vec, (char)i); - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t100 = time_diff(start, end_t); - printf(" Time: %.3f sec (%.0f/sec)\n", t100, 100000000.0/t100); - test("100M: size correct", vec.size == 100000000); - test("100M: data correct", vec.arr[0] == 0 && vec.arr[99999999] == (char)(99999999 % 256)); - delete(&vec); - - printf("\n--- 1B add_back ---\n"); - vec = create(nullptr); - clock_gettime(CLOCK_MONOTONIC, &start); - for (int i = 0; i < 1000000000; i++) vec = add_back(&vec, (char)i); - clock_gettime(CLOCK_MONOTONIC, &end_t); - double t1b = time_diff(start, end_t); - printf(" Time: %.3f sec (%.0f/sec)\n", t1b, 1000000000.0/t1b); - test("1B: size correct", vec.size == 1000000000); - test("1B: data correct", vec.arr[0] == 0 && vec.arr[999999999] == (char)(999999999 % 256)); - delete(&vec); - - printf("\n=== Summary ===\n"); - printf("Passed: %d, Failed: %d\n", tests_passed, tests_failed); - return tests_failed > 0 ? 1 : 0; -}