- Feb 1, 2021
- 38
- 11
- 8
- Customer Identifier
- E074775
The command SCATTER .. NAME provides an easy way for loading the values in the fields of a table into a data object. For example, for transforming values using certain criteria and the writing the data back to the table using GATTER .. NAME.
Care must be taken, however, if SCATTER .. NAME is used in an inner loop. Because the command creates a new data object by default, a fast running loop can easily produce a high system load and can even result in runtime errors due to memory/handle exhaustion.
In the above code snippet, order positions are successively read into a data object, manipulated and then appended to a new table. In each iteration, a new data object is created in SCATTER .. NAME, which depending on the structure of the table "orderposition", may have many member variables storing the field values. This together with the fact that the loop runs uninterrupted produces a high memory/handle consumption and may easily swamp the garbage collector.
A better approach is using the ADDITIVE option of SCATTER .. NAME. This causes an existing data object to be reused in the operation, and results in a constant resource load in the above scenario. Also, the code runs faster because the data object's member list remains constant and does not need to be recreated in each iteration of the loop.
See also:
Xbase++ documentation Command SCATTER NAME
Care must be taken, however, if SCATTER .. NAME is used in an inner loop. Because the command creates a new data object by default, a fast running loop can easily produce a high system load and can even result in runtime errors due to memory/handle exhaustion.
Xbase++:
////////////////////////////////////////////
// WRONG/MEMORY EXHAUSTIVE CODE
////////////////////////////////////////////
LOCAL oData
USE orderposition NEW
USE orderposition_new NEW
DO WHILE .NOT. orderposition->(EOF())
SCATTER NAME oData IN orderposition
oData:price *= nFactor
orderposition_new->(DbAppend())
GATHER NAME oData IN orderposition_new
orderposition->(DbSkip())
ENDDO
In the above code snippet, order positions are successively read into a data object, manipulated and then appended to a new table. In each iteration, a new data object is created in SCATTER .. NAME, which depending on the structure of the table "orderposition", may have many member variables storing the field values. This together with the fact that the loop runs uninterrupted produces a high memory/handle consumption and may easily swamp the garbage collector.
A better approach is using the ADDITIVE option of SCATTER .. NAME. This causes an existing data object to be reused in the operation, and results in a constant resource load in the above scenario. Also, the code runs faster because the data object's member list remains constant and does not need to be recreated in each iteration of the loop.
Xbase++:
////////////////////////////////////////////
// CORRECTED CODE
////////////////////////////////////////////
LOCAL oData
USE orderposition NEW
USE orderposition_new NEW
DO WHILE .NOT. orderposition->(EOF())
// Use ADDITIVE option for reusing data objects in the loop
SCATTER NAME oData IN orderposition ADDITIVE
oData:price *= nFactor
orderposition_new->(DbAppend())
GATHER NAME oData IN orderposition_new
orderposition->(DbSkip())
ENDDO
See also:
Xbase++ documentation Command SCATTER NAME
Last edited: