Associative Arrays
Associative arrays are used to represent collections of data elements that can be
retrieved by specifying a name called a key. D associative array keys are
formed by a list of scalar expression values called a tuple. You can
think of the array tuple itself as an imaginary parameter list to a
function that is called to retrieve the corresponding array value when you reference
the array. Each D associative array has a fixed key signature consisting of a
fixed number of tuple elements where each element has a given, fixed type.
You can define different key signatures for each array in your D program.
Associative arrays differ from normal, fixed-size arrays in that they have no predefined
limit on the number of elements, the elements can be indexed by any
tuple as opposed to just using integers as keys, and the elements are
not stored in preallocated consecutive storage locations. Associative arrays are useful in situations where
you would use a hash table or other simple dictionary data structure in
a C, C++, or JavaTM language program. Associative arrays give you the ability
to create a dynamic history of events and state captured in your D
program that you can use to create more complex control flows.
To define an associative array, you write an assignment expression of the form:
name [ key ] = expression ;
where name is any valid D identifier and key is a comma-separated
list of one or more expressions. For example, the following statement defines an
associative array a with key signature [ int, string ] and stores the integer value 456 in
a location named by the tuple [ 123, "hello" ]:
a[123, "hello"] = 456;
The type of each object contained in the array is also fixed
for all elements in a given array. Because a was first assigned using the
integer 456, every subsequent value stored in the array will also be of
type int. You can use any of the assignment operators defined in Chapter
2 to modify associative array elements, subject to the operand rules defined for
each operator. The D compiler will produce an appropriate error message if you
attempt an incompatible assignment. You can use any type with an associative array
key or value that you can use with a scalar variable. You cannot
nest an associative array within another associative array as a key or value.
You can reference an associative array using any tuple that is compatible with
the array key signature. The rules for tuple compatibility are similar to those
for function calls and variable assignments: the tuple must be of the same
length and each type in the list of actual parameters must be compatible
with the corresponding type in the formal key signature. For example, if an
associative array x is defined as follows:
x[123ull] = 0;
then the key signature is of type unsigned long long and the values are of
type int. This array can also be referenced using the expression x['a'] because
the tuple consisting of the character constant 'a' of type int and length one
is compatible with the key signature unsigned long long according to the arithmetic conversion rules
described in Type Conversions.
If you need to explicitly declare a D associative array before using it,
you can create a declaration of the array name and key signature outside
of the probe clauses in your program source code:
int x[unsigned long long, char];
BEGIN
{
x[123ull, 'a'] = 456;
}
Once an associative array is defined, references to any tuple of a compatible
key signature are permitted, even if the tuple in question has not been
previously assigned. Accessing an unassigned associative array element is defined to return a
zero-filled object. A consequence of this definition is that underlying storage is not allocated
for an associative array element until a non-zero value is assigned to that
element. Conversely, assigning an associative array element to zero causes DTrace to deallocate
the underlying storage. This behavior is important because the dynamic variable space out
of which associative array elements are allocated is finite; if it is exhausted
when an allocation is attempted, the allocation will fail and an error message
will be generated indicating a dynamic variable drop. Always assign zero to associative
array elements that are no longer in use. See Chapter 16, Options and Tunables for other techniques
to eliminate dynamic variable drops.