예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
        /// <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));
        }
예제 #4
0
            /// <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));
            }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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();
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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));
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        /// <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());
            }
        }
예제 #13
0
        /// <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));
            }
        }
예제 #14
0
        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));
        }