1.2.3. Recovery and persistence

At the root of the class hierarchy is the class StateManager. This class is responsible for object activation and deactivation and object recovery. The simplified signature of the class is:
public abstract class StateManager
{
    public boolean activate ();
    public boolean deactivate (boolean commit);

    public Uid get_uid (); // object’s identifier.

    // methods to be provided by a derived class

    public boolean restore_state (InputObjectState os);
    public boolean save_state (OutputObjectState os);

    protected StateManager ();
    protected StateManager (Uid id);
};
Objects are assumed to be of three possible flavours. They may simply be recoverable, in which case StateManager will attempt to generate and maintain appropriate recovery information for the object. Such objects have lifetimes that do not exceed the application program that creates them. Objects may be recoverable and persistent, in which case the lifetime of the object is assumed to be greater than that of the creating or accessing application, so that in addition to maintaining recovery information StateManager will attempt to automatically load (unload) any existing persistent state for the object by calling the activate (deactivate) operation at appropriate times. Finally, objects may possess none of these capabilities, in which case no recovery information is ever kept nor is object activation/deactivation ever automatically attempted.
If an object is recoverable or recoverable and persistent then StateManager will invoke the operations save_state (while performing deactivate), and restore_state (while performing activate) at various points during the execution of the application. These operations must be implemented by the programmer since StateManager cannot detect user level state changes. (We are examining the automatic generation of default save_state and restore_state operations, allowing the programmer to override this when application specific knowledge can be used to improve efficiency.) This gives the programmer the ability to decide which parts of an object’s state should be made persistent. For example, for a spreadsheet it may not be necessary to save all entries if some values can simply be recomputed. The save_state implementation for a class Example that has integer member variables called A, B and C could simply be:
public boolean save_state(OutputObjectState o)
{
    if (!super.save_state(o))
    return false;
            
    try
        {
            o.packInt(A);
            o.packInt(B);
            o.packInt(C));
        }
    catch (Exception e)
        {
            return false;
        }
        
    return true;
}
Objects are assumed to be of three possible flavours. They may simply be recoverable, in which case StateManager will attempt to generate and maintain appropriate recovery information for the object. Such objects have lifetimes that do not exceed the application program that creates them. Objects may be recoverable and persistent, in which case the lifetime of the object is assumed to be greater than that of the creating or accessing application, so that in addition to maintaining recovery information StateManager will attempt to automatically load (unload) any existing persistent state for the object by calling the activate (deactivate) operation at appropriate times. Finally, objects may possess none of these capabilities, in which case no recovery information is ever kept nor is object activation/deactivation ever automatically attempted.
If an object is recoverable or recoverable and persistent then StateManager will invoke the operations save_state (while performing deactivate), and restore_state (while performing activate) at various points during the execution of the application. These operations must be implemented by the programmer since StateManager cannot detect user level state changes. (We are examining the automatic generation of default save_state and restore_state operations, allowing the programmer to override this when application specific knowledge can be used to improve efficiency.) This gives the programmer the ability to decide which parts of an object’s state should be made persistent. For example, for a spreadsheet it may not be necessary to save all entries if some values can simply be recomputed. The save_state implementation for a class Example that has integer member variables called A, B and C could simply be:
public boolean save_state(OutputObjectState o)
{
    if (!super.save_state(o))
    return false;
            
    try
    {
        o.packInt(A);
        o.packInt(B);
        o.packInt(C));
    }
    catch (Exception e)
    {
        return false;
    }
                
return true;
}

Note

It is necessary for all save_state and restore_state methods to call super.save_state and super.restore_state. This is to cater for improvements in the crash recovery mechanisms.