The first time that the database server calls the iterator function, the database server passes it an MI_FPARAM structure with the iterator status set to SET_INIT and the user-state pointer set to NULL. When the iterator function obtains this iterator-status value, it can perform the following initialization tasks for the iterator function:
Make sure that this memory has a memory duration of PER_COMMAND so that the user state remains for the duration of all iterations of the iterator function. If the memory has the default PER_ROUTINE memory duration, the database server automatically deallocates it after only one iteration of the iterator function. For more information, see Choosing the Memory Duration.
Each subsequent call to the iterator function uses the same MI_FPARAM structure, so each iteration can reuse the cached user-state memory. The iterator function must save enough information to return values one at a time on demand. For more information, see Saving a User State.
You can perform these initialization tasks directly in the iterator function or you can declare a separate iterator-initialization function, which the iterator function calls when it receives the SET_INIT iterator-status value. Declare the iterator-initialization function to return the same data type as the main iterator function. However, the database server ignores the return value of this function; it does not put this return value in the active set.
Figure 90 implements an iterator-initialization function, call fibGen_init( ), which the fibGen( ) iterator function (Figure 89) calls when it obtains the SET_INIT iterator-status value.
mi_integer fibGen_init(stop_val, fparam) mi_integer stop_val; MI_FPARAM *fparam; { fibState *fibstate; /* Allocate the user-state structure, fibState. This user-state * structure is allocated with PER_COMMAND duration to hold the memory * until the end of all iterations of the iterator function. */ fibstate = (fibState *)mi_dalloc(sizeof(fibState), PER_COMMAND); /* Save a pointer to the user-state structure in the MI_FPARAM structure. */ mi_fp_setfuncstate(fparam, (void *)fibstate); /* Set return value of function to NULL for either of the following: * - no argument passed into function (MI_FPARAM has a NULL argument) * - stop value is < 0 */ if ( mi_fp_argisnull(fparam, 0) || stop_val < 0 ) { mi_fp_setreturnisnull(fparam,0,1); return; } /* Set the first two numbers of the series: 0 and 1. Set the stop value * field in the user-state structure (stop_val) to the stop value passed * to the function. */ if ( stop_val < 1 ) { fibstate->fib_prec1 = 0; fibstate->fib_prec2 = 1; fibstate->fib_ncomputed = 1; fibstate->fib_endval = stop_val; } else { fibstate->fib_prec1 = 0; fibstate->fib_prec2 = 1; fibstate->fib_ncomputed = 0; fibstate->fib_endval = stop_val; } return (0); /* return value is ignored */ }
The fibGen_init( ) function returns an mi_integer value (0) because the main iterator function, fibGen( ), returns an active set of mi_integer values. However, the database server does not return this value as part of the active set. Once fibGen_init( ) completes, the database server calls the next iteration of fibGen( ) with an iterator-status value of SET_RETONE to return the first item of the active set.
Home | [ Top of Page | Previous Page | Next Page | Contents | Index ]