When a source provider responds to a GetChangeBatch(UInt32, SyncKnowledge, Object) (for managed code) or IKnowledgeSyncProvider::GetChangeBatch (for unmanaged code) request, its task is to generate a batch of changes that are not known by the destination replica. The source provider determines which items in the source replica are not contained in the knowledge object sent by the destination provider, and then returns a batch of those items.
Each change batch is made up of the following information:
The global IDs and versions for the changed items.
Tombstones that the destination replica should know about.
The made-with knowledge. This is the knowledge of the source replica when the changes were made. Sync Framework computes the learned knowledge for the destination from the made-with knowledge as the destination provider applies changes.
The prerequisite knowledge. This is the minimum knowledge a destination replica must have to process this batch of changes. If the knowledge of the destination replica does not contain the prerequisite knowledge, it cannot process these changes.
The forgotten knowledge of the source replica. This is used to detect an out-of-date destination replica.
Change Enumeration Between Two Replicas
This section provides a scenario that describes the process of change enumeration between two replicas by using the Sync Framework knowledge interfaces.
A replica is responsible for ensuring that changes that are made locally are reflected in its knowledge before a provider enumerates changes. This can be achieved either by updating the knowledge when a local change is made or by doing a metadata maintenance pass before enumerating changes.
In this scenario, a destination provider requests changes from the source provider. The order of the request is as follows:
The destination replica ensures that all changes that were made locally are reflected in its knowledge for the scope that is to be synchronized with the source replica.
The destination provider sends the destination replica's knowledge to the source provider. The source provider receives the knowledge through the GetChangeBatch(UInt32, SyncKnowledge, Object) (for managed code) or IKnowledgeSyncProvider::GetChangeBatch (for unmanaged code) method.
To build a change batch, the source provider enumerates the changes and deletes in the source replica and verifies each one against the destination replica's knowledge. A change is only added to the change batch when it is not contained in the knowledge of the destination replica. The change batch is represented by the ChangeBatch object (for managed code) or the ISyncChangeBatch interface (for unmanaged code).
The source provider returns the change batch to the destination provider.
Potentially, there might be lots of changes in a change set. To allow it time to process the list of incoming changes, the destination provider can ask that the changes be sent in batches by returning a non-zero number for the batch size in its GetSyncBatchParameters(UInt32, SyncKnowledge) (for managed code) or GetSyncBatchParameters (for unmanaged code) method.
When the source provider uses change units to represent subitems that are enumerated from the source replica, it sends only the change units that changed, instead of than the whole item. For more information, see Synchronizing Change Units.
Handling Obsolete Changes
When a change batch is constructed, obsolete changes are automatically excluded. An obsolete change is a change that is already contained in the destination replica's knowledge and that should not be applied to the destination replica. When a change is added to a change batch, Sync Framework compares the version of the change against the destination replica's knowledge and adds the change only if it is not contained in the destination replica's knowledge. This produces a minimal change batch and allows a provider to implement a simpler algorithm for enumerating changes, such as one based on tick count.
A provider can perform its own verification that the changes it adds to a change batch are not obsolete. To do this, the provider determines whether the global ID and version of the change are contained in the destination replica's knowledge. This is performed by using the Contains (for managed code) or the ISyncKnowledge::ContainsChange (for unmanaged code) method. If the knowledge does not contain the change, the provider adds that change to the change batch. This produces a minimal change batch and is useful for providers that want full control over change batch construction.
Filtered Change Enumeration
The changes that are enumerated by the source provider can be filtered in various ways, such as by using item filters, change unit filters, or custom filters. Also, when filters are used in the synchronization community, replicas can track custom filters for greater efficiency, which means additional information must be sent during change enumeration. For more information, see Filtering Synchronization Data.