|
|
|
|
||
|
DEFINITION MODULE DatFraUsage; (******************************************************************* Module DatFraUsage (Version 1.0) Copyright (c) 1998-2006 by Andreas Fischlin and ETH Zurich. Purpose Supports efficient data usage on behalf of complex systems with large data requirements. It supports selective loading and unloading of a segment of the data, such as all data needed by a subsystem, yet to share commonly needed data as well. The techniques gives such a subsystem full and efficient control over its data in a situation where many such subsystems have to coexist. Remarks Uses data frames. The latter are analyzed as currently present in memory and updated according to needs and interests. Only those data frames are loaded which need some updating, e.g. because they have been changed. Interest in particular data frames can be announced by the callee by using routines such as AnnounceDataInterest from this module. Programming o Design Andreas Fischlin 03/05/1998 o Implementation Andreas Fischlin 03/05/1998 ETH Zurich Systems Ecology CHN E 35.1 Universitaetstrasse 16 8092 Zurich SWITZERLAND URLs: <mailto:RAMSES@env.ethz.ch> <http://www.sysecol.ethz.ch> <http://www.sysecol.ethz.ch/SimSoftware/RAMSES> Last revision of definition: 20/06/1998 AF *******************************************************************) FROM DMLanguage IMPORT userBase; FROM DataFrames IMPORT ReadingFilter; (*****************************************) (*##### Managing Data Interests #####*) (*****************************************) (*===== Announcing Data Interests =====*) TYPE DataInterest; VAR noDataInterest: DataInterest; (* read only *) PROCEDURE AnnounceDataInterest(VAR di: DataInterest); (* Initiates a particular data interest. An intantiation of a data interest di is required in order to add to it particular data frames via routine AddDFToDataInterest. Such a "package" of data interests in a series of data frames can then be referenced, in particular loaded, in one, simple step (see routine ReadyData). *) PROCEDURE DataInterestExists(di: DataInterest): BOOLEAN; (* Returns wether data interest di currently exists, i.e. has been announced lately by a call to AnnounceDataInterest. *) PROCEDURE AddDFToDataInterest(di: DataInterest; dfIdent: ARRAY OF CHAR); (* Adds your interest in the data of the data frame denoted by the name dfIdent to the data interest package di. As a consequence when calling ReadyData (see below), a loading process will be triggered as soon as that particular data frame is not in memory or has changed since last use via di. Note, AddDFToDataInterest can be called repeatedly for the same dfIdent without triggering error messages. See also explanations of formal parameter autoExtendInterest of procedure SetDataInterestKind for handy alternatives to calls to AddDFToDataInterest. *) (*===== Denaouncing Data Interests =====*) PROCEDURE DelDFInDataInterest(di: DataInterest; dfIdent: ARRAY OF CHAR); (* Reverts the effect of AddDFToDataInterest by removing your interest in the data frame of name dfIdent from di. *) PROCEDURE DenounceDataInterest(VAR di: DataInterest); (* Reverts the effect of AnnounceDataInterest by denouncing your interest in the data package di. Of course it also implicitely discards all your interests in particular data frames you have announced by calling AddDFToDataInterest. *) (**************************************************) (*##### Data Insterest Specific Settings #####*) (**************************************************) (*===== Auto Data Interest =====*) PROCEDURE SetDataInterestKind(di: DataInterest; autoExtendInterest: BOOLEAN); PROCEDURE GetDataInterestKind(di: DataInterest; VAR autoExtendInterest: BOOLEAN); (* It may convenient to let this module extend your data interest automatically during the loading process (see routine ReadyData). If autoExtendInterest is TRUE for the data interest di, any data frame encountered during the loading process is automatically added to the data interest (like if you would have called AddDFToDataInterest). The advantage of this method is that you don't need to know ahead all names of the data frames involved in a particular data interest. *) (*===== Reading Filters =====*) PROCEDURE SetDataInterestReadFilters(di: DataInterest; minLoadFilter,maxLoadFilter, minSharedFilter, maxSharedFilter: ReadingFilter); PROCEDURE GetDataInterestReadFilters(di: DataInterest; VAR minLoadFilter,maxLoadFilter, minSharedFilter, maxSharedFilter: ReadingFilter); (* Loading data interest di occurrs with reading filter range [minLoadFilter..maxLoadFilter] (cf. module DataFrames) if only data frames in non-shared mode are to be loaded (see routines ReadyData and SetDFInterestKind). In case at least one shared data frame is involved in the loading process, instead the filter range [minSharedFilter..maxSharedFilter] is used to load data into memory. If this routine is never called for di, loading by ReadyData is done with the default filter range [minFilter..maxFilter] available from module DataFrames. *) (**********************************************) (*##### Data Frame Specific Settings #####*) (**********************************************) PROCEDURE SetDFInterestKind(di: DataInterest; dfIdent: ARRAY OF CHAR; shared: BOOLEAN); PROCEDURE GetDFInterestKind(di: DataInterest; dfIdent: ARRAY OF CHAR; VAR shared: BOOLEAN); (* Above routine tell this module that a particular data frame denoted by 'dfIdent' contains shared data. This means that the data interest is not an exclusive one and that the callee is willing to accept the data in the given data frame, regardless who has actually loaded them. Such a use is called a shared data use. Note, that by default, i.e. without calling routine SetDFInterestKind, it is assumed that the data interest is exclusive. Consequently, in such a non-shared data use mode, it is not tolerated, that another callee of ReadyData has loaded the data frame. For instance, in a non-shared mode, ReadyData reloads the data, despite the fact that they might already be in memory, since the callee has never loaded them herself. The latter behvarior is in general needed to have proper control over data, since the presence of a data frame in memory is not a sufficient condition to know that its data are actually the wanted ones (it is not sufficient because data frames can be loaded along practically infinite path-ways, due to filtering and the use of different anchors, see also module DataFrames). The disadvantage of the non-shared mode is that in case of actually shared data, the same data would be relaoded each time by each callee, who is interested in them and wants to use the data. To avoid the resulting inefficiency, you should declare your interest in such data frames containing shared data as shared by calling SetDFInterestKind with shared = TRUE. Finally note, when a data interest contains at least one shared data frame, and that data frame triggers a need to reload the data interest, the loading does not necessary use the same reading filters, but uses the filtering range [minSharedFilter..maxSharedFilter] (cf. routine SetDataInterestReadFilters). *) (**********************************************) (*##### Readying and Discarding Data #####*) (**********************************************) PROCEDURE LoadDataFramesWithDlg( prompt: ARRAY OF CHAR; fromFilter, tillFilter: ReadingFilter; VAR startOnFileWithName: ARRAY OF CHAR; VAR resCode: INTEGER); (* Same as LoadDataFrames from module DataFrames, but always offers a file selection dialog explaining the user via the prompt what needs to be done. startOnFileWithName returns path and filename of the file which has been selected or the empty string if the user cancelled the dialog. For all other arguments see comments on procedure LoadDataFrames from module DataFrames. *) PROCEDURE ReadyData(di: DataInterest; overWriteAll: BOOLEAN; anchor: ARRAY OF CHAR; VAR isready, newData: BOOLEAN; VAR resCode: INTEGER); (* Core routine of this module which loads any data frames for which interest has been announced into memory as intelligently as possible. If flag overWriteAll is TRUE, loading takes place unconditionally; otherwise, loading occurrs only conditionally, i.e. either when the needed data frames have never been loaded or if they have been changed since last loading. If loading is necessary, it occurrs starting from anchor file 'anchor'. ReadyData returns in isready whether the loading process has been completed successfully and all data frames in which interest has been announced are now ready in memory for retrieval. Parameter newData returns wether the data have actually changed since last use, i.e. are new, and consequently indicateds the need to actually (re)assign the data to models and model objects. The main purpose of this all is to avoid unnecessary reloading of large data files and to avoid unnecessary, lengthy recalculations during assigning data to model objects, for instance, such as matrix inversions during computation of initial conditions of a model etc. Finally note, if the data interest di is set to autoExtendInterest = TRUE (see routine SetDataInterestKind), all data frames which are loaded are automatically added to the data interest di, as if you would have called AddDFToDataInterest yourself (happens only if the data frame has not been added to di previously). Any subsequent ReadyData call will then operate on the extended data interest, unless you call DiscardData (see below). *) PROCEDURE DiscardData(di: DataInterest; sharedToo: BOOLEAN); (* Core routine of this module which discards selectively all data associated with the data interest di (calls DropDataFrame from module DatFraAux). This routine is typically called in response to a request by a master to reload and reassign all data in control by the callee prior to a call to procedure ReadyData. Parameter sharedToo determines wether shared data frames (see routine SetDFInterestKind) are to be skipped from the dropping or discarded as well. Finally note, for any data frames automatically added due to autoExtendInterest (see routine SetDataInterestKind) DiscardData calls internally DelDFInDataInterest. Thus, as a result the data interest di is shrinked to its original state it was after the last, explicit declaration made by the callee by calls to AnnounceDataInterest, and to AddDFToDataInterest. *) (********************************) (*##### Error Messages #####*) (********************************) CONST dfUsageMsgOffset = userBase + 240; (* constants used for resCode *) dfUsageMsgMaxCode = dfUsageMsgOffset + 10-1; (* Values in range [dfUsageMsgOffset..dfUsageMsgOffset] are reserved *) tooManyDFIdents = dfUsageMsgOffset + 0; (* only internally used *) couldntLoadDF = dfUsageMsgOffset + 1; (* insert Δ (=306C) - data frame's identifier *) unknownDatInt = dfUsageMsgOffset + 2; (* insert Δ (=306C) - empty *) unknownDatIntWhile = dfUsageMsgOffset + 3; (* inserts Δ (=306C) - operation, data frame's identifier *) datIntDefTwice = dfUsageMsgOffset + 4; (* insert Δ (=306C) - empty *) dFIntDefTwice = dfUsageMsgOffset + 5; (* insert Δ (=306C) - data frame's identifier *) undknownDFInterest = dfUsageMsgOffset + 6; (* insert Δ (=306C) - data frame's identifier *) missingDataFrame = dfUsageMsgOffset + 7; (* insert Δ (=306C) - data frame's identifier *) PROCEDURE GetDFUErrMsg( msgnr: INTEGER; VAR msg: ARRAY OF CHAR ); (* Returns error messages for the entire data fram package. *) END DatFraUsage.
|
||
|
|
|