The _user_calculation_context field allows the server to concurrently execute calculations on multiple groups of data.
A UDAF must keep intermediate counters for calculations as it is processing rows. The simple model for managing these counters is to allocate memory at the start API function, store a pointer to it in the aggregate context's _user_data field, then release the memory at the aggregate's finish API. An alternative method, based on the _user_calculation_context field, allows the server to concurrently execute calculations on multiple groups of data.
The _user_calculation_context field is a server-allocated memory pointer, created by the server for each concurrent processing group. The server ensures that the _user_calculation_context always points to the correct calculation context for the group of rows currently being processed. Between UDF API calls, depending on the data, the server may allocate new _user_calculation_context values. The server may save and restore calculation context areas to disk while processing a query.
The UDF stores all intermediate calculation values in this field. This illustrates a typical usage:
struct my_average_context { int sum; int count; }; reset(a_v3_aggregate_context *context) { mycontext = (my_average_context *) context->_user_calculation_context; mycontext->count = 0; mycontext->sum = 0; } next_value(a_v3_aggregate_context *context, void *args_handle) { mycontext = (my_average_context *) context->_user_calculation_context; mycontext->count++; .. }
In this model, the _user_data field can still be used, but no values relating to intermediate result calculations can be stored there. The _user_calculation_context is NULL at both the start and finish entry points.
To use the _user_calculation_context to enable concurrent processing, the UDF must specify the size and alignment requirements for its calculation context, and define a structure to hold its values and set a_v3_extfn_aggregate and _calculation_context_size to the sizeof() of that structure.
The UDF must also specify the data alignment requirements of _user_calculation_context through _calculation_context_alignment. If user_calculation_context memory contains only a character byte array, no particular alignment is necessary, and you can specify an alignment of 1. Likewise, double floating point values might require an 8-byte alignment. Alignment requirements vary by platform and data type. Specifying a larger alignment than necessary always works; however, using the smallest alignment uses memory more efficiently.