Esempio n. 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));
        }
Esempio n. 2
0
        /// <summary>
        /// Prepares operation for every descendant index of target array.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <returns>Array where the input arrays is merged into.</returns>
        private void mergeArrays(MergeOperation operation)
        {
            AssociativeArray    targetArray      = Structure.Readonly.GetArray(operation.TargetIndex);
            IArrayDescriptor    targetDescriptor = Structure.Readonly.GetDescriptor(targetArray);
            ContainerOperations collectIndexes   = new ContainerOperations(this, targetDescriptor, operation.TargetIndex, targetDescriptor.UnknownIndex);

            foreach (var operationData in operation.Indexes)
            {
                MemoryIndex index    = operationData.Item1;
                Snapshot    snapshot = operationData.Item2;

                AssociativeArray arrayValue;
                if (snapshot.Structure.Readonly.TryGetArray(index, out arrayValue))
                {
                    IArrayDescriptor descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue);
                    collectIndexes.AddContainer(descriptor, snapshot);
                }
                else
                {
                    collectIndexes.SetUndefined();
                }
            }

            collectIndexes.MergeContainers();
        }
Esempio n. 3
0
        /// <summary>
        /// Creates merge operations for all indexes in the target collection. Source indexes for the operation are
        /// retreived from the source collections. When there is missing index in some collection the operation set
        /// to undefined.
        ///
        /// This method is for both phases of analysis.
        /// </summary>
        public void MergeContainers()
        {
            // Process all names which has unassociated index and creates one
            foreach (string indexName in undefinedIndexes)
            {
                writeableTargetContainer.AddIndex(indexName, targetIndex.CreateIndex(indexName));
            }

            foreach (var index in targetContainer.Indexes)
            {
                MergeOperation operation = new MergeOperation(index.Value);
                worker.addOperation(operation);

                if (isUndefined)
                {
                    operation.SetUndefined();
                }

                foreach (var source in sources)
                {
                    IReadonlyIndexContainer container = source.Item1;
                    Snapshot snapshot = source.Item2;

                    MemoryIndex containerIndex;
                    if (container.TryGetIndex(index.Key, out containerIndex))
                    {
                        operation.Add(containerIndex, snapshot);
                    }
                    else
                    {
                        operation.Add(container.UnknownIndex, snapshot);
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Gets the operation at the top of operation stack. Operation is removed from stack.
        /// </summary>
        /// <returns>First operation in the memory stack</returns>
        private MergeOperation getOperation()
        {
            MergeOperation operation = operationStack.First.Value;

            operationStack.RemoveFirst();

            return(operation);
        }
Esempio n. 5
0
        /// <summary>
        /// Process all merge operations. Continues processing until operation stack is empty.
        /// </summary>
        private void processMerge()
        {
            while (operationStack.Count > 0)
            {
                MergeOperation operation = getOperation();

                processMergeOperation(operation);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// 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>
        /// <returns>Array where the input arrays is merged into.</returns>
        private Value mergeArrays(MergeOperation operation)
        {
            var structure = writeableStrucure;
            IArrayDescriptorBuilder builder = Factories.StructuralContainersFactories.ArrayDescriptorFactory.CreateArrayDescriptor(writeableStrucure, null, operation.TargetIndex).Builder(structure);

            builder.SetUnknownIndex(operation.TargetIndex.CreateUnknownIndex());

            ContainerOperations collectVariables = new ContainerOperations(this, builder, operation.TargetIndex, builder.UnknownIndex);

            // Collecting possible indexes of merged array
            AssociativeArray targetArray = null;

            foreach (var operationData in operation.Indexes)
            {
                MemoryIndex index    = operationData.Item1;
                Snapshot    snapshot = operationData.Item2;

                AssociativeArray arrayValue;
                if (snapshot.Structure.Readonly.TryGetArray(index, out arrayValue))
                {
                    // Target array value will be the firs one
                    if (targetArray == null)
                    {
                        if (index.Equals(operation.TargetIndex))
                        {
                            targetArray = arrayValue;
                        }
                    }

                    IArrayDescriptor descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue);
                    collectVariables.CollectIndexes(snapshot, index, descriptor);
                }
                else
                {
                    collectVariables.SetUndefined();
                }
            }

            if (targetArray == null)
            {
                targetArray = targetSnapshot.CreateArray();
            }
            builder.SetArrayValue(targetArray);

            collectVariables.MergeContainers();

            structure.SetArray(operation.TargetIndex, targetArray);
            structure.SetDescriptor(targetArray, builder.Build(structure));

            return(targetArray);
        }
Esempio n. 7
0
        /// <summary>
        /// Main method of merge algorithm.
        ///
        /// iI first phase prepares new empty data collection. Then collects all root memory locations and
        /// prepares their operations. As the final step process all merge operations which traverses the
        /// memory tree and merges data from all source indexes.
        /// </summary>
        internal void Merge()
        {
            ContainerOperations[] collectVariables = new ContainerOperations[targetCallLevel + 1];
            ContainerOperations[] collectControl   = new ContainerOperations[targetCallLevel + 1];
            MergeOperation        returnOperation  = new MergeOperation();

            for (int x = 0; x <= targetCallLevel; x++)
            {
                IReadonlyIndexContainer variables = Structure.Readonly.GetReadonlyStackContext(x).ReadonlyVariables;
                collectVariables[x] = new ContainerOperations(this, variables, variables.UnknownIndex, variables.UnknownIndex);

                IReadonlyIndexContainer control = Structure.Readonly.GetReadonlyStackContext(x).ReadonlyControllVariables;
                collectControl[x] = new ContainerOperations(this, control, control.UnknownIndex, control.UnknownIndex);
            }

            foreach (Snapshot snapshot in sourceSnapshots)
            {
                for (int sourceLevel = 0, targetLevel = 0; targetLevel <= targetCallLevel; sourceLevel++, targetLevel++)
                {
                    if (sourceLevel == snapshot.CallLevel && snapshot.CallLevel != targetCallLevel)
                    {
                        if (isCallMerge)
                        {
                            break;
                        }
                        else
                        {
                            targetLevel = targetCallLevel;
                        }
                    }

                    IReadonlyIndexContainer variables = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyVariables;
                    collectVariables[targetLevel].AddContainer(variables, snapshot);

                    IReadonlyIndexContainer control = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyControllVariables;
                    collectControl[targetLevel].AddContainer(control, snapshot);
                }
            }

            mergeObjects();

            for (int x = 0; x <= targetCallLevel; x++)
            {
                collectVariables[x].MergeContainers();
                collectControl[x].MergeContainers();
                mergeTemporary(x);
            }

            processMerge();
        }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ContainerOperations"/> class.
        /// </summary>
        /// <param name="worker">The worker.</param>
        /// <param name="targetContainer">The target container.</param>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="unknownIndex">Index of the unknown.</param>
        public ContainerOperations(
            IMergeWorker worker,
            IWriteableIndexContainer targetContainer,
            MemoryIndex targetIndex,
            MemoryIndex unknownIndex)
        {
            this.targetContainer          = targetContainer;
            this.writeableTargetContainer = targetContainer;
            this.worker      = worker;
            this.targetIndex = targetIndex;

            unknownOperation = new MergeOperation(unknownIndex);
            worker.addOperation(unknownOperation);
        }
Esempio n. 9
0
        public void MergeIndexes(MemoryIndex targetIndex, MemoryIndex sourceIndex)
        {
            if (!sourceIndex.IsPrefixOf(targetIndex) && !targetIndex.IsPrefixOf(sourceIndex))
            {
                MergeOperation operation = new MergeOperation(targetIndex);
                operation.Add(targetIndex, targetSnapshot);
                operation.Add(sourceIndex, targetSnapshot);
                operation.IsRoot = true;
                addOperation(operation);

                arrayCount = 2;

                processMerge();
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Gets all values which can be in target memory entry. If sources contains some arrays merge this arrays together
        /// and traverse their indexes.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="visitor">The visitor.</param>
        /// <returns>Values for the target memory entry.</returns>
        private HashSet <Value> getValues(MergeOperation operation, CollectComposedValuesVisitor visitor)
        {
            HashSet <Value> values        = visitor.Values;
            bool            noScalarValue = visitor.Values.Count == 0;

            if (visitor.Arrays.Count > 0)
            {
                values.Add(mergeArrays(operation));
            }

            foreach (ObjectValue value in visitor.Objects)
            {
                values.Add(value);
            }

            return(values);
        }
Esempio n. 11
0
        /// <summary>
        /// Creates merge operations for all temporary indexes in the target structure.
        /// </summary>
        /// <param name="index">The index.</param>
        private void mergeTemporary(int index)
        {
            foreach (var temp in Structure.Readonly.GetReadonlyStackContext(index).ReadonlyTemporaryVariables)
            {
                MergeOperation operation = new MergeOperation(temp);
                addOperation(operation);

                foreach (Snapshot snapshot in sourceSnapshots)
                {
                    if (snapshot.Structure.Readonly.IsDefined(temp))
                    {
                        operation.Add(temp, snapshot);
                    }
                    else
                    {
                        operation.SetUndefined();
                    }
                }
            }
        }
Esempio n. 12
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));
        }
Esempio n. 13
0
        /// <summary>
        /// Creates merge operations for all temporary indexes in the target structure.
        /// </summary>
        /// <param name="index">The index.</param>
        private void mergeTemporary(int index)
        {
            IWriteableSet <MemoryIndex> temporary = writeableStrucure.GetWriteableStackContext(index).WriteableTemporaryVariables;

            foreach (var temp in temporary)
            {
                MergeOperation operation = new MergeOperation(temp);
                addOperation(operation);

                foreach (Snapshot snapshot in sourceSnapshots)
                {
                    if (snapshot.Structure.Readonly.IsDefined(temp))
                    {
                        operation.Add(temp, snapshot);
                    }
                    else
                    {
                        operation.SetUndefined();
                    }
                }
            }
        }
Esempio n. 14
0
        private AssociativeArray mergeArrays(
            MemoryIndex targetIndex,
            HashSet <AssociativeArray> arrays,
            bool includeUndefined)
        {
            AssociativeArray arrayValue;

            if (!targetSnapshot.Structure.Readonly.TryGetArray(targetIndex, out arrayValue))
            {
                arrayValue = targetSnapshot.CreateArray(targetIndex);
            }
            IArrayDescriptor newDescriptor = targetSnapshot.Structure.Readonly.GetDescriptor(arrayValue);

            MergeOperation unknownMerge = new MergeOperation(newDescriptor.UnknownIndex);

            unknownMerge.SetUndefined();
            addOperation(unknownMerge);

            HashSet <string> indexNames = new HashSet <string>();

            foreach (AssociativeArray array in arrays)
            {
                foreach (Tuple <Snapshot, IArrayDescriptor> item in getIArrayDescriptor(array))
                {
                    Snapshot         snapshot   = item.Item1;
                    IArrayDescriptor descriptor = item.Item2;

                    unknownMerge.Add(descriptor.UnknownIndex, snapshot);

                    foreach (var index in descriptor.Indexes)
                    {
                        indexNames.Add(index.Key);
                    }
                }
            }

            foreach (string indexName in indexNames)
            {
                MergeOperation operation = new MergeOperation();

                if (includeUndefined)
                {
                    operation.SetUndefined();
                }

                foreach (var array in arrays)
                {
                    foreach (Tuple <Snapshot, IArrayDescriptor> item in getIArrayDescriptor(array))
                    {
                        Snapshot         snapshot   = item.Item1;
                        IArrayDescriptor descriptor = item.Item2;

                        MemoryIndex sourceIndex;
                        if (descriptor.TryGetIndex(indexName, out sourceIndex))
                        {
                            operation.Add(sourceIndex, snapshot);
                        }
                        else
                        {
                            operation.Add(descriptor.UnknownIndex, snapshot);
                        }
                    }
                }

                MemoryIndex arrayIndex;
                if (!newDescriptor.TryGetIndex(indexName, out arrayIndex))
                {
                    arrayIndex = targetSnapshot.CreateIndex(indexName, arrayValue, true, false);
                }
                operation.SetTargetIndex(arrayIndex);
                addOperation(operation);
            }

            return(arrayValue);
        }
Esempio n. 15
0
 /// <summary>
 /// Adds operation into stack of merge worker.
 /// </summary>
 /// <param name="operation">The operation.</param>
 public void addOperation(MergeOperation operation)
 {
     operationStack.AddLast(operation);
 }
Esempio n. 16
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));
        }
Esempio n. 17
0
        /// <summary>
        /// Main method of merge algorithm.
        ///
        /// in first phase prepares new empty structure and data collections. Then collects all root memory locations
        /// and prepares their operations. As the final step process all merge operations which traverses the memory tree
        /// and creates new memory locations in target structure with the data from all source indexes.
        /// </summary>
        internal void Merge()
        {
            ContainerOperations[] collectVariables = new ContainerOperations[targetSnapshotCallLevel + 1];
            ContainerOperations[] collectControl   = new ContainerOperations[targetSnapshotCallLevel + 1];
            MergeOperation        returnOperation  = new MergeOperation();

            // Prepares empty structure for target snapshot
            for (int x = 0; x <= targetSnapshotCallLevel; x++)
            {
                writeableStrucure.AddLocalLevel();

                IWriteableIndexContainer variables = writeableStrucure.GetWriteableStackContext(x).WriteableVariables;
                collectVariables[x] = new ContainerOperations(this, variables, variables.UnknownIndex, variables.UnknownIndex);

                IWriteableIndexContainer control = writeableStrucure.GetWriteableStackContext(x).WriteableControllVariables;
                collectControl[x] = new ContainerOperations(this, control, control.UnknownIndex, control.UnknownIndex);
            }

            // Collects all objects and root locations from the source objects
            foreach (Snapshot snapshot in sourceSnapshots)
            {
                collectObjects(snapshot);

                for (int sourceLevel = 0, targetLevel = 0; targetLevel <= targetSnapshotCallLevel; sourceLevel++, targetLevel++)
                {
                    // Local levels of snaphot has to be merged together no matter to call level of each snapshot.
                    if (sourceLevel == snapshot.CallLevel && snapshot.CallLevel != targetSnapshotCallLevel)
                    {
                        if (isCallMerge)
                        {
                            // When this is the call merge the local level is forgotten
                            break;
                        }
                        else
                        {
                            targetLevel = targetSnapshotCallLevel;
                        }
                    }

                    // Gets all root locations
                    IWriteableIndexContainer targetVariables = writeableStrucure.GetWriteableStackContext(targetLevel).WriteableVariables;
                    IReadonlyIndexContainer  sourceVariables = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyVariables;
                    collectVariables[targetLevel].CollectIndexes(snapshot, targetVariables.UnknownIndex, sourceVariables);

                    IWriteableIndexContainer targetControlls = writeableStrucure.GetWriteableStackContext(targetLevel).WriteableControllVariables;
                    IReadonlyIndexContainer  sourceControlls = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyControllVariables;
                    collectControl[targetLevel].CollectIndexes(snapshot, targetControlls.UnknownIndex, sourceControlls);
                    collectTemporary(snapshot, sourceLevel, targetLevel);
                }

                foreach (var name in snapshot.Structure.Readonly.GetFunctions())
                {
                    foreach (var decl in snapshot.Structure.Readonly.GetFunction(name))
                    {
                        writeableStrucure.AddFunctiondeclaration(name, decl);
                    }
                }

                foreach (var name in snapshot.Structure.Readonly.GetClasses())
                {
                    foreach (var decl in snapshot.Structure.Readonly.GetClass(name))
                    {
                        writeableStrucure.AddClassDeclaration(name, decl);
                    }
                }

                // When is it call merge remember which arrays was forgotten in order to support arrays in returns
                if (isCallMerge)
                {
                    foreach (AssociativeArray array in snapshot.Structure.Readonly.ReadonlyLocalContext.ReadonlyArrays)
                    {
                        writeableStrucure.AddCallArray(array, snapshot);
                    }
                }
            }

            mergeObjects();

            // Prepares operations for all root locations
            for (int x = 0; x <= targetSnapshotCallLevel; x++)
            {
                collectVariables[x].MergeContainers();
                collectControl[x].MergeContainers();
                mergeTemporary(x);
            }

            processMerge();

            // Build aliases
            foreach (var alias in memoryAliases)
            {
                writeableStrucure.SetAlias(alias.Key, alias.Value.Build(writeableStrucure));
            }
        }
Esempio n. 18
0
 private void addOperation(MergeOperation operation)
 {
     operationStack.AddLast(operation);
 }