manpagez: man pages & more
info gawk
Home | html | info | man

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.

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.