Calculation Context

The _user_calculation_context field allows the server to concurrently execute calculations on multiple groups of data.

An Aggregate UDF 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.