/// <summary> /// Collects the structure changes and find ancestor. /// </summary> /// <returns></returns> private IReadonlyChangeTracker <IReadOnlySnapshotStructure> collectStructureChangesAndFindAncestor() { SnapshotContext ancestorContext = snapshotContexts[0]; IReadonlyChangeTracker <IReadOnlySnapshotStructure> ancestor = ancestorContext.SourceStructure.ReadonlyChangeTracker; List <MemoryIndexTree> changes = new List <MemoryIndexTree>(); changes.Add(snapshotContexts[0].ChangedIndexesTree); for (int x = 1; x < snapshotContexts.Count; x++) { SnapshotContext context = snapshotContexts[x]; MemoryIndexTree currentChanges = context.ChangedIndexesTree; changes.Add(currentChanges); ancestor = getFirstCommonAncestor(context.SourceStructure.ReadonlyChangeTracker, ancestor, currentChanges, changes); } return(ancestor); }
/// <summary> /// Collects the call structure changes. /// </summary> /// <param name="callSnapshot">The call snapshot.</param> private void collectCallStructureChanges(Snapshot callSnapshot) { List <MemoryIndexTree> changes = new List <MemoryIndexTree>(); var ancestor = callSnapshot.Structure.Readonly.ReadonlyChangeTracker; for (int x = 0; x < snapshotContexts.Count; x++) { SnapshotContext context = snapshotContexts[x]; MemoryIndexTree currentChanges = context.ChangedIndexesTree; changes.Add(currentChanges); collectSingleFunctionChanges(callSnapshot, context.SourceStructure.ReadonlyChangeTracker, currentChanges, changes); } if (targetSnapshot.StructureCallChanges != null) { CollectionMemoryUtils.AddAll(this.changeTree, targetSnapshot.StructureCallChanges); } targetSnapshot.StructureCallChanges = changeTree.StoredIndexes; }
/// <summary> /// Collects the single function changes. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="callSnapshot">The call snapshot.</param> /// <param name="tracker">The tracker.</param> /// <param name="currentChanges">The current changes.</param> /// <param name="changes">The changes.</param> protected void collectSingleFunctionChanges <T>( Snapshot callSnapshot, IReadonlyChangeTracker <T> tracker, MemoryIndexTree currentChanges, List <MemoryIndexTree> changes) where T : class { int functionCallLevel = tracker.CallLevel; bool done = false; while (!done && tracker != null && tracker.CallLevel == functionCallLevel) { if (tracker.ConnectionType != TrackerConnectionType.SUBPROGRAM_MERGE) { done = tracker.ConnectionType == TrackerConnectionType.CALL_EXTEND; CollectionMemoryUtils.AddAll(currentChanges, tracker.IndexChanges); CollectionMemoryUtils.AddAll(this.changeTree, tracker.IndexChanges); CollectionMemoryUtils.AddAllIfNotNull(functionChages, tracker.FunctionChanges); CollectionMemoryUtils.AddAllIfNotNull(classChanges, tracker.ClassChanges); tracker = tracker.PreviousTracker; } else { IReadonlyChangeTracker <T> callTracker; if (tracker.TryGetCallTracker(callSnapshot, out callTracker)) { tracker = callTracker; } else { tracker = tracker.PreviousTracker; } } } }
/// <summary> /// Gets the first common ancestor. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="trackerA">The tracker a.</param> /// <param name="trackerB">The tracker b.</param> /// <param name="currentChanges">The current changes.</param> /// <param name="changes">The changes.</param> /// <returns>Located ancestor</returns> protected IReadonlyChangeTracker <T> getFirstCommonAncestor <T>( IReadonlyChangeTracker <T> trackerA, IReadonlyChangeTracker <T> trackerB, MemoryIndexTree currentChanges, List <MemoryIndexTree> changes ) where T : class { bool swapped = false; while (trackerA != trackerB) { if (trackerA == null || trackerB != null && trackerA.TrackerId < trackerB.TrackerId) { var swap = trackerA; trackerA = trackerB; trackerB = swap; swapped = true; } CollectionMemoryUtils.AddAll(currentChanges, trackerA.IndexChanges); CollectionMemoryUtils.AddAll(this.changeTree, trackerA.IndexChanges); CollectionMemoryUtils.AddAllIfNotNull(functionChages, trackerA.FunctionChanges); CollectionMemoryUtils.AddAllIfNotNull(classChanges, trackerA.ClassChanges); if (swapped) { foreach (MemoryIndexTree tree in changes) { CollectionMemoryUtils.AddAll(tree, trackerA.IndexChanges); } } trackerA = trackerA.PreviousTracker; } return(trackerA); }