File: gawk.info, Node: Cached values, Prev: Symbol table by cookie, Up: Symbol Table Access 17.4.11.3 Creating and Using Cached Values .......................................... The routines in this minor node allow you to create and release cached values. Like scalar cookies, in theory, cached values are not necessary. You can create numbers and strings using the functions in *note Constructor Functions::. You can then assign those values to variables using 'sym_update()' or 'sym_update_scalar()', as you like. However, you can understand the point of cached values if you remember that _every_ string value's storage _must_ come from 'gawk_malloc()', 'gawk_calloc()', or 'gawk_realloc()'. If you have 20 variables, all of which have the same string value, you must create 20 identical copies of the string.(1) It is clearly more efficient, if possible, to create a value once, and then tell 'gawk' to reuse the value for multiple variables. That is what the routines in this minor node let you do. The functions are as follows: 'awk_bool_t create_value(awk_value_t *value, awk_value_cookie_t *result);' Create a cached string or numeric value from 'value' for efficient later assignment. Only values of type 'AWK_NUMBER', 'AWK_REGEX', 'AWK_STRNUM', and 'AWK_STRING' are allowed. Any other type is rejected. 'AWK_UNDEFINED' could be allowed, but doing so would result in inferior performance. 'awk_bool_t release_value(awk_value_cookie_t vc);' Release the memory associated with a value cookie obtained from 'create_value()'. You use value cookies in a fashion similar to the way you use scalar cookies. In the extension initialization routine, you create the value cookie: static awk_value_cookie_t answer_cookie; /* static value cookie */ static void my_extension_init() { awk_value_t value; char *long_string; size_t long_string_len; /* code from earlier */ ... /* ... fill in long_string and long_string_len ... */ make_malloced_string(long_string, long_string_len, & value); create_value(& value, & answer_cookie); /* create cookie */ ... } Once the value is created, you can use it as the value of any number of variables: static awk_value_t * do_magic(int nargs, awk_value_t *result) { awk_value_t new_value; ... /* as earlier */ value.val_type = AWK_VALUE_COOKIE; value.value_cookie = answer_cookie; sym_update("VAR1", & value); sym_update("VAR2", & value); ... sym_update("VAR100", & value); ... } Using value cookies in this way saves considerable storage, as all of 'VAR1' through 'VAR100' share the same value. You might be wondering, "Is this sharing problematic? What happens if 'awk' code assigns a new value to 'VAR1'; are all the others changed too?" That's a great question. The answer is that no, it's not a problem. Internally, 'gawk' uses "reference-counted strings". This means that many variables can share the same string value, and 'gawk' keeps track of the usage. When a variable's value changes, 'gawk' simply decrements the reference count on the old value and updates the variable to use the new value. Finally, as part of your cleanup action (*note Exit Callback Functions::) you should release any cached values that you created, using 'release_value()'. ---------- Footnotes ---------- (1) Numeric values are clearly less problematic, requiring only a C 'double' to store. But of course, GMP and MPFR values _do_ take up more memory.