How FastMaps! Handles Serialization

How Ultimate FastMaps! Handles Serialization

FastMaps! supports serialization to iostreams or CArchive obejcts.

Serialization Using iostream

Serialization to iostreams is based on the zSerial class, which defines the Load() and Store() interfaces and several helper functions.

Serialization to an ostream object is performed by the Store() member. The tBalTree implementation of Store() begins by writing the stream header to the output stream. It then calls the storeTree() member to navigate the tree; for each node in the tree, the onStore() virtual is called to write the key and data of the node to the stream. After the tree has been fully navigated, the stream header is updated and the serialization operation is complete.

Serialization from an istream object is performed by the Load() member. The tBalTree implementation of Load() begins by disabling autobalance and examining the stream header. If the onStore() virtual tracks buffer sizes for key and data buffers, these are allocated at the start of the Load() operation. The Load() implementation then calls the onLoad() virtual repeatedly until the stream segment has been fully loaded. Once the tree has been reloaded, autobalance is re-enabled. The order in which the storeTree() member navigates the tree ensures that the tree that results from the Load() operation will have the same structure as the tree had when it was serialized by Store(). No balancing is required during serialization to or from an iostream.

To support serialization to iostreams, your derived class will need to implement the onStore() and onLoad() virtuals. All classes provided in the product include implementations of these members; note that the classes which store CObject-derived data block them since CObject does not support serialization to iostreams.

Serialization Using CArchive

Serialization using CArchive is implemented by the Serialize() member inherited from CObject and overridden by the tree class.

Serialization to a CArchive object begins by writing the number of items in the tree to the CArchive object. After the total number of items has been written to the CArchive object, the storeTree() member is called to navigate the tree and call the onStore() virtual for each node. The onStore() virtual simply writes the key followed by the data to the CArchive object.

Serialization from a CArchive object begins by disabling autobalance and reading the total number of items from the CArchive object. Then key,data pairs are read from the CArchive object until the item count is exhausted, and the set(key,data) member is called to add each pair to the tree. Once all items have been reloaded, autobalance is re-enabled. The order in which the storeTree() member navigates the tree ensures that no balancing is required during serialization from a CArchive object.

To support serialization using CArchive objects, your class needs to override the Serialize() and onStore() member functions. All MFC-oriented classes in the product contain implementations for these virtuals.

Serialization Using EITHER iostream Or CArchive

Serialization using either an iostream or a CArchive object is performed as described above; the derived class must implement overrides for the Serialize(), onStore(), and onLoad() members.

The onLoad() member is only called during serialization from iostreams, but the onStore() member is called during serialization to either an iostream or a CArchive object, and must behave differently for each.

The implementations provided in the product use the value of the m_bufSize protected member variable as a flag to determine whether onStore() is being called from Serialize() or Store(). The tBalTree implementation of Store() initializes the value of m_bufSize to zero in expectation that the onStore() member will track the size of the largest buffer needed. The implementations of Serialize() that are provided in the product classes all set m_bufSize to -1 at the start of their operation; thus their onStore() member can tell that if m_bufSize is -1 the call originates in Serialize(), otherwise it originates in Store().

It is recommended that you examine the source code of a class similar to the one you are deriving before beginning the actual coding process.