next up previous contents index
Next: Function Definitions Up: Input Previous: Storage Options

Life Time of Terms

Terms maintained under non-unique storage can be freed using a free_phylum call. Terms maintained under unique storage cannot be freed individually. They are stored via hashtables, and their lifetime can only be controlled by manipulation of their hashtables. By default, Kimwitu stores all unique terms in the same hashtable. The following manipulations on hashtables are defined: creation, assignment, deletion and reuse. New, initially empty, hashtables of arbitrary size can be created and used instead of the default hashtable. A newly created hashtable is not used directly after creation, but only after it has been `assigned' - from that moment on it will be used instead of the previously assigned hashtable, until another hashtable gets assigned. A `de-assigned' hashtable is not freed; all its memory cells remain alive, so pointers to those cells remain valid. However, they are invisible to the create routines, and thus the unique storage guarantee no longer holds in the following sequence of events: an (uniquely maintained) operator is created with a certain set of arguments, and a memory cell for it is created in the hashtable, and the initialization code for its phylum is executed; a new hashtable is created and assigned; the same operator is called with the same set of arguments, a new memory cell for it is created in the new hashtable, and the initialization code for its phylum is executed again. A `de-assigned' hashtable can be freed when its memory cells are no longer needed.

This can be used to control the lifetime of unique terms quite effectively, eg. to free intermediate results of a computation, as follows. First, a `temporary' hashtable is created to hold the intermediate results. Then, just before the computation is started, replace the default hashtable with the temporary one. When the computation is finished, the intermediate results and the final result are in the `temporary' hashtable. Re-assign the `old' hashtable, and copy the final result2, to re-create the memory cells belonging to the final result in the `old' hashtable. Finally, free the `temporary' hashtable.

Often only a limited number of phyla appears in the intermediate results. To allow more precise control, the phyla maintained under unique storage can be partitioned over multiple storage-classes, that each can have its own hashtable assigned. The memory cells created for a phylum are created in the hashtable assigned to the phylum's storage-class. Usually, phyla with a different `lifetime' will be in different storage classes. There is one predefined storage-class: uniq. Other storage-classes can be defined and used as follows: 

%storageclass intermediate wholeprogram; /* the `%' is part of the keyword */
ID2 { intermediate }: Operator1( ... ) | Operator2( ... ) | ... ; ID3 { wholeprogram }: Operator3( ... );
Here ID2 and ID3 belong to different storage-classes; if different hashtables are assigned to intermediate and wholeprogram, then the memory cells for Operator1 and Operator2 will be in another hashtable than those for Operator3.

A phylum can be in only one storage class. The term processor reports an error if this condition is violated. The %storageclass declaration is optional; if Kimwitu input does contain a storage class declaration, errors will be reported for all storage classes that were not explicitly declared.

For each storage class, Kimwitu creates statically (at compile time) a hashtable. Dynamically, hashtables can be created, (re)assigned to one or more storage classes, cleared and freed. The hashtable functions are listed in Section 2.2.

If the default (statically allocated) hashtable is not used, ie. if all storage classes are reassigned to dynamically created hashtables before they are used, it is useful to redefine LARGEPRIME  :

or use the -DLARGEPRIME=0 flag with cc during compilation of file k.c (see Section 2.5), to avoid the creation of the statically allocated hashtable.

next up previous contents index
Next: Function Definitions Up: Input Previous: Storage Options