Associative array type

An associative array is a map or look-up table consisting of a collection of keys and their associated values. There is a one-to-one mapping between a set of keys and values. Associative arrays are supported by Perl, ksh93, and several other languages.

In Vue, each mapping is from one or more keys (dimensions) to a single value. Associative Array keys can have the following types
  • integral
  • floating point
  • string
  • timestamp
  • stacktrace
  • path
  • MAC address
  • IP address
Associative Array value can have the following types
  • integral
  • floating point
  • string
  • timestamp
  • stacktrace
  • path
  • MAC address
  • IP address
  • list
  • range

Associative arrays are abstract data types in Vue.Following actions can be performed on associative array data types.

  • Binding keys to a value:

    If the instance of the keys does not already exist, this action adds a key or set of keys along with the associated value to the associative array. Otherwise, this action replaces the associated old value with the new value. Keys that are not bound have a default value of 0 for the numerical type, empty string value for the string type, or a NULL value for other key types.

    Following example explains binding keys to a value
    /* single key dimension */
    count["ksh"] = 1;
    /* multiple key dimensions */
    var[0][“a”][2.5] = 1;
    var[1][“a”][3.5] = 2;

    The very first use of an associative array variable sets the type of the keys, the key dimension size and the type of the value. It must remain the same throughout the other places in the Vue script.

    For a key in ASO, you can bind a LIST value by completing the following different actions:

    1. By assigning a LIST variable:
         assoc_array["ksh"]=ll  /* copies ll list into associative array */
         assoc_array["ksh"]=assoc_array["abc"]; /* copies a list in ASO to another list in ASO.
                                                          Here the value type of assoc_array is LIST */ 
    2. By assigning an empty list returned by list() constructor function:
      assoc_array["ksh"]=list(); /* assigns an empty list */ 
    3. By appending a list or integral value
      append(assoc_array["ksh"], 5);	/* integral value 5 is appended to the list in ASO */
      append(assoc_array["ksh"], ll);	/* appends the contents of LIST variable ll to the list in ASO*/
      append(assoc_array["ksh"], assoc_array["abc"]); /* appends the contents of list in ASO to another list in ASO */
  • Unbinding a key or a set of keys and deleting the associated value: The delete() function is used to remove keys and binding values from the associative array. An unbound key is assigned a value of 0 or an empty string.
    Following example explains how to use delete function for unbinding a key
    delete(count, "ksh");
    delete(var, 0, “a”, 2.5);
    The first argument is the name of the associative array variable. The array variable name must be followed by N comma separated keys, where N is the key dimension size. If you want to only delete an associated value on the basis of key dimensions other than N, you can specify ANY for that key dimension. For example, to delete all the elements that have the string “a” as the second dimension, enter the following command.
    delete(var, ANY, “a”, ANY);

    All of the keys in delete() function can be specified as ANY, in which case, all elements of the associative array will be deleted. This function returns 0 if matching elements are found and are deleted. Otherwise, the delete() function returns a value of 1.

  • Finding the value for a set of keys: This operation looks up values that are bound to a single key or multiple keys.

    total = count["ksh"] + count["csh"];
    prod = var[0][“a”][2.5] * var[1][“a”][3.5];

    A LIST value for a key can be retrieved by indexing the associative array with the key. All LIST functions, sum(), min(), max(), count(), and avg(), can be used on a List in an Associative array. You can also assign a list in associative array to a LIST variable.

    Example:
    /* copies associative array list into list variable "ll" */
    ll=assoc_array["ksh"];
    /* prints the sum of all elements of list in associative array indexed with ksh" */
    printf("sum of assoc_array %d\n",sum(assoc_array["ksh"]) ); 
    /* prints the minimum value */
    printf("min of assoc_array %d\n",min(assoc_array["ksh"]) );
    /* prints the maximum value */
    printf("max of assoc_array %d\n",max(assoc_array["ksh"]) ); 
    /* prints the number of values in list */
    printf("count of assoc_array %d\n",count(assoc_array["ksh"]) );
    /* prints average value of the list */
    printf("avg of assoc_array %d\n",avg(assoc_array["ksh"]) );  
  • Checking whether a key or set of keys exists: The exists() function checks whether the associative array has any element that corresponds to the given keys. The exists() function returns a value 1 if an element is found and the function returns 0 if an element is not found.
    Following code block checks whether a key or set of keys exist.
    if (exists(count, "ksh"))
      printf("Number of ksh calls = %d\n", count["ksh"]);
    if (exists(var, 0, “a”, 2.5))
      printf(“Found value = %d\n”, var[0][“a”][2.5]);
    

    If you specify ANY keyword for a particular key dimension, the dimension becomes insignificant for search operation. All keys in the exists() function can be specified as ANY, in which case, the exists() function will check if the Associative Array has any element or not.

    my_key = “a”;
    if (exists(var, ANY, my_key, ANY))
      printf(“Found element with second key as %s \n”, my_key);
    
  • Increment and decrement operation: This operation can be used to increment or decrement the associative array values. To use this operation, you must specify an integer as the value type for the key. The following examples show the usage of the increment and decrement operation:

  1. printf(“Incremented value = %d\n”, ++count[“ksh”]);
  2. printf(“Incremented value = %d\n”, count[“ksh”]++);
  3. printf(“Decremented value = %d\n”, --count[“ksh”]);
  4. printf (“Decremented value = %d\n”, count[“ksh”]--);

In example 1, the value that corresponds to ksh key, incremented and the incremented value is printed.

In example 2, the value that corresponds to ksh is first printed and then the value is incremented. The decrement operation works the same way. However, the increment or decrement operation can be performed only on associative arrays whose value type is integer. The increment or decrement operation can also be used as an aggregator, where the value type of the associative array by default is set as integer. For example, on encountering statement, a[100]++ the first time, associative array a is created with the integer key type and the integer value type. The value stored for key 100 is 1. However, for a[100]--, -1 would be stored as the value for key 100. On encountering subsequent increment or decrement operations for the same associative array a increment and decrement operations is performed on the value for the specified key.

The increment and decrement behavior is exactly the same for associative arrays with more than one key dimension:
++var[0][“a”][2.5];
var[0][“a”][2.5]++;
--var[1][“a”][3.5];
var[1][“a”][3.5]--;
  • Printing contents of an associative array: This operation prints the key and associated value of the elements for an associative array. You can specify the following print options:
    Associative array print option Description Possible Values Default value
    num-of-entries Specifies to print the first number of key-value pairs. n>=0. (If 0, all the entries are displayed.) 0
    sort-type Specifies the sorting order. SORT_TYPE_ASCEND, SORT_TYPE_DESCEND SORT_TYPE_ASCEND
    sort-by Specifies whether to sort based on key or value. SORT_BY_KEY, SORT_BY_VALUE SORT_BY_KEY
    list-value Specifies which LIST attribute to sort or quantize when the value of the associative array is the list type USE_LIST_SUM, USE_LIST_MIN, USE_LIST_MAX, USE_LIST_COUNT, USE_LIST_AVG USE_LIST_AVG
    sort-key-index Specifies the key index (dimension), based on which the output will be sorted. -1 or k, where 0 <= k < number_of_keys 0
    stack-raw Specifies to print the stack trace in RAW address format. STKTRC_NO_SYM 0

    When the sort-by flag is SORT_BY_KEY, SORT_BY_VALUE and the key (given by sort-key-index) and value pair is of a type where sorting cannot be done, then the num-of-entries option and other print options are applied to the printing of the individual key and value pair, if applicable. For example, if the sorting is by range type, the num-of-entries option, and the other print options are reserved for slots of each range.

    The default associative array print options can be changed by using the set_aso_print_options()function in the BEGIN probe.

    Example:
    set_aso_print_options (10, SORT_TYPE_DESCEND|SORT_BY_VALUE);

    As shown in the example, multiple flags can be provided by inserting a vertical bar symbol between them.

    Note: The sort-key-index option cannot be set by the set_aso_print_options() function because it cannot be generalized for associative arrays of different key dimension sizes.

    The print() function prints the keys and associated value for all elements or a subset of elements of the associative array by using the default print options. To override the default print options, you must use additional arguments in the print() function. For more information about the print() function, see the Vue functions topic.

    The print() function prints the key and value pairs of the associative array by using the default print options. If you want to view the associative array contents in a different format, he will provide the num-of-entries option and the print option flags as additional parameters to the print() function.

    Example:

    /* uses default print options to display the contents of associative array ‘count’ */
    print(count); 	
    /* prints the first 10 entries of sorted associative array ‘count’. 
    Default sort-by and sort-type options are used */
    print(count, 10);	
    /* sorts the associative array ‘count’ in descending order of values and 
    displays the first 10 entries of ‘count’ */ 
    print(count, 10, SORT_BY_VALUE|SORT_TYPE_DESCEND);
    
    /* print elements which have first key as 0 */
    print(var[0][ANY][ANY]);
    
  • The clear() routine is used to clear the keys and associated values for elements of the associative array. The clear() routine is also used to reset the value of the associated array key without clearing the keys. If the clear() subroutine successfully clear one or more elements, it returns a 0, and the subroutine returns 1 when no elements are cleared.
    clear(count);               // count is an associative array.
    The previous routine with only one argument of the associative array type clears all the key pairs present in the associative array count. After the previous clear operation, the associative array count is empty.
    clear(count, RESET_VALUE);       // count is an associative array. 
    clear(var);          //  var is an associative array with three key dimensions
    The previous clear routine resets the value of all the key pairs in the associative array without clearing the key. The following default value is reset based on the type of value of the associative array:
    To clear elements with specific keys, you must specify the keys in the first argument. Also, to ignore any particular key dimension (all values of that particular key dimension match), you can specify ANY. If the keys are specified, all the key dimensions of the associative array must be specified as either genuine values of the matching key type or ANY.
    clear(var[ANY][“a”][ANY]);  // clear all elements with second key as “a”
    You can specify a second parameter in the clear() routine as RESET_VALUE. If you specify RESET_VALUE , the keys of the associative array are retained and only the values are reset.
    clear(count, RESET_VALUE);  
    clear(var[0][ANY][ANY], RESET_VALUE);
    

    The RESET_VALUE is dependent on type of the value. The following table displays the data types and default values to which the data type is reset:

    Type Default value
    Integral types (int, long, short, long long) 0
    LIST Empty
    Foat and double 0.0000000
    String Empty
    stktrace_t Empty
    probev_timestamp_t 0
    path_t Empty
    mac_addr_t 0
    ip_addr_t 0
  • The Quantizeoperation prints the keys and values of the given associative array in a graphical format based on the linear scaling of the values.
    quantize(count);
    count is an associative array, and it prints out the following contents:
    key                  value
    1                     1             ========
    2                     2             =========
    3                     3             ==========
    4                     4             ===========
    5                     5             ============
    6                     6             =============

Similar to print() function, you can provide quantize() function print options to override the default print options.

Example:

/* sorts the associative array ‘count’ in descending order of values and displays 
the first 10 entries of ‘count’ in graphical format*/
quantize(count, 10, _BY_VALUE|SORT_TYPE_DESCEND);
For associative arrays with multi-dimensional keys, keys can be specified in the first argument to restrict specific elements:
quantize(var[0][ANY][ANY]);  //quantize elements with first key as 0
  • Lquantize on associative array: This operation prints the keys and values of the given associative array in graphical format based on the logarithmic scaling of the values.
    lquantize (count);
    Where count is an associative array would print out the following contents :
    key                    value
    500                     500           ====
    1000                   1000           ====
    2000                   2000           =====
    4000                   4000           =====
    8000                   8000           ======
    16000                 16000           ======
    32000                 32000           =======
    64000                 64000           =======

Similar to print() function, you can provide with lquantize() function print options to override the default print options.

Example:

/* sorts the associative array ‘count’ in descending order of values, and displays 
the first 10 entries of ‘count’ in graphical 
format based on the logarithmic value*/
lquantize(count, 10, _BY_VALUE|SORT_TYPE_DESCEND);
For associative arrays with multi-dimensional keys, keys can be provided in the first argument to restrict to specific elements:
lquantize(var[0][ANY][ANY]);  //lquantize elements with first key as 0

The following example show how to use an associative array:

Example:

# Trace all the alloc- related calls and store the entry 
# Time in ‘entry_time’ associative array
#
@@uft:$__CPID:*:"/alloc/":entry
{
        entry_time[get_function()]=timestamp();
}
#
# At exit, first check if entry for this function was traced
# If so, delete the entry time from ‘entry_time’ associative array 
# To ensure that next time no action is taken on exit if entry was not traced. 

@@uft:$__CPID:*:"/alloc/":exit
{
   func =get_function();
   if(exists(entry_time, func) )
   {
             append(time_taken[func],
                   diff_time(timestamp(),entry_time[func],MICROSECONDS));
	            delete(entry_time, func);
	  }
}
#
# Print the list attributes sum, min, max, count, and avg time taken in every 
# Alloc function.
#
@@syscall:$__CPID:exit:entry
{
  print(time_taken);
	 exit();
}
Note: With this way, you need not define multiple list variables explicitly and still get the complete functions of the list with help of associative arrays.