Store map cleanup support

This document describes store map cleanup support.

The destructor of a CStoreMap object calls the ResetAndDestroy() member function. This function deletes from the store all streams whose stream IDs are currently held by the store map.

This is of most use:

  • in stores which do not support commit and revert, for example, the non-persistent in-memory store CBufStore.

  • where the streams, whose IDs are in the store map, do not contain pointers to other streams.

This behaviour allows a partially complete set of streams to be deleted if a leave occurs part of the way through the building of the set.

Note that this behaviour cannot be exploited by stores which do not support the deletion of streams, for example, the direct file store CDirectFileStore.

Stores such as the permanent file store, CPermanentFileStore, can also use commit and revert to implement this kind of behaviour.

Given the example class, CCompound, defined as:

class CCompound : public CBase
    {
    ...
    TSwizzle<CClassA> iA;
    TSwizzle<CClassB> iB;
    TSwizzle<CClassC> iC; 
    ...
    }

the CCompound object is stored using its StoreL() function and the individual components are externalised by the StoreComponentsL() function:

TStreamId CCompound::StoreL(CStreamStore& aStore)
    {
    CStoreMap* map=CStoreMap::NewLC(aStore);
    StoreComponentsL(*map);
       RStoreWriteStream stream(*map);
    TStreamId id=stream.CreateLC(aStore);
    ExternalizeL(stream);
    stream.CommitL();
    map->Reset();
    CleanupStack::PopAndDestroy(2);
    return id;
    }
void CCompound::StoreComponentsL(CStoreMap& aMap) const
    {
    TStreamId id;
    ...
    id = iA->StoreL(iStore);
    aMap.BindL(iA,id);
    ...
    id = iB->StoreL(iStore);
    aMap.BindL(iB,id);
    ...
    id = iC->StoreL(iStore);
    aMap.BindL(iC,id);
    ...
    }

Once the store map has been created, a cleanup item for it is placed onto the cleanupstack. This means that if, for example, the call to either:

id = iC->StoreL(iStore);

or

aMap.BindL(iC,id);

were to fail, then the streams containing the CClassA and CClassB objects would be deleted from the store as part of the subsequent destruction of the store map.

Once all three components have been successfully externalised and the CCompound's other data has also been externalised to its own stream, and no further failure modes are possible, then the store map can be and must be reset, by calling its Reset() function.