Esempio n. 1
0
        /// <summary>
        /// Accepts incoming isolated commit
        /// </summary>
        /// <param name="isolatedChangeSet">Isolated changeset</param>
        /// <returns>Appended changes</returns>
        public CommitResult <Guid> AcceptCommit(IsolatedChangeSet <Guid, object, EdgeData> isolatedChangeSet)
        {
            lock (commitSync)
            {
                var latestSnapshot = snapshotsService.GetLatestSnapshotId();
                if (latestSnapshot.Equals(isolatedChangeSet.SourceSnapshotId))
                {
                    AppendableChangeSet <Guid, object, EdgeData> appendableChangeSet = CreateAppendableChangeSet(isolatedChangeSet.SourceSnapshotId, Guid.NewGuid(), isolatedChangeSet);
                    // Commit is directly on the last snapshot
                    CommitDirect(appendableChangeSet);
                    return(new CommitResult <Guid>(appendableChangeSet.DestinationSnapshotId, appendableChangeSet.Mapping));
                }
                else
                {
                    // There are snapshots in between
#if DEBUG
                    Debug.WriteLine("Source snapshot = " + isolatedChangeSet.SourceSnapshotId);
#endif
                    // Calculate changes between last snapshot and source snapshot
                    var intermediateChanges = ChangesBetween(isolatedChangeSet.SourceSnapshotId, latestSnapshot);

                    // Isolate portion of the last snapshot which is relevant for the change set
                    var subTree = IsolateSubTree(latestSnapshot, isolatedChangeSet, intermediateChanges);

                    // Create a brand new changeset which is compatible with last snapshot
                    // Do this by recursive walk through the last snapshot and perform the "compatible" operations done in the incomming changeset

                    var mergedChangeSet = CreateMergedChangeSet(latestSnapshot, subTree, isolatedChangeSet, intermediateChanges);

                    // When complete perform the CommitDirect of the new changeset
                    CommitDirect(mergedChangeSet);

                    // Start with created change mapping
                    var mapping = mergedChangeSet.Mapping;

                    // Merge intermediate changes items to it
                    foreach (var item in intermediateChanges)
                    {
                        AddChangeItem(mapping, item.Key, item.Value);
                    }

                    return(new CommitResult <Guid>(mergedChangeSet.DestinationSnapshotId, mapping));
                }
            }
        }