Save and Restore Algorithms
List of: Discussion Topic
Subjects: SAT Save and Restore
Contents: Kernel

The save algorithm works much like the first stage of copying.


1. Create an empty entity list to hold a pointer to each data structure in the body. Seed the list with the BODY pointer.


ENTITY_LIST list;

list.add(body_to_be_saved);


2. For each entity in the list, write out the class data. Write any pointers as integer indexes by adding them to the list. Continue to scan until all pointers have been added:


list.init();

for(int count = 0; ; ++count) {


ENTITY* this_ent = list.next();


if (this_ent == NULL)



break;


this_ent->save(list);

}

The LUMP pointer in the BODY is written out as:

write_ptr(lump(), list);

This call saves the pointer to the file as an index and adds the lump to the entity list.

The example in Figure 10-1 is a body (B0) with two lumps (L0 and L0'). The save begins with the scan that takes the pointers from the body and entities contained within and makes an ENTITY_LIST, assigning an index to each pointer. The body pointer is index zero (0).


Figure 10-1. ENTITY_LIST Taken from Body

The save algorithm is analogous to the first two stages of copying. The intermediate form of the copied body is now on secondary storage instead of in the entity array.

Restore can be broken into two stages.

Restore Stage 1

Stage 1 reads the save file record and constructs the new object, leaving pointers to other restored entities in symbolic form (as indices into an array), and entering the address into the array.

The restore_entity_from_file function reads the ID string from the start of each save file record and searches its tables for the ID components, starting with the last (base) one and proceeding towards the leaf. It then calls the restore method for the leaf-most class found. That function constructs an object of the appropriate derived type, and then calls its restore_common method. That method in turn calls its parent's restore_common method, and then reads data specific to the derived class. Finally, restore_entity_from_file reads any more data in the save file record, and constructs an unknown_entity_text record to contain it, together with any unrecognized ID strings.

Restore Stage 2

After all new objects have been constructed, stage 2 visits each to convert the symbolic ENTITY pointers into genuine ones.

The fix_pointers method for each entity in the array is called with the array as argument. This calls fix_common, which calls its parent's fix_common, and then corrects any pointers in the derived class. In practice there is never anything special for fix_pointers to do, but it is retained for consistency and compatibility.

The restore process rebuilds the entity array as it reads the records from the file. Then the pointers are reconstructed as in copying. The restore process is:


1. Read the header to get the version number and set it; otherwise, the restore is not guaranteed to work correctly:


restore_version = read_int();

restore_major_version = MAJOR_VERSION(restore_version_number);

restore_minor_version =


MINOR_VERSION(restore_version_number);


2. Read the header to find the number of records and create an array (Figure 10-2) to hold a pointer to each restored record.


ENTITY** array = new ENTITY* [num_ents];


3. Restore each entity from the file leaving the pointers as integers.


for(i = 0; i < num_ents; i++)


array[i] = restore the ENTITY


4. For each entity in the array, replace the pointer indexes with pointers corresponding to the new entities.


for(i = 0; i < num_ents; i++)


array[i]->fix_pointers(array);

The first n entities in the array (array[0] to array[n-1], where n was read from the save file header) are returned and the array is returned to free storage.

While restoring the example body, the new body contains pointers to the new lumps. Lump L1 contains a pointer to L1',and the pointer of L1' is NULL (indicated by -1). This is the data stored in the disk by the save algorithm. (Figure 10-2).


Figure 10-2. Array Created for Restore

Figure 10-3 shows the new body after fix_pointers is called for each entity in the array.


Figure 10-3. Body Recovered by Restore Algorithm

Each class derived from ENTITY has a save method, and the object is saved by invoking the save method for the class.

Restoring is more difficult. ACIS uses a function that is not a class method to restore each class derived from ENTITY. When the ACIS modeler begins execution, each class derived from ENTITY notifies the restore code of its identifier and restore function. During the restore process, the restore code deciphers the identifier and calls the appropriate function.
PDF/KERN/10SAVE.PDF
HTM/DATA/KERN/KERN/10SAVE/0003.HTM