Controlling the lifetime of unique memory cells by the creation, freeing and (re-) assignment of hashtables has one disadvantage: the uniqueness of storage property is no longer guaranteed. The following alternative does not have this flaw, but may be slower in execution time. The idea is to treat the hashtable as a stack of life-times, called segments, or memory-levels. New memory cells will always be created in the memory segment at the top of the stack. A new segment can be pushed onto the stack, eg. to store intermediate results of a computation. When the computation is finished, the segment can be popped from the stack; its memory cells remain alive. When now the final result of the computation is copied, its memory cells in the popped segment are re-created in the now topmost segment. Finally, the popped segment can be deleted. For each hashtable such a stack of segments can be used, and pushing and popping the segments of one hashtable does not influence the segments of another one.
In addition to the segments on the stack, there is one `heap' segment, that is meant for memory cells that never will be reclaimed. In Kimwitu, we call the heap segment `static', and the stack segments `dynamic'. Kimwitu offers two routines to switch between the use of the `static' segment and the `dynamic' segments. By default, all unique memory cells are created in the `heap' segments of the hashtables, ie. by default the `static' segments are used.
The routines that `manage' the segments (pushing, popping, freeing, switching between `static' (heap) and `dynamic' (stack)), and the routines that manage the hashtables (creation, assignment, freeing, deletion, reuse) can be freely intermixed, to use the best of both approaches.
Below follows a description of the memory level routines.
Allocate everything using the `static' scheme, until kc_ht_dynamic is called for this storage class. This is the default.
Allocate everything using the `dynamic' scheme, until kc_ht_dynamic is called for this storage class, or until the hashtable is changed (by assignment, deletion, clearing or reuse).
Increment the memory level: everything allocated in hashtable ht using the `dynamic' scheme will be freed during subsequent kc_ht_dec_level, kc_ht_free_level calls.
Decrements the memory level: everything allocated using the `dynamic' scheme in the previous, higher, memory level is still available, but can no longer be found using the hashtable, ie. copying a node that was created in the previous, higher, memory level will yield a new copy of that node (and the initialization code of its phylum will be executed).
Free all nodes/elements allocated during previous, higher, memory levels.