Update AGENTS.md
This commit is contained in:
@@ -28,6 +28,9 @@ All code follows the patterns established in `src/wapp/`. The project prefix is
|
|||||||
| Internal/static funcs | `_` + camelCase | `_resolveTopology`, `_execCmd` |
|
| Internal/static funcs | `_` + camelCase | `_resolveTopology`, `_execCmd` |
|
||||||
| File-scope globals | `_` + camelCase | `_default_allocator` |
|
| File-scope globals | `_` + camelCase | `_default_allocator` |
|
||||||
| File-scope constants | SCREAMING_SNAKE | `MAX_NODE_NAME` |
|
| File-scope constants | SCREAMING_SNAKE | `MAX_NODE_NAME` |
|
||||||
|
| Variables | snake_case | `vertex_count`, `edge_node` |
|
||||||
|
|
||||||
|
- **Variable names**: Prefer descriptive names (e.g. `vertex_count` over `vc`, `edge_node` over `en`). Short names (`i`, `j`, `n`) are acceptable only in tight loop counters or trivial index variables. Avoid single-letter names in non-trivial scopes, and avoid abbreviated names that require the reader to hold a mental dictionary.
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
@@ -118,6 +121,55 @@ prefer SoA layouts, batch processing, and minimise pointer chasing. Keep
|
|||||||
the DAG in contiguous arrays (e.g. adjacency lists packed in flat buffers)
|
the DAG in contiguous arrays (e.g. adjacency lists packed in flat buffers)
|
||||||
rather than individually allocated linked structures.
|
rather than individually allocated linked structures.
|
||||||
|
|
||||||
|
### Graph / adjacency lists
|
||||||
|
|
||||||
|
Adjacency list nodes must be **separately allocated from the vertex array**.
|
||||||
|
Never use the vertex struct itself as a linked-list node in another vertex's
|
||||||
|
adjacency chain — that shares the `next` pointer between two roles (vertex state
|
||||||
|
vs. edge linking) and causes edges to splice into unintended chains.
|
||||||
|
|
||||||
|
```c
|
||||||
|
// correct — per-edge copy on the arena
|
||||||
|
static void addEdge(PrGraph *g, const WpAllocator *alloc, u64 from, u64 to) {
|
||||||
|
PrVertex *src = &g->vertices[from];
|
||||||
|
PrVertex *dst = wpMemAllocatorAlloc(alloc, sizeof(PrVertex));
|
||||||
|
if (!dst) { /* handle OOM */ return; }
|
||||||
|
dst->id = g->vertices[to].id;
|
||||||
|
dst->value = g->vertices[to].value;
|
||||||
|
dst->next = src->next;
|
||||||
|
src->next = dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrong — reuses the destination vertex as the list node
|
||||||
|
static void addEdge_bad(PrGraph *g, u64 from, u64 to) {
|
||||||
|
PrVertex *src = &g->vertices[from];
|
||||||
|
PrVertex *dest = &g->vertices[to];
|
||||||
|
dest->next = src->next;
|
||||||
|
src->next = dest; // overwrites dest->next used elsewhere
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Arena bump allocation (`wpMemAllocatorAlloc`) is the natural fit for building
|
||||||
|
graph structures: per-edge nodes live in the arena and are freed in one shot
|
||||||
|
when the arena is destroyed.
|
||||||
|
|
||||||
|
Always NULL-check the result of `wpMemAllocatorAlloc` — even arena allocators
|
||||||
|
can fail if the backing buffer is exhausted.
|
||||||
|
|
||||||
|
### WpArray usage
|
||||||
|
|
||||||
|
| Scenario | API | Size must be… |
|
||||||
|
|----------|-----|---------------|
|
||||||
|
| Stack (local, short-lived) | `wpArrayWithCapacity` | compile-time constant |
|
||||||
|
| Heap (arena-backed) | `wpArrayAllocCapacity` | runtime value |
|
||||||
|
|
||||||
|
`wpArrayWithCapacity` creates a VLA-like compound literal on the stack —
|
||||||
|
passing a runtime variable triggers undefined behaviour and compiler warnings.
|
||||||
|
Use `wpArrayAllocCapacity` with an arena allocator for runtime sizes.
|
||||||
|
|
||||||
|
Initialise arrays with `WP_ARRAY_INIT_FILLED` to set `count = capacity`
|
||||||
|
immediately, allowing direct indexing.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Save research notes and implementation plans as markdown in `documents/`:
|
Save research notes and implementation plans as markdown in `documents/`:
|
||||||
|
|||||||
Reference in New Issue
Block a user