mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-03 08:03:38 +08:00
Complete C implementation of the indexing pipeline (src/), parallel worker pool, graph buffer with merge support, SQLite writer, and 1893-test suite. Linter setup: zero warnings from clang-tidy (all checks enabled, no NOLINT suppressions), cppcheck, and clang-format. All issues fixed at source — proper headers for external linkage, GROW_ARRAY macro restructured to eliminate type parameter, null-deref paths guarded, named intermediates for suspicious-argument checks.
106 lines
5.1 KiB
C
106 lines
5.1 KiB
C
/*
|
|
* dyn_array.h — Type-safe growable arrays via macros (header-only).
|
|
*
|
|
* Usage:
|
|
* CBM_DYN_ARRAY(int) nums = {0}; // zero-init
|
|
* cbm_da_push(&nums, 42);
|
|
* cbm_da_push(&nums, 99);
|
|
* for (int i = 0; i < nums.count; i++)
|
|
* printf("%d\n", nums.items[i]);
|
|
* cbm_da_free(&nums);
|
|
*
|
|
* Design:
|
|
* - Items are contiguous in memory (cache-friendly)
|
|
* - Grows by 2x (amortized O(1) push)
|
|
* - Uses realloc — NOT arena-compatible (use CBMDefArray etc. for arena)
|
|
* - Header-only: no .c file needed
|
|
*/
|
|
#ifndef CBM_DYN_ARRAY_H
|
|
#define CBM_DYN_ARRAY_H
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* Declare a dynamic array type for a given element type. */
|
|
#define CBM_DYN_ARRAY(T) \
|
|
struct { \
|
|
T *items; \
|
|
int count; \
|
|
int cap; \
|
|
}
|
|
|
|
/* Push an element. Grows by 2x when full. */
|
|
#define cbm_da_push(da, item) \
|
|
do { \
|
|
if ((da)->count >= (da)->cap) { \
|
|
int _new_cap = (da)->cap ? (da)->cap * 2 : 8; \
|
|
void *_new = realloc((da)->items, (size_t)_new_cap * sizeof(*(da)->items)); \
|
|
if (!_new) \
|
|
break; \
|
|
(da)->items = _new; \
|
|
(da)->cap = _new_cap; \
|
|
} \
|
|
(da)->items[(da)->count++] = (item); \
|
|
} while (0)
|
|
|
|
/* Push an element with a pointer return (for in-place init). */
|
|
#define cbm_da_push_ptr(da) \
|
|
(((da)->count >= (da)->cap \
|
|
? ((void)((da)->cap = (da)->cap ? (da)->cap * 2 : 8), \
|
|
(void)((da)->items = realloc((da)->items, (size_t)(da)->cap * sizeof(*(da)->items)))) \
|
|
: (void)0), \
|
|
&(da)->items[(da)->count++])
|
|
|
|
/* Pop last element. Returns the element. Undefined if empty. */
|
|
#define cbm_da_pop(da) ((da)->items[--(da)->count])
|
|
|
|
/* Get last element without removing. Undefined if empty. */
|
|
#define cbm_da_last(da) ((da)->items[(da)->count - 1])
|
|
|
|
/* Clear without freeing (reset count to 0). */
|
|
#define cbm_da_clear(da) ((da)->count = 0)
|
|
|
|
/* Free all memory. */
|
|
#define cbm_da_free(da) \
|
|
do { \
|
|
free((da)->items); \
|
|
(da)->items = NULL; \
|
|
(da)->count = 0; \
|
|
(da)->cap = 0; \
|
|
} while (0)
|
|
|
|
/* Reserve capacity (grow if needed, never shrink). */
|
|
#define cbm_da_reserve(da, n) \
|
|
do { \
|
|
if ((n) > (da)->cap) { \
|
|
void *_new = realloc((da)->items, (size_t)(n) * sizeof(*(da)->items)); \
|
|
if (_new) { \
|
|
(da)->items = _new; \
|
|
(da)->cap = (n); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Insert at index, shifting elements right. */
|
|
#define cbm_da_insert(da, idx, item) \
|
|
do { \
|
|
cbm_da_push(da, item); /* ensure space */ \
|
|
if ((idx) < (da)->count - 1) { \
|
|
memmove(&(da)->items[(idx) + 1], &(da)->items[(idx)], \
|
|
(size_t)((da)->count - 1 - (idx)) * sizeof(*(da)->items)); \
|
|
(da)->items[(idx)] = (item); \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Remove at index, shifting elements left. */
|
|
#define cbm_da_remove(da, idx) \
|
|
do { \
|
|
if ((idx) < (da)->count - 1) { \
|
|
memmove(&(da)->items[(idx)], &(da)->items[(idx) + 1], \
|
|
(size_t)((da)->count - 1 - (idx)) * sizeof(*(da)->items)); \
|
|
} \
|
|
(da)->count--; \
|
|
} while (0)
|
|
|
|
#endif /* CBM_DYN_ARRAY_H */
|