/// <summary> /// Processes the source aliases. /// </summary> /// <param name="node">The node.</param> /// <param name="memoryAlias">The memory alias.</param> private void processSourceAliases(MemoryCollectorNode node, IMemoryAlias memoryAlias) { if (memoryAlias != null && memoryAlias.HasAliases) { if (node.IsMust) { foreach (MemoryIndex alias in memoryAlias.MustAliases) { Snapshot.AddAlias(alias, node.TargetIndex, null); } foreach (MemoryIndex alias in memoryAlias.MayAliases) { Snapshot.AddAlias(alias, null, node.TargetIndex); } Snapshot.MustSetAliases(node.TargetIndex, memoryAlias.MustAliases, memoryAlias.MayAliases); } else { HashSet <MemoryIndex> aliases = new HashSet <MemoryIndex>(); CollectionMemoryUtils.AddAll(aliases, memoryAlias.MustAliases); CollectionMemoryUtils.AddAll(aliases, memoryAlias.MayAliases); foreach (MemoryIndex alias in aliases) { Snapshot.AddAlias(alias, null, node.TargetIndex); } Snapshot.MaySetAliases(node.TargetIndex, aliases); } } }
/// <summary> /// Collects the values. /// </summary> /// <param name="targetIndex">Index of the target.</param> /// <returns>true if the value is always defined</returns> private bool collectValues(MemoryIndex targetIndex) { bool valuesAlwaysDefined = true; foreach (Snapshot sourceSnapshot in sourceSnapshots) { MemoryEntry sourceEntry = getSourceEntry(targetIndex, sourceSnapshot); if (sourceEntry != null) { if (sourceEntry.ContainsAssociativeArray) { VisitMemoryEntry(sourceEntry); } else { CollectionMemoryUtils.AddAll(values, sourceEntry.PossibleValues); } } else { valuesAlwaysDefined = false; } } return(valuesAlwaysDefined); }
/// <summary> /// Compares the data and simplify. /// </summary> /// <param name="widen">if set to <c>true</c> then widening operation is performed.</param> /// <returns>true if memory state is different; otherwise false</returns> public bool CompareDataAndSimplify(bool widen) { bool areEquals = true; HashSet <MemoryIndex> indexes = new HashSet <MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, newData.Readonly.Indexes); CollectionMemoryUtils.AddAll(indexes, oldData.Readonly.Indexes); foreach (MemoryIndex index in indexes) { if (widen) { if (!compareData(index)) { widenData(index); } } if (!compareData(index)) { areEquals = false; } } return(!areEquals); }
/// <summary> /// Collects the single function changes. /// </summary> /// <param name="callSnapshot">The call snapshot.</param> /// <param name="tracker">The tracker.</param> protected void collectSingleFunctionChanges( Snapshot callSnapshot, IReadonlyChangeTracker <IReadOnlySnapshotData> tracker) { 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(indexChanges, tracker.IndexChanges); tracker = tracker.PreviousTracker; } else { IReadonlyChangeTracker <IReadOnlySnapshotData> callTracker; if (tracker.TryGetCallTracker(callSnapshot, out callTracker)) { tracker = callTracker; } else { tracker = tracker.PreviousTracker; } } } }
/// <summary> /// Assigns the must memory index. /// </summary> /// <param name="mustIndex">Index of the must.</param> /// <param name="composedValues">The composed values.</param> private void assignMust(MemoryIndex mustIndex, CollectComposedValuesVisitor composedValues) { IIndexDefinition data = snapshot.Structure.Readonly.GetIndexDefinition(mustIndex); HashSet <Value> values = new HashSet <Value>(composedValues.Values); if (snapshot.CurrentMode == SnapshotMode.MemoryLevel) { if (data.Array != null) { values.Add(data.Array); } if (composedValues.Objects.Count > 0) { IObjectValueContainer objects = Factories.StructuralContainersFactories.ObjectValueContainerFactory.CreateObjectValueContainer(snapshot.Structure.Writeable, composedValues.Objects); snapshot.Structure.Writeable.SetObjects(mustIndex, objects); if (data.Objects != null) { CollectionMemoryUtils.AddAll(values, data.Objects); } } } snapshot.CurrentData.Writeable.SetMemoryEntry(mustIndex, snapshot.CreateMemoryEntry(values)); }
private void simplifyData() { List <MemoryIndex> indexes = new List <MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, newData.Readonly.ReadonlyChangeTracker.IndexChanges); var previousTracker = newData.Readonly.ReadonlyChangeTracker.PreviousTracker; var currentTracker = newData.Writeable.WriteableChangeTracker; foreach (MemoryIndex index in indexes) { MemoryEntry newEntry = getMemoryEntryOrEmpty(index, newData.Readonly); if (newEntry != null && newEntry.Count > simplifyLimit) { MemoryEntry simplifiedEntry = assistant.Simplify(newEntry); setNewMemoryEntry(index, newEntry, simplifiedEntry); newEntry = simplifiedEntry; } if (previousTracker != null) { MemoryEntry previousEntry = getMemoryEntryOrEmpty(index, previousTracker.Container); if (ValueUtils.CompareMemoryEntries(previousEntry, newEntry)) { currentTracker.RemoveIndexChange(index); } } } }
private void clearDataTracker() { var previousTracker = newData.Readonly.ReadonlyChangeTracker.PreviousTracker; if (previousTracker != null) { List <MemoryIndex> indexes = new List <MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, newStructure.Readonly.ReadonlyChangeTracker.IndexChanges); IReadOnlySnapshotData previousData = previousTracker.Container; foreach (MemoryIndex index in indexes) { if (index is TemporaryIndex) { newStructure.Writeable.WriteableChangeTracker.RemoveIndexChange(index); } else { MemoryEntry newEntry = getMemoryEntryOrEmpty(index, newData.Readonly); MemoryEntry previousEntry = getMemoryEntryOrEmpty(index, previousData); if (ValueUtils.CompareMemoryEntries(newEntry, previousEntry)) { newData.Writeable.WriteableChangeTracker.RemoveIndexChange(index); } } } } }
/// <summary> /// Merges the declarations. /// </summary> private void mergeDeclarations() { foreach (QualifiedName functionName in functionChages) { HashSet <FunctionValue> declarations = new HashSet <FunctionValue>(); foreach (var context in snapshotContexts) { IEnumerable <FunctionValue> decl; if (context.SourceStructure.TryGetFunction(functionName, out decl)) { CollectionMemoryUtils.AddAll(declarations, decl); } } writeableTargetStructure.SetFunctionDeclarations(functionName, declarations); } foreach (QualifiedName className in classChanges) { HashSet <TypeValue> declarations = new HashSet <TypeValue>(); foreach (var context in snapshotContexts) { IEnumerable <TypeValue> decl; if (context.SourceStructure.TryGetClass(className, out decl)) { CollectionMemoryUtils.AddAll(declarations, decl); } } writeableTargetStructure.SetClassDeclarations(className, declarations); } }
/// <summary> /// Initializes a new instance of the <see cref="CopyIndexContainer"/> class. /// /// Content of given container is copied to the new container. /// </summary> /// <param name="container">The container.</param> public CopyIndexContainer(IReadonlyIndexContainer container) { unknownIndex = container.UnknownIndex; indexes = new Dictionary <string, MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, container.Indexes); }
/// <summary> /// Processes single merge operation - prepares all valid values and alias informations from the source indexes. /// When the source indexes contains some array values prepares operation for every descendant index and merge the /// array into one which will be stored in the target memory entry. /// </summary> /// <param name="operation">The operation.</param> private void processMergeOperation(MergeOperation operation) { HashSet <Value> values = new HashSet <Value>(); foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.Infos.Readonly, index); CollectionMemoryUtils.AddAll(values, entry.PossibleValues); } if (Structure.Readonly.HasArray(operation.TargetIndex)) { mergeArrays(operation); } if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } Infos.Writeable.SetMemoryEntry(operation.TargetIndex, targetSnapshot.CreateMemoryEntry(values)); }
/// <summary> /// Collects all objects from given collection of objects. /// </summary> /// <param name="obejcts">The obejcts.</param> public void collectSourceObjects(IObjectValueContainer obejcts) { if (obejcts != null && obejcts.Count > 0) { hasObjects = true; CollectionMemoryUtils.AddAll(objectValues, obejcts.Values); } }
/// <summary> /// Collects the data changes from call snapshot. /// </summary> /// <param name="callSnapshot">The call snapshot.</param> private void collectDataChangesFromCallSnapshot(Snapshot callSnapshot) { CollectionMemoryUtils.AddAll(indexChanges, targetSnapshot.MergeInfo.GetIndexes()); for (int x = 0; x < sourceSnapshots.Count; x++) { Snapshot sourceSnapshot = sourceSnapshots[x]; collectSingleFunctionChanges(callSnapshot, sourceSnapshot.CurrentData.Readonly.ReadonlyChangeTracker); } }
/// <summary> /// Processes the objects stored within this operation. /// </summary> protected void processObjects() { if (Node.Objects != null && Node.Objects.Count > 0) { IObjectValueContainer objects = Worker.Factories.StructuralContainersFactories.ObjectValueContainerFactory.CreateObjectValueContainer(Worker.Structure, Node.Objects); Worker.Structure.SetObjects(TargetIndex, objects); CollectionMemoryUtils.AddAll(Values, Node.Objects); } }
/// <summary> /// Collects the information changes and find ancestor. /// </summary> /// <returns>Ancestor</returns> private IReadonlyChangeTracker <IReadOnlySnapshotData> collectInfoChangesAndFindAncestor() { CollectionMemoryUtils.AddAll(indexChanges, targetSnapshot.MergeInfo.GetIndexes()); IReadonlyChangeTracker <IReadOnlySnapshotData> ancestor = sourceSnapshots[0].Infos.Readonly.ReadonlyChangeTracker; for (int x = 1; x < sourceSnapshots.Count; x++) { Snapshot sourceSnapshot = sourceSnapshots[x]; ancestor = getFirstCommonAncestor(sourceSnapshot.Infos.Readonly.ReadonlyChangeTracker, ancestor); } return(ancestor); }
/// <summary> /// Assigns new value into specified index. /// </summary> /// <param name="index">The index.</param> private void assign(MemoryIndex index) { HashSet <Value> newValues = new HashSet <Value>(); if (!isMust) { MemoryEntry oldEntry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, index); CollectionMemoryUtils.AddAll(newValues, oldEntry.PossibleValues); } CollectionMemoryUtils.AddAll(newValues, entry.PossibleValues); snapshot.CurrentData.Writeable.SetMemoryEntry(index, snapshot.CreateMemoryEntry(newValues)); }
/// <summary> /// Visits the information value location. /// </summary> /// <param name="location">The location.</param> public void VisitInfoValueLocation(InfoValueLocation location) { MemoryEntry oldEntry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, location.ContainingIndex); HashSet <Value> newValues = new HashSet <Value>(); CollectionMemoryUtils.AddAll(newValues, oldEntry.PossibleValues); IEnumerable <Value> values = location.WriteValues(snapshot.MemoryAssistant, entry); newValues.Add(location.Value); snapshot.CurrentData.Writeable.SetMemoryEntry(location.ContainingIndex, snapshot.CreateMemoryEntry(newValues)); }
public override void ProcessOperation() { Worker.Structure.NewIndex(TargetIndex); if (Node.ScalarValues != null) { CollectionMemoryUtils.AddAll(Values, Node.ScalarValues); } processArrays(); processAliases(); processObjects(); processIndexModifications(); setValues(); }
/// <inheritdoc /> public void Assign(Snapshot snapshot, MemoryPath path, MemoryEntry value, bool forceStrongWrite) { if (snapshot.AssignInfo == null) { snapshot.AssignInfo = new AssignInfo(); } MemoryIndexModificationList pathModifications = snapshot.AssignInfo.GetOrCreatePathModification(path); List <Tuple <MemoryIndex, HashSet <Value> > > valuesToAssign = new List <Tuple <MemoryIndex, HashSet <Value> > >(); // Prepares locations and values to assign foreach (var item in pathModifications.Modifications) { MemoryIndex index = item.Key; MemoryIndexModification indexModification = item.Value; HashSet <Value> values = new HashSet <Value>(); valuesToAssign.Add(new Tuple <MemoryIndex, HashSet <Value> >(index, values)); if (indexModification.IsCollectedIndex) { CollectionMemoryUtils.AddAll(values, value.PossibleValues); } // Loads all other datasources where to get additional values to assign - unknown indexes. foreach (var datasource in indexModification.Datasources) { MemoryEntry entry; if (datasource.SourceSnapshot.Infos.Readonly.TryGetMemoryEntry(datasource.SourceIndex, out entry)) { CollectionMemoryUtils.AddAll(values, entry.PossibleValues); } } } // Assigns values to locations foreach (var item in valuesToAssign) { MemoryIndex index = item.Item1; HashSet <Value> values = item.Item2; MemoryEntry entry = new MemoryEntry(values); snapshot.Infos.Writeable.SetMemoryEntry(index, entry); } }
/// <summary> /// Compares the data and simplify. /// </summary> /// <param name="widen">if set to <c>true</c> [widen].</param> /// <returns>true if memory state is different; otherwise false</returns> public bool CompareDataAndSimplify(bool widen) { if (snapshot.NumberOfTransactions == 1) { // This is the first transaction of the snapshot - it has to be different return(true); } if (newData.IsReadonly) { // Snapshot was not modified - it is different if the previous snapshot was different bool differs = newData.Readonly.DiffersOnCommit; return(differs); } bool areEqual = true; HashSet <MemoryIndex> indexes = new HashSet <MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, newData.Readonly.Indexes); CollectionMemoryUtils.AddAll(indexes, oldData.Readonly.Indexes); foreach (MemoryIndex index in indexes) { if (widen) { if (!compareData(index)) { widenData(index); } } if (!compareData(index)) { areEqual = false; } } // Stores information whether is different or not if (!newData.IsReadonly) { newData.Writeable.SetDiffersOnCommit(!areEqual); } return(!areEqual); }
private void processSourceValues() { MemoryEntry oldEntry = SnapshotDataUtils.GetMemoryEntry(Worker.Snapshot, Worker.Data, SourceIndex); if (oldEntry.ContainsAssociativeArray) { foreach (Value value in oldEntry.PossibleValues) { if (!(value is AssociativeArray)) { Values.Add(value); } } } else { CollectionMemoryUtils.AddAll(Values, oldEntry.PossibleValues); } }
public MemoryEntry GenerateMemeoryEntry(IEnumerable <Value> values) { List <Value> entryValues = new List <Value>(values); if (ScalarValues != null) { CollectionMemoryUtils.AddAll(entryValues, ScalarValues); } if (Arrays != null) { CollectionMemoryUtils.AddAll(entryValues, Arrays); } if (Objects != null) { CollectionMemoryUtils.AddAll(entryValues, Objects); } return(new MemoryEntry(entryValues)); }
/// <summary> /// Compares the structure and simplifies the data. /// </summary> /// <param name="widen">if set to <c>true</c> then widening operation is performed.</param> /// <returns>true if memory state is different; otherwise false</returns> public bool CompareStructureAndSimplify(bool widen) { HashSet <MemoryIndex> usedIndexes = new HashSet <MemoryIndex>(); CollectionMemoryUtils.AddAll(usedIndexes, newStructure.Readonly.Indexes); CollectionMemoryUtils.AddAll(usedIndexes, oldStructure.Readonly.Indexes); IIndexDefinition emptyDefinition = Factories.StructuralContainersFactories.IndexDefinitionFactory.CreateIndexDefinition(newStructure.Writeable); bool areEqual = true; foreach (MemoryIndex index in usedIndexes) { if (index is TemporaryIndex) { continue; } IIndexDefinition newDefinition = getIndexDefinitionOrUndefined(index, newStructure, emptyDefinition); IIndexDefinition oldDefinition = getIndexDefinitionOrUndefined(index, oldStructure, emptyDefinition); if (widen) { if (!compareData(index)) { widenData(index); } } if (!compareIndexDefinitions(newDefinition, oldDefinition)) { areEqual = false; } if (!compareData(index)) { areEqual = false; } } return(!areEqual); }
public override void ProcessOperation() { IIndexDefinition definition = Worker.Structure.GetIndexDefinition(TargetIndex); if (Node.ScalarValues != null) { CollectionMemoryUtils.AddAll(Values, Node.ScalarValues); } MemoryEntry oldEntry = SnapshotDataUtils.GetMemoryEntry(Worker.Snapshot, Worker.Data, TargetIndex); CollectionMemoryUtils.AddAll(Values, oldEntry.PossibleValues); processArrays(definition.Array); processAliases(definition.Aliases); processObjects(definition.Objects); processIndexModifications(TargetIndex); setValues(); }
/// <summary> /// Gets the first common ancestor. /// </summary> /// <param name="trackerA">The tracker a.</param> /// <param name="trackerB">The tracker b.</param> /// <returns>Common ancestor</returns> protected IReadonlyChangeTracker <IReadOnlySnapshotData> getFirstCommonAncestor( IReadonlyChangeTracker <IReadOnlySnapshotData> trackerA, IReadonlyChangeTracker <IReadOnlySnapshotData> trackerB ) { while (trackerA != trackerB) { if (trackerA == null || trackerB != null && trackerA.TrackerId < trackerB.TrackerId) { var swap = trackerA; trackerA = trackerB; trackerB = swap; } CollectionMemoryUtils.AddAll(indexChanges, trackerA.IndexChanges); trackerA = trackerA.PreviousTracker; } return(trackerA); }
/// <summary> /// Stores objects in given container to this node and process them /// </summary> /// <param name="objects">The objects.</param> protected void processObjects(IObjectValueContainer objects) { if (objects != null && objects.Count > 0) { IObjectValueContainerBuilder builder = Worker.Factories.StructuralContainersFactories.ObjectValueContainerFactory.CreateObjectValueContainer(Worker.Structure, objects).Builder(Worker.Structure); if (Node.Objects != null) { builder.AddAll(Node.Objects); CollectionMemoryUtils.AddAll(Values, Node.Objects); } Worker.Structure.SetObjects(TargetIndex, builder.Build(Worker.Structure)); CollectionMemoryUtils.AddAll(Values, objects.Values); } else { processObjects(); } }
/// <summary> /// Assigns the may memory index. /// </summary> /// <param name="mayIndex">Index of the may.</param> /// <param name="composedValues">The composed values.</param> private void assignMay(MemoryIndex mayIndex, CollectComposedValuesVisitor composedValues) { IIndexDefinition data = snapshot.Structure.Readonly.GetIndexDefinition(mayIndex); HashSet <Value> values = new HashSet <Value>(composedValues.Values); if (composedValues.Objects.Count > 0) { HashSet <ObjectValue> objectsSet = new HashSet <ObjectValue>(data.Objects); CollectionMemoryUtils.AddAll(objectsSet, composedValues.Objects); IObjectValueContainer objects = Factories.StructuralContainersFactories.ObjectValueContainerFactory.CreateObjectValueContainer(snapshot.Structure.Writeable, composedValues.Objects); snapshot.Structure.Writeable.SetObjects(mayIndex, objects); //if (data.Objects != null) CollectionMemoryUtils.AddAll(values, data.Objects); } MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, mayIndex); CollectionMemoryUtils.AddAll(values, entry.PossibleValues); snapshot.CurrentData.Writeable.SetMemoryEntry(mayIndex, snapshot.CreateMemoryEntry(values)); }
/// <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> /// Adds the aliases to must or may lists of indexes. /// </summary> private void addAliasesToIndexes() { HashSet <MemoryIndex> mustAliases = new HashSet <MemoryIndex>(); HashSet <MemoryIndex> mayAliases = new HashSet <MemoryIndex>(); foreach (MemoryIndex index in mustIndexesProcess) { IMemoryAlias alias; if (snapshot.Structure.Readonly.TryGetAliases(index, out alias)) { CollectionMemoryUtils.AddAll(mustAliases, alias.MustAliases); foreach (MemoryIndex mayIndex in alias.MayAliases) { mayAliases.Add(mayIndex); } } } foreach (MemoryIndex index in mayIndexesProcess) { IMemoryAlias alias; if (snapshot.Structure.Readonly.TryGetAliases(index, out alias)) { CollectionMemoryUtils.AddAll(mayAliases, alias.MustAliases); CollectionMemoryUtils.AddAll(mayAliases, alias.MayAliases); } } foreach (MemoryIndex index in mustAliases) { addToMust(index); } foreach (MemoryIndex index in mayAliases) { addToMay(index); } }
private void clearStructureTracker() { var previousTracker = newStructure.Readonly.ReadonlyChangeTracker.PreviousTracker; if (previousTracker != null) { List <MemoryIndex> indexes = new List <MemoryIndex>(); CollectionMemoryUtils.AddAll(indexes, newStructure.Readonly.ReadonlyChangeTracker.IndexChanges); IReadOnlySnapshotStructure previousStructure = previousTracker.Container; foreach (MemoryIndex index in indexes) { IIndexDefinition newDefinition = getIndexDefinitionOrUndefined(index, newStructure.Readonly); IIndexDefinition previousDefinition = getIndexDefinitionOrUndefined(index, previousStructure); if (compareIndexDefinitions(newDefinition, previousDefinition)) { newStructure.Writeable.WriteableChangeTracker.RemoveIndexChange(index); } } } }
/// <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; } } } }