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