/// <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> /// Assigns the specified collector. /// </summary> /// <param name="collector">The collector.</param> /// <param name="sourceIndex">Index of the source.</param> internal void Assign(IIndexCollector collector, MemoryIndex sourceIndex) { foreach (MemoryIndex mustIndex in collector.MustIndexes) { snapshot.DestroyMemory(mustIndex); CopyWithinSnapshotWorker copyWorker = new CopyWithinSnapshotWorker(snapshot, true); copyWorker.Copy(sourceIndex, mustIndex); } foreach (MemoryIndex mayIndex in collector.MayIndexes) { MergeWithinSnapshotWorker mergeWorker = new MergeWithinSnapshotWorker(snapshot); mergeWorker.MergeIndexes(mayIndex, sourceIndex); } MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, sourceIndex); LocationVisitor mustVisitor = new LocationVisitor(snapshot, entry, true); foreach (ValueLocation location in collector.MustLocation) { location.Accept(mustVisitor); } LocationVisitor mayVisitor = new LocationVisitor(snapshot, entry, false); foreach (ValueLocation location in collector.MayLocaton) { location.Accept(mayVisitor); } }
/// <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)); }
/// <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> /// Continues the memory index collector node. /// </summary> /// <param name="node">The node.</param> protected void continueMemoryIndexCollectorNode(MemoryIndexCollectorNode node) { HashSet <Value> values = new HashSet <Value>(); testAndCreateImplicitArray(node, values); testAndCreateImplicitObject(node, values); testAndCreateUndefinedChildren(node); bool removeUndefined = node.IsMust && node.ContainsUndefinedValue; if (removeUndefined || values.Count > 0) { MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(Snapshot, Data, node.TargetIndex); copyEntryValues(entry, values, removeUndefined, false); Data.SetMemoryEntry(node.TargetIndex, Snapshot.CreateMemoryEntry(values)); } enqueueLocationChildNodes(node); }
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 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> /// Continues the unknown index collector node. /// </summary> /// <param name="node">The node.</param> protected void continueUnknownIndexCollectorNode(UnknownIndexCollectorNode node) { Structure.NewIndex(node.TargetIndex); PathModifications.GetOrCreateModification(node.TargetIndex).AddDatasource(node.SourceIndex, Snapshot); IIndexDefinition definition = Structure.GetIndexDefinition(node.SourceIndex); HashSet <Value> values = new HashSet <Value>(); processSourceAliases(node, definition.Aliases); processSourceArray(node, definition.Array, values); processSourceObjects(node, definition.Objects); testAndCreateImplicitObject(node, values); testAndCreateUndefinedChildren(node); MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(Snapshot, Data, node.SourceIndex); copyEntryValues(entry, values, node.IsMust, true); Data.SetMemoryEntry(node.TargetIndex, Snapshot.CreateMemoryEntry(values)); enqueueLocationChildNodes(node); }
/// <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> /// 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) { CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); ReferenceCollector references = new ReferenceCollector(); // Collect all data from source indexes foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, index); visitor.VisitMemoryEntry(entry); IMemoryAlias aliases; if (snapshot.Structure.Readonly.TryGetAliases(index, out aliases)) { references.CollectMust(aliases.MustAliases, targetSnapshotCallLevel); references.CollectMay(aliases.MayAliases, targetSnapshotCallLevel); } else { references.InvalidateMust(); } } references.SetAliases(operation.TargetIndex, this, !operation.IsUndefined); //repares the set of values - array values are traversed HashSet <Value> values = getValues(operation, visitor); // If some index in operation can be undefined add undefined value into result if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } Data.Writeable.SetMemoryEntry(operation.TargetIndex, targetSnapshot.CreateMemoryEntry(values)); writeableStrucure.SetObjects(operation.TargetIndex, Factories.StructuralContainersFactories.ObjectValueContainerFactory.CreateObjectValueContainer(writeableStrucure, visitor.Objects)); }
public void CollectValuesFromSources(MemoryEntryCollector collector) { mustHaveArray = true; foreach (SourceIndex source in SourceIndexes) { MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(source.Snapshot, source.Snapshot.Data.Readonly, source.Index); hasArray = false; this.VisitMemoryEntry(entry); mustHaveArray &= hasArray; } if (!IsMust) { if (ScalarValues == null) { ScalarValues = new HashSet <Value>(); } this.ScalarValues.Add(collector.Snapshot.UndefinedValue); } }
/// <summary> /// Deeply copies the specified source index into target index. /// </summary> /// <param name="sourceIndex">Index of the source.</param> /// <param name="targetIndex">Index of the target.</param> public void Copy(MemoryIndex sourceIndex, MemoryIndex targetIndex) { if (!sourceIndex.IsPrefixOf(targetIndex) && !targetIndex.IsPrefixOf(sourceIndex)) { var writeablestrucutre = snapshot.Structure.Writeable; MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, sourceIndex); CopyWithinSnapshotVisitor visitor = new CopyWithinSnapshotVisitor(snapshot, this, targetIndex); visitor.VisitMemoryEntry(entry); if (isMust && visitor.GetValuesCount() == 1 && objectValues.Count == 1) { IObjectValueContainerBuilder objectsValues = snapshot.Structure.Readonly.GetObjects(targetIndex).Builder(writeablestrucutre); ObjectValue value = objectValues.First(); objectsValues.Add(value); writeablestrucutre.SetObjects(targetIndex, objectsValues.Build(writeablestrucutre)); } else if (objectValues.Count > 0) { IObjectValueContainerBuilder objectsValues = snapshot.Structure.Readonly.GetObjects(targetIndex).Builder(writeablestrucutre); foreach (ObjectValue value in objectValues) { objectsValues.Add(value); } writeablestrucutre.SetObjects(targetIndex, objectsValues.Build(writeablestrucutre)); } if (!isMust) { visitor.AddValue(snapshot.UndefinedValue); } snapshot.CopyAliases(sourceIndex, targetIndex, isMust); snapshot.Data.Writeable.SetMemoryEntry(targetIndex, visitor.GetCopiedEntry()); } }
/// <summary> /// Reads the values from locations specified by given collector. /// </summary> /// <param name="collector">The collector.</param> /// <returns>Memory entry with values from locations specified by given collector.</returns> public MemoryEntry ReadValue(IIndexCollector collector) { if (collector.MustIndexesCount == 1 && collector.IsDefined) { MemoryIndex index = collector.MustIndexes.First(); return(SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, index)); } else { HashSet <Value> values = new HashSet <Value>(); if (!collector.IsDefined) { values.Add(snapshot.UndefinedValue); } foreach (MemoryIndex index in collector.MustIndexes) { MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, index); CollectionMemoryUtils.AddAll(values, entry.PossibleValues); } foreach (ValueLocation location in collector.MustLocation) { if (snapshot.CurrentMode == SnapshotMode.MemoryLevel) { CollectionMemoryUtils.AddAll(values, location.ReadValues(snapshot.MemoryAssistant)); } else { InfoLocationVisitor visitor = new InfoLocationVisitor(snapshot); location.Accept(visitor); CollectionMemoryUtils.AddAll(values, visitor.Value); } } return(new MemoryEntry(values)); } }
private void processMergeOperation(MergeOperation operation) { CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); ReferenceCollector references = new ReferenceCollector(); foreach (var item in operation.Indexes) { Snapshot snapshot = item.Item2; MemoryIndex index = item.Item1; MemoryEntry entry = SnapshotDataUtils.GetMemoryEntry(snapshot, snapshot.CurrentData.Readonly, index); visitor.VisitMemoryEntry(entry); IMemoryAlias aliases; if (snapshot.Structure.Readonly.TryGetAliases(index, out aliases)) { references.CollectMust(aliases.MustAliases, snapshot.CallLevel); references.CollectMay(aliases.MayAliases, snapshot.CallLevel); } else { references.InvalidateMust(); } } if (references.HasAliases && !operation.IsRoot) { if (!operation.IsUndefined && operation.Indexes.Count == 1 && references.HasMustAliases) { if (targetSnapshot == operation.Indexes.First().Item2) { references.AddMustAlias(operation.Indexes.First().Item1); } } else { HashSet <MemoryIndex> referenceIndexes = new HashSet <MemoryIndex>(); foreach (var item in operation.Indexes) { MemoryIndex index = item.Item1; Snapshot snapshot = item.Item2; if (index != operation.TargetIndex && targetSnapshot == snapshot) { referenceIndexes.Add(index); } } references.CollectMay(referenceIndexes, targetSnapshot.CallLevel); } } references.SetAliases(operation.TargetIndex, targetSnapshot, !operation.IsUndefined); HashSet <Value> values = getValues(operation.TargetIndex, visitor, operation.IsUndefined); if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } targetSnapshot.CurrentData.Writeable.SetMemoryEntry(operation.TargetIndex, targetSnapshot.CreateMemoryEntry(values)); }