This class is a simple implementation of a reliable Log. The client of a ReliableLog must provide a set of callbacks (via a LogHandler) that enables a ReliableLog to read and write checkpoints and log records. This implementation ensures that the current value of the data stored (via a ReliableLog) is recoverable after a system crash.
The secondary storage strategy is to record values in files using a representation of the caller's choosing. Two sorts of files are kept: snapshots and logs. At any instant, one snapshot is current. The log consists of a sequence of updates that have occurred since the current snapshot was taken. The current stable state is the value of the snapshot, as modified by the sequence of updates in the log. From time to time, the client of a ReliableLog instructs the package to make a new snapshot and clear the log. A ReliableLog arranges disk writes such that updates are stable (as long as the changes are force-written to disk) and atomic : no update is lost, and each update either is recorded completely in the log or not at all. Making a new snapshot is also atomic.
Normal use for maintaining the recoverable store is as follows: The client maintains the relevant data structure in virtual memory. As updates happen to the structure, the client informs the ReliableLog (all it "log") by calling log.update. Periodically, the client calls log.snapshot to provide the current value of the data structure. On restart, the client calls log.recover to obtain the latest snapshot and the following sequences of updates; the client applies the updates to the snapshot to obtain the state that existed before the crash.
The current logfile format is:
- a format version number (two 4-octet integers, major and minor), followed by
- a sequence of log records. Each log record contains, in order,
- a 4-octet integer representing the length of the following log data,
- the log data (variable length).
@see LogHandler
@author Ann Wollrath