Note that the new persistense always runs using lazy fetch. This section is therefore only relevant to users of the old persistense
When fetching an object from a persistent store using the get operation, the default is to eagerly fetch all objects in the transitive closure of the persistent root specified. However, since this may involve a huge number of objects not really needed by the current program execution, the persistent store offers the possibility to fetch the transitive closure lazily as the program goes along following references from the persistent root.
By further binding the persistentstore.allowLazyFetch virtual to trueObject, the default fetch strategy is changed to lazy fetch. Alternatively the fetch strategy may be set on a per get basis by further binding the get.allowLazyFetch virtual to trueObject.
In short, lazy fetch works as follows. Using the persistent store get operation, the object graph reachable from the persistent root is always fetched in a breadth-first manner, whether or not lazy fetch is applied. In the case of lazy fetch, instead of fetching the full object graph, only a limited number of objects are fetched from secondary storage and instantiated in the current process. The objects fetched are the persistentstore.maxFetchOnDanglerHitfirst objects met during the breadth-first traversal. The default number of objects fetched may be changed by further binding the maxFetchOnDanglerHit virtual.
So, what about the objects not fetched? Since these objects are not instantiated, it is impossible to setup usual in-memory references. Instead socalled dangling references are used. Simply stated, a dangling reference is a negative number uniquely identifying a persistent object to the current process. If a dangling reference is ever followed [3], the same mechanism that checks for NONE references will trap to the persistent store kernel in order to transparently fetch the object needed from secondary storage. Also in this case the objects fetched are the maxFetchOnDanglerHit first objects met during a breadth-first traversal of the object graph rooted in the object needed. All dangling references in the process referencing newly fetched objects are replaced by genuine in-memory references. A more detailed description of the implementation of lazy object fetch may be found in [Brandt 94].
Note that the --noCheckNone (or -s 14 0 ) compiler switch suppressing the generation of runtime checks for NONE references cannot be used in programs using lazy object fetch!
In addition to maxFetchOnDanglerHit and allowLazyFetch, the persistentstore.OnDanglerHit and persistentstore.AfterDanglerHit virtuals are used in conjunction with lazy object fetch. OnDanglerHit is called when a dangling reference has been hit, but before the object is actually fetched from secondary storage. AfterDanglerHit is called when the object has been fetched, giving the object as parameter. When AfterDanglerHit returns, the program continues whatever it was doing when the dangling reference was hit. The purpose of these virtuals is to offer informative callbacks that may be used for example in interactive programs where lazy object fetch may otherwise result in inexplicable delays.
It should be noted that there are no semantic differences whatsoever between lazy and eager object fetch. The practical difference lies in different efficiency/memory usage trade-offs.
The demo programs largeWrite.bet and largeRead.bet together illustrates the use of lazy fetch.
Persistence in BETA - Reference Manual | © 1991-2002 Mjølner Informatics |
[Modified: Monday October 23rd 2000 at 22:18]
|