(parts of the README written by AI, it may have errors in it, trust chunk-array.h for documentation).
A flexible, high-performance C library for managing chunked arrays with support for custom memory allocators and cache-aligned memory access. This data structure is designed to grow dynamically by allocating memory in fixed-size blocks (chunks), minimizing frequent reallocations.
The pointers within the array are stable as it kind of behave like an arena allocator on itself. If ordered and then modified, the order might not be kept (ck_array_remove does swap value within array).
- Dynamic Resizing: Automatically grows to accommodate new elements using a tiered chunk/block architecture.
- Custom Allocators: Support for custom memory management via the
ck_memory_tinterface, allowing for integration with specialized memory pools or tracking systems. - Cache Friendly: Configurable block sizes and alignment to optimize for CPU cache performance.
- Performance Focused: Optimized
pushandpopoperations, with built-in performance testing tools. - Safety: Built-in assertions and bounds checking for development stability.
The project uses the Check unit testing framework for its test suite.
gccpkg-configlibcheck
Build the test suite using the provided Makefile:
make
To remove build artifacts:
make clean
Create a new array by specifying the item size and optional configuration options.
#include "chunk-array.h"
struct ck_array_opts opts = {
.blk_size = 4096, // Size of each data block
.chk_size = 32, // Initial number of chunk pointers
.aln_size = 16 // Memory alignment
};
ck_array_t *array = ck_array_new(sizeof(int), NULL, opts);int val = 42;
// Push an item to the end
ck_array_push(array, &val);
// Get an item by index
int *retrieved = (int *)ck_array_get(array, 0);
// Set an item at a specific index (will grow the array if needed)
ck_array_set(array, &val, 10);
// Pop the last item
int *last = (int *)ck_array_pop(array);
// Get current size
size_t size = ck_array_size(array);
// Cleanup
ck_array_destroy(array);If you do something like
int val = 0;
void *ptr = ck_array_set(array, 1, &val);
*(int *)ptr = 4;The content in the array is modified, you don't need to set it back. But if you do :
int val = 0;
int val3 = 10;
ck_array_set(array, 1, &val);
ck_array_push(array, &val3);
void *ptr = ck_array_get(array, 1);
ck_array_remove(array, 1);
*(int *)ptr == val3;In fact, ck_array_remove takes the last value from the array, overwrite the content at specified index with that value and reduce the array size by one. Implementation of remove looks like :
void *ptr = ck_array_pop(array);
ck_array_set(array, ptr, 1);The library uses the following default values if not specified:
- Default Block Size: 4096 bytes
- Default Chunk Size: 32 pointers
- Default Alignment:
max_align_t
src/include/chunk-array.h: Core API definitions and inline functions.src/chunk-array.c: Implementation of memory management and indexing logic.src/ck-array-test.c: Unit tests and performance benchmarks.Makefile: Build configuration for the test suite.