I am in the process of implementing a persistent collection in C, specifically, an immutable hash trie. In order to increase acceptance and reusability, I have identified the following key areas that should be abstracted:
- typing of key and value
- allocation & freeing of additional nodes
Typing of key and value also comes with the complexity abstracting hash and equality functions.
I am mostly interested in being able to handle the following cases in particular, regarding memory management:
- creating new nodes with
malloc
and using reference counting to free them - using the ravenbrooks memory pool system (mps) as a garbage collector, which means I'll have to use the mps api to request new memory
and typing:
(void *)
as default for key and value types- making any or both of key and value types a struct
In addition I am wondering whether it would be useful to give users the option to provide hash
and equals
functions either:
- at runtime, and passing them down the trie every time, or
- at compile time, "baking" them into the various functions with the help of preprocessor macros
Are there "standard" ways to achieve those goals? Patterns, so to speak? Or are these goals misguided?
I haven't gotten to the point of a working implementation yet, but from first experiments I think I can achieve these goals via heavy use of macros and an unorthodox #include
order.
void*
pointers and lots of macros is hell to debug, and templates are much simpler.