Example #1
0
        private void mergeWithEmptyAssignedArray(AssociativeArray sourceArray, AssociativeArray targetArray)
        {
            // Get descriptors
            IArrayDescriptor        sourceDescriptor        = Worker.Structure.GetDescriptor(sourceArray);
            IArrayDescriptorBuilder targetDescriptorBuilder = Worker.Structure.GetDescriptor(targetArray).Builder(Worker.Structure);

            // Create child index and merge with empty node
            foreach (var item in sourceDescriptor.Indexes)
            {
                string      name  = item.Key;
                MemoryIndex index = item.Value;

                MemoryIndex createdIndex = TargetIndex.CreateIndex(name);
                targetDescriptorBuilder.AddIndex(name, createdIndex);

                Worker.AddOperation(new UnknownIndexMayAssign(Worker, index, createdIndex, MemoryEntryCollectorNode.GetEmptyNode(Worker.Snapshot)));
            }

            // Merge unknown index with empty node (unknown index was created in array initialization - scip new array)
            UnknownIndexMayAssign toUnknownAssignOperation = new UnknownIndexMayAssign(Worker, sourceDescriptor.UnknownIndex,
                                                                                       targetDescriptorBuilder.UnknownIndex, MemoryEntryCollectorNode.GetEmptyNode(Worker.Snapshot));

            toUnknownAssignOperation.CreateNewIndex = false;
            Worker.AddOperation(toUnknownAssignOperation);

            // Build and set modified target descriptor
            Worker.Structure.SetDescriptor(targetArray, targetDescriptorBuilder.Build(Worker.Structure));
        }
Example #2
0
        /// <summary>
        /// Processes the index - traverse thru array or sets path to undefined. When memory location contains
        /// no array and undefined value new array is created.
        /// </summary>
        /// <param name="segment">The segment.</param>
        /// <param name="parentIndex">Index of the parent.</param>
        /// <param name="visitor">The visitor to process scalar values.</param>
        /// <param name="isMust">if set to <c>true</c> [is must].</param>
        private void processIndex(PathSegment segment, MemoryIndex parentIndex, IndexLocationVisitor visitor, bool isMust)
        {
            AssociativeArray arrayValue         = null;
            bool             processOtherValues = false;
            MemoryEntry      entry;

            if (snapshot.Data.Readonly.TryGetMemoryEntry(parentIndex, out entry))
            {
                if (snapshot.Structure.Readonly.TryGetArray(parentIndex, out arrayValue))
                {
                    processOtherValues = entry.Count > 1;
                }
                else if (entry.Count > 0)
                {
                    processOtherValues = true;
                }
                else
                {
                    entry = snapshot.EmptyEntry;
                    processOtherValues = true;
                }
            }
            else
            {
                entry = snapshot.EmptyEntry;
                processOtherValues = true;
                snapshot.Structure.Readonly.TryGetArray(parentIndex, out arrayValue);
            }

            if (!snapshot.Structure.Locked && processOtherValues)
            {
                visitor.ProcessValues(parentIndex, entry.PossibleValues, isMust);
                ReadIndexVisitor valueVisitor    = visitor.LastValueVisitor;
                bool             removeUndefined = isMust;

                if (valueVisitor.ContainsDefinedValue || valueVisitor.ContainsAnyValue)
                {
                    isMust = false;
                }

                if (valueVisitor.ContainsUndefinedValue)
                {
                    if (arrayValue == null)
                    {
                        arrayValue = snapshot.CreateArray(parentIndex, isMust, removeUndefined);
                    }
                    else if (removeUndefined)
                    {
                        snapshot.RemoveUndefinedFromMemoryEntry(parentIndex);
                    }
                }
            }

            if (arrayValue != null)
            {
                IArrayDescriptor descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue);
                creatorVisitor.ArrayValue = arrayValue;
                processSegment(segment, descriptor, isMust);
            }
        }
Example #3
0
        /// <summary>
        /// Deletes the array.
        /// </summary>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="targetArray">The target array.</param>
        public void DeleteArray(MemoryIndex targetIndex, AssociativeArray targetArray)
        {
            IArrayDescriptor targetArrayDescriptor = targetStructure.GetDescriptor(targetArray);

            foreach (var index in targetArrayDescriptor.Indexes)
            {
                // Enqueue delete operation for every child index
                MemoryIndex    childIndex     = index.Value;
                MergeOperation childOperation = new MergeOperation();
                childOperation.SetTargetIndex(childIndex);
                childOperation.SetDeleteOperation();
                operationQueue.AddLast(childOperation);
            }

            // Enqueue delete operation for unknown index
            MergeOperation unknownOperation = new MergeOperation();

            unknownOperation.SetTargetIndex(targetArrayDescriptor.UnknownIndex);
            unknownOperation.SetUndefined();
            unknownOperation.SetDeleteOperation();
            operationQueue.AddLast(unknownOperation);

            // Deletes array from structure
            writeableTargetStructure.RemoveArray(targetIndex, targetArray);
        }
Example #4
0
        /// <summary>
        /// Collects the source array.
        /// </summary>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="operation">The operation.</param>
        /// <param name="operationContext">The operation context.</param>
        /// <param name="sourceArray">The source array.</param>
        public void collectSourceArray(MemoryIndex targetIndex, MergeOperation operation, MergeOperationContext operationContext, AssociativeArray sourceArray)
        {
            // Source array
            if (sourceArray != null)
            {
                // Becomes target array when not set
                if (targetArray == null && operationContext.Index.Equals(targetIndex))
                {
                    targetArray = sourceArray;
                }
                hasArray = true;

                // Save source array to merge descriptors
                IArrayDescriptor descriptor = operationContext.SnapshotContext.SourceStructure.GetDescriptor(sourceArray);
                sourceArrays.Add(new ContainerContext(operationContext.SnapshotContext, descriptor, operationContext.OperationType));

                // Equeue all array indexes when whole subtree should be merged
                if (operationContext.OperationType == MergeOperationType.WholeSubtree)
                {
                    foreach (var index in descriptor.Indexes)
                    {
                        operation.TreeNode.GetOrCreateChild(index.Key);
                    }
                    operation.TreeNode.GetOrCreateAny();
                }
            }
            else
            {
                // Source do not contain array - at least one source is empty
                arrayAlwaysDefined = false;
            }
        }
Example #5
0
        /// <summary>
        /// Processes the delete operation.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="operationAccessor">The operation accessor.</param>
        private void processDeleteOperation(MergeOperation operation, TrackingMergeWorkerOperationAccessor operationAccessor)
        {
            MemoryIndex      targetIndex = operation.TargetIndex;
            IIndexDefinition targetDefinition;

            if (targetStructure.TryGetIndexDefinition(targetIndex, out targetDefinition))
            {
                // Index is set in target snapshot
                if (targetDefinition.Array != null)
                {
                    // Target contains array - continue deleting
                    AssociativeArray targetArray           = targetDefinition.Array;
                    IArrayDescriptor targetArrayDescriptor = targetStructure.GetDescriptor(targetArray);

                    foreach (var index in targetArrayDescriptor.Indexes)
                    {
                        // Enqueue delete operation for every child index
                        MemoryIndex    childIndex     = index.Value;
                        MergeOperation childOperation = new MergeOperation();
                        childOperation.SetTargetIndex(childIndex);
                        childOperation.SetDeleteOperation();
                        operationQueue.AddLast(childOperation);
                    }

                    // Enqueue delete operation for unknown index
                    MergeOperation unknownOperation = new MergeOperation();
                    unknownOperation.SetTargetIndex(targetArrayDescriptor.UnknownIndex);
                    unknownOperation.SetUndefined();
                    unknownOperation.SetDeleteOperation();
                    operationQueue.AddLast(unknownOperation);
                }

                operationAccessor.provideCustomDeleteOperation(targetIndex, targetDefinition);
            }
        }
Example #6
0
        /// <summary>
        /// Processes the source array.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="arrayValue">The array value.</param>
        /// <param name="values">The values.</param>
        private void processSourceArray(MemoryCollectorNode node, AssociativeArray arrayValue, ICollection <Value> values)
        {
            if (arrayValue != null)
            {
                IArrayDescriptor sourceArray = Structure.GetDescriptor(arrayValue);

                if (node.AnyChildNode == null)
                {
                    node.CreateMemoryIndexAnyChild(sourceArray.UnknownIndex);
                }

                foreach (var item in sourceArray.Indexes)
                {
                    string      name  = item.Key;
                    MemoryIndex index = item.Value;

                    if (!node.NamedChildNodes.ContainsKey(name))
                    {
                        LocationCollectorNode newChild = node.CreateMemoryIndexChildFromAny(name, sourceArray.UnknownIndex);
                        newChild.IsMust = node.IsMust;
                    }
                }

                createArray(node, values);
            }
            else
            {
                testAndCreateImplicitArray(node, values);
            }
        }
Example #7
0
        private void mergeWithAssignedArray(AssociativeArray sourceArray, AssociativeArray targetArray)
        {
            // Get descriptors
            IArrayDescriptor        sourceDescriptor        = Worker.Structure.GetDescriptor(sourceArray);
            IArrayDescriptorBuilder targetDescriptorBuilder = Worker.Structure.GetDescriptor(targetArray).Builder(Worker.Structure);

            // Iterate source indexes which are not present in node
            foreach (var item in sourceDescriptor.Indexes)
            {
                string      name  = item.Key;
                MemoryIndex index = item.Value;

                if (!Node.NamedChildren.ContainsKey(name))
                {
                    // Index is present in source but not in node
                    MemoryIndex createdIndex = TargetIndex.CreateIndex(name);
                    targetDescriptorBuilder.AddIndex(name, createdIndex);

                    Worker.AddOperation(new UnknownIndexMayAssign(Worker, index, createdIndex, MemoryEntryCollectorNode.GetEmptyNode(Worker.Snapshot)));
                }
            }

            // Iterate all child nodes
            foreach (var item in Node.NamedChildren)
            {
                string name = item.Key;
                MemoryEntryCollectorNode node = item.Value;

                if (sourceDescriptor.ContainsIndex(name))
                {
                    // Index is present in source and node
                    MemoryIndex createdIndex = TargetIndex.CreateIndex(name);
                    targetDescriptorBuilder.AddIndex(name, createdIndex);

                    Worker.AddOperation(new UnknownIndexMayAssign(Worker, sourceDescriptor.GetIndex(name), createdIndex, node));
                }
                else
                {
                    // Index is present in node but not in source
                    MemoryIndex createdIndex = TargetIndex.CreateIndex(name);
                    targetDescriptorBuilder.AddIndex(name, createdIndex);

                    Worker.AddOperation(new UnknownIndexMayAssign(Worker, sourceDescriptor.UnknownIndex, createdIndex, node));
                }
            }

            // Merge unknown index with unknown node (unknown index was created in array initialization - scip new array)
            UnknownIndexMayAssign toUnknownAssignOperation = new UnknownIndexMayAssign(Worker, sourceDescriptor.UnknownIndex,
                                                                                       targetDescriptorBuilder.UnknownIndex, Node.AnyChild);

            toUnknownAssignOperation.CreateNewIndex = false;
            Worker.AddOperation(toUnknownAssignOperation);

            // Build and set modified target descriptor
            Worker.Structure.SetDescriptor(targetArray, targetDescriptorBuilder.Build(Worker.Structure));
        }
Example #8
0
        private void mergeWithAssignedArray(AssociativeArray arrayValue)
        {
            // Get descriptors
            IArrayDescriptor        descriptor = Worker.Structure.GetDescriptor(arrayValue);
            IArrayDescriptorBuilder builder    = Worker.Structure.GetDescriptor(arrayValue).Builder(Worker.Structure);

            // Iterate source indexes which are not present in node
            List <string> namesToRemove = new List <string>();

            foreach (var item in descriptor.Indexes)
            {
                string      name  = item.Key;
                MemoryIndex index = item.Value;

                if (!Node.NamedChildren.ContainsKey(name))
                {
                    // Index is present in source but not in node
                    Worker.AddOperation(new MemoryIndexDeleteAssignOperation(Worker, index));
                    namesToRemove.Add(name);
                }
            }

            // Safely removes nodes which are no longer used (prevents changes in lazy builder)
            foreach (string name in namesToRemove)
            {
                builder.RemoveIndex(name);
            }

            // Iterate all child nodes
            foreach (var item in Node.NamedChildren)
            {
                string name = item.Key;
                MemoryEntryCollectorNode node = item.Value;

                if (descriptor.ContainsIndex(name))
                {
                    // Index is present in source and node
                    Worker.AddOperation(new MemoryIndexMustAssignOperation(Worker, descriptor.GetIndex(name), node));
                }
                else
                {
                    // Index is present in node but not in source
                    MemoryIndex createdIndex = TargetIndex.CreateIndex(name);
                    builder.AddIndex(name, createdIndex);

                    Worker.AddOperation(new UndefinedMustAssignOperation(Worker, createdIndex, node));
                }
            }

            // Merge unknown index with unknown node (unknown index was created in array initialization - scip new array)
            Worker.AddOperation(new MemoryIndexMustAssignOperation(Worker, descriptor.UnknownIndex, Node.AnyChild));

            // Build and set modified target descriptor
            Worker.Structure.SetDescriptor(arrayValue, builder.Build(Worker.Structure));
        }
Example #9
0
        private void mergeWithEmptyAssignedArray(AssociativeArray arrayValue)
        {
            IArrayDescriptor descriptor = Worker.Structure.GetDescriptor(arrayValue);

            foreach (var item in descriptor.Indexes)
            {
                string      name  = item.Key;
                MemoryIndex index = item.Value;

                Worker.AddOperation(new MemoryIndexMayAssignOperation(Worker, index, MemoryEntryCollectorNode.GetEmptyNode(Worker.Snapshot)));
            }
            Worker.AddOperation(new MemoryIndexMayAssignOperation(Worker, descriptor.UnknownIndex, MemoryEntryCollectorNode.GetEmptyNode(Worker.Snapshot)));
        }
Example #10
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);
        }
Example #11
0
        private void deleteArray(AssociativeArray arrayValue)
        {
            IArrayDescriptor oldDescriptor = Worker.Structure.GetDescriptor(arrayValue);

            foreach (var item in oldDescriptor.Indexes)
            {
                string      name  = item.Key;
                MemoryIndex index = item.Value;
                Worker.AddOperation(new MemoryIndexDeleteAssignOperation(Worker, index));
            }
            Worker.AddOperation(new MemoryIndexDeleteAssignOperation(Worker, oldDescriptor.UnknownIndex));

            Worker.Structure.RemoveArray(TargetIndex, arrayValue);
        }
Example #12
0
        /// <summary>
        /// Creates the array.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="values">The values.</param>
        /// <returns>New created array</returns>
        public AssociativeArray createArray(MemoryCollectorNode node, ICollection <Value> values)
        {
            AssociativeArray createdArrayValue = Snapshot.CreateArray(node.TargetIndex);

            values.Add(createdArrayValue);

            if (node.AnyChildNode != null)
            {
                IArrayDescriptor descriptor = Structure.GetDescriptor(createdArrayValue);
                node.AnyChildNode.TargetIndex = descriptor.UnknownIndex;
            }

            return(createdArrayValue);
        }
Example #13
0
        /// <summary>
        /// Merges the arrays into the target index and clear inner collection.
        /// </summary>
        /// <param name="targetSnapshot">The target snapshot.</param>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="operation">The operation.</param>
        public void MergeArraysAndClear(Snapshot targetSnapshot, MemoryIndex targetIndex, MergeOperation operation)
        {
            if (hasArray)
            {
                if (targetArray == null)
                {
                    targetArray = targetSnapshot.CreateArray();
                }

                IArrayDescriptor targetArrayDescriptor;
                if (!writeableTargetStructure.TryGetDescriptor(targetArray, out targetArrayDescriptor))
                {
                    // Target does not contain array - create and add new in target snapshot
                    targetArrayDescriptor = worker.Factories.StructuralContainersFactories.ArrayDescriptorFactory.CreateArrayDescriptor(writeableTargetStructure, targetArray, targetIndex);
                    writeableTargetStructure.SetDescriptor(targetArray, targetArrayDescriptor);
                    writeableTargetStructure.NewIndex(targetArrayDescriptor.UnknownIndex);
                    writeableTargetStructure.SetArray(targetIndex, targetArray);
                }

                // Create context and merge descriptors
                var arrayContext = new ArrayTargetContainerContext(writeableTargetStructure, targetArrayDescriptor);
                worker.CreateAndEnqueueOperations(arrayContext, operation.TreeNode, sourceArrays, arrayAlwaysDefined && !operation.IsUndefined);

                // Update current descriptor when changed
                IArrayDescriptor currentDescriptor = arrayContext.getCurrentDescriptor();
                if (currentDescriptor != targetArrayDescriptor)
                {
                    writeableTargetStructure.SetDescriptor(targetArray, currentDescriptor);
                }

                sourceArrays.Clear();
                hasArray    = false;
                targetArray = null;
            }
            else if (targetArray != null)
            {
                worker.DeleteArray(targetIndex, targetArray);

                targetArray = null;
            }
            arrayAlwaysDefined = true;
        }
Example #14
0
        /// <summary>
        /// Collects the index of the index from memory.
        /// </summary>
        /// <param name="collector">The collector.</param>
        /// <param name="indexSegment">The index segment.</param>
        /// <param name="index">The index.</param>
        protected void CollectIndexFromMemoryIndex(TreeIndexCollector collector, IndexPathSegment indexSegment, MemoryIndex index)
        {
            MemoryEntry entry = collector.GetMemoryEntry(index);

            this.ContainsUndefinedValue = entry.ContainsUndefinedValue;
            bool processOtherValues = false;

            AssociativeArray arrayValue;

            if (collector.Structure.TryGetArray(index, out arrayValue))
            {
                if (entry.ContainsUndefinedValue)
                {
                    processOtherValues = entry.Count > 2;
                }
                else
                {
                    processOtherValues = entry.Count > 1;
                }

                IArrayDescriptor descriptor = collector.Structure.GetDescriptor(arrayValue);
                collector.CollectSegmentFromStructure(indexSegment, this, descriptor, !processOtherValues);
            }
            else if (entry.ContainsUndefinedValue)
            {
                processOtherValues = entry.Count > 1;

                this.HasNewImplicitArray = true;
                collector.CollectSegmentWithoutStructure(indexSegment, this, !processOtherValues);
            }
            else
            {
                processOtherValues = true;
            }

            if (processOtherValues)
            {
                collector.CollectIndexSegmentFromValues(indexSegment, this, entry.PossibleValues, true);
            }
        }
Example #15
0
        /// <summary>
        /// Processes the array value - create new copy of this level of memory tree.
        /// </summary>
        /// <param name="targetIndex">Index of the target.</param>
        /// <param name="value">The value.</param>
        /// <returns>Array value which should be inserted into target location.</returns>
        internal AssociativeArray ProcessArrayValue(MemoryIndex targetIndex, AssociativeArray value)
        {
            AssociativeArray arrayValue = snapshot.CreateArray(targetIndex, isMust);

            IArrayDescriptor sourceDescriptor = snapshot.Structure.Readonly.GetDescriptor(value);
            IArrayDescriptor targetDescriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue);

            CopyAliasState oldState = AliasState;

            AliasState = CopyAliasState.OnlyAliases;
            Copy(sourceDescriptor.UnknownIndex, targetDescriptor.UnknownIndex);

            AliasState = CopyAliasState.LinkWithIndex;
            foreach (var index in sourceDescriptor.Indexes)
            {
                MemoryIndex newIndex = snapshot.CreateIndex(index.Key, arrayValue, false, false);
                Copy(index.Value, newIndex);
            }

            AliasState = oldState;
            return(arrayValue);
        }
Example #16
0
        /// <summary>
        /// Tests the and create undefined children.
        /// </summary>
        /// <param name="node">The node.</param>
        private void testAndCreateUndefinedChildren(MemoryCollectorNode node)
        {
            if (node.HasUndefinedChildren)
            {
                AssociativeArray arrayValue = Structure.GetArray(node.TargetIndex);

                IArrayDescriptor        oldDescriptor = Structure.GetDescriptor(arrayValue);
                IArrayDescriptorBuilder builder       = oldDescriptor.Builder(Structure);

                foreach (var newChild in node.UndefinedChildren)
                {
                    string childName = newChild.Item1;
                    MemoryCollectorNode childNode = newChild.Item2;

                    MemoryIndex index = node.TargetIndex.CreateIndex(childName);
                    childNode.TargetIndex = index;

                    builder.AddIndex(childName, index);
                }

                IArrayDescriptor newDescriptor = builder.Build(Structure);
                Structure.SetDescriptor(arrayValue, newDescriptor);
            }
        }
Example #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ArrayTargetContainerContext"/> class.
 /// </summary>
 /// <param name="strucure">The strucure.</param>
 /// <param name="arrayDescriptor">The array descriptor.</param>
 public ArrayTargetContainerContext(IWriteableSnapshotStructure strucure, IArrayDescriptor arrayDescriptor)
 {
     this.arrayDescriptor = arrayDescriptor;
     this.strucure        = strucure;
 }
Example #18
0
 /// <inheritdoc />
 public override void SetDescriptor(AssociativeArray arrayvalue, IArrayDescriptor descriptor)
 {
     arrayDescriptors[arrayvalue] = descriptor;
 }
Example #19
0
 /// <inheritdoc />
 public override bool TryGetDescriptor(AssociativeArray arrayValue, out IArrayDescriptor descriptor)
 {
     return(arrayDescriptors.TryGetValue(arrayValue, out descriptor));
 }
Example #20
0
 /// <inheritdoc />
 public abstract bool TryGetDescriptor(AssociativeArray arrayValue, out IArrayDescriptor descriptor);
Example #21
0
 /// <inheritdoc />
 public abstract void SetDescriptor(AssociativeArray arrayvalue, IArrayDescriptor descriptor);
Example #22
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);
        }
Example #23
0
 /// <inheritdoc />
 public override void SetDescriptor(AssociativeArray arrayvalue, IArrayDescriptor descriptor)
 {
     arrayDescriptors[arrayvalue] = descriptor;
     changeTracker.ModifiedIndex(descriptor.ParentIndex);
 }
Example #24
0
        public void CollectChildren(MemoryEntryCollector collector)
        {
            if (Arrays != null && Arrays.Count > 0)
            {
                // Create new collection for named children
                NamedChildren = new Dictionary <string, MemoryEntryCollectorNode>();

                // Any child node
                AnyChild = new MemoryEntryCollectorNode();
                AnyChild.SourceIndexes = new List <SourceIndex>();
                AnyChild.IsMust        = false;
                collector.AddNode(AnyChild);

                // Collect child names and adds any child sources
                HashSet <string> names = new HashSet <string>();
                List <Tuple <Snapshot, IArrayDescriptor> > sourceDescriptors = new List <Tuple <Snapshot, IArrayDescriptor> >();
                foreach (AssociativeArray arrayValue in Arrays)
                {
                    var descriptors = getIArrayDescriptors(collector, arrayValue);
                    foreach (var tuple in descriptors)
                    {
                        sourceDescriptors.Add(tuple);

                        Snapshot         sourceSnapshot = tuple.Item1;
                        IArrayDescriptor descriptor     = tuple.Item2;

                        AnyChild.SourceIndexes.Add(new SourceIndex(descriptor.UnknownIndex, sourceSnapshot));
                        foreach (var item in descriptor.Indexes)
                        {
                            names.Add(item.Key);
                        }
                    }
                }

                // Test whether new array as MAY or MUST
                bool mustHaveChildren = this.IsMust && mustHaveArray;
                mustHaveChildren &= (ScalarValues == null || ScalarValues.Count == 0);
                mustHaveChildren &= (Objects == null || Objects.Count == 0);

                // Iterates collected names and stors them into the structure
                foreach (string name in names)
                {
                    MemoryEntryCollectorNode childNode = new MemoryEntryCollectorNode();
                    childNode.SourceIndexes = new List <SourceIndex>();
                    childNode.IsMust        = mustHaveChildren;
                    collector.AddNode(childNode);
                    NamedChildren.Add(name, childNode);

                    // Collect sources for named child
                    foreach (var tuple in sourceDescriptors)
                    {
                        Snapshot         sourceSnapshot = tuple.Item1;
                        IArrayDescriptor descriptor     = tuple.Item2;

                        MemoryIndex index;
                        if (descriptor.TryGetIndex(name, out index))
                        {
                            childNode.SourceIndexes.Add(new SourceIndex(index, sourceSnapshot));
                        }
                        else
                        {
                            childNode.IsMust = false;
                            childNode.SourceIndexes.Add(new SourceIndex(descriptor.UnknownIndex, sourceSnapshot));
                        }
                    }
                }
            }
        }
Example #25
0
        /// <summary>
        /// Processes the merge operation.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="operationAccessor">The operation accessor.</param>
        /// <exception cref="System.Exception">
        /// Error merging structure in readonly mode - undefined index  + targetIndex
        /// or
        /// Error merging structure in readonly mode - target descriptor for  + targetIndex
        /// </exception>
        private void processMergeOperation(MergeOperation operation, TrackingMergeWorkerOperationAccessor operationAccessor)
        {
            MemoryIndex             targetIndex  = operation.TargetIndex;
            AssociativeArray        targetArray  = null;
            List <ContainerContext> sourceArrays = new List <ContainerContext>();
            bool arrayAlwaysDefined = !operation.IsUndefined;
            bool cotainsArray       = false;

            // Iterate sources
            foreach (MergeOperationContext operationContext in operation.Indexes)
            {
                // Retreive source context and definition
                MemoryIndex      sourceIndex      = operationContext.Index;
                SnapshotContext  context          = operationContext.SnapshotContext;
                IIndexDefinition sourceDefinition = context.SourceStructure.GetIndexDefinition(sourceIndex);

                // Provide custom operation for merge algorithm
                operationAccessor.addSource(operationContext, sourceDefinition);

                // Source array
                if (sourceDefinition.Array != null)
                {
                    // Becomes target array when not set
                    if (targetArray == null && sourceIndex.Equals(targetIndex))
                    {
                        targetArray = sourceDefinition.Array;
                    }
                    cotainsArray = true;

                    // Save source array to merge descriptors
                    IArrayDescriptor descriptor = context.SourceStructure.GetDescriptor(sourceDefinition.Array);
                    sourceArrays.Add(new ContainerContext(context, descriptor, operationContext.OperationType));

                    // Equeue all array indexes when whole subtree should be merged
                    if (operationContext.OperationType == MergeOperationType.WholeSubtree)
                    {
                        foreach (var index in descriptor.Indexes)
                        {
                            operation.TreeNode.GetOrCreateChild(index.Key);
                        }
                        operation.TreeNode.GetOrCreateAny();
                    }
                }
                else
                {
                    // Source do not contain array - at least one source is empty
                    arrayAlwaysDefined = false;
                }
            }

            IIndexDefinition targetDefinition;
            IArrayDescriptor targetArrayDescriptor = null;

            if (targetStructure.TryGetIndexDefinition(targetIndex, out targetDefinition))
            {
                // Index is set in target snapshot
                if (targetDefinition.Array != null)
                {
                    // Target contains array - continue merging
                    targetArray           = targetDefinition.Array;
                    targetArrayDescriptor = targetStructure.GetDescriptor(targetArray);
                }
            }
            else
            {
                // Index is not set in target snapshot - create it
                if (isStructureWriteable)
                {
                    writeableTargetStructure.NewIndex(targetIndex);
                }
                else
                {
                    throw new Exception("Error merging structure in readonly mode - undefined index " + targetIndex);
                }
            }

            // Provide custom operation for merge algorithm
            operationAccessor.provideCustomOperation(targetIndex);

            // Process next array
            if (cotainsArray)
            {
                if (targetArray == null)
                {
                    targetArray = targetSnapshot.CreateArray();
                }

                if (targetArrayDescriptor == null)
                {
                    // Target does not contain array - create and add new in target snapshot
                    if (isStructureWriteable)
                    {
                        targetArrayDescriptor = Factories.StructuralContainersFactories.ArrayDescriptorFactory.CreateArrayDescriptor(writeableTargetStructure, targetArray, targetIndex);
                        writeableTargetStructure.SetDescriptor(targetArray, targetArrayDescriptor);
                        writeableTargetStructure.NewIndex(targetArrayDescriptor.UnknownIndex);
                        writeableTargetStructure.SetArray(targetIndex, targetArray);
                    }
                    else
                    {
                        throw new Exception("Error merging structure in readonly mode - target descriptor for " + targetIndex);
                    }
                }

                // Create context and merge descriptors
                var arrayContext = new ArrayTargetContainerContext(writeableTargetStructure, targetArrayDescriptor);
                createAndEnqueueOperations(arrayContext, operation.TreeNode, sourceArrays, arrayAlwaysDefined);

                if (isStructureWriteable)
                {
                    // Ubdate current descriptor when changed
                    IArrayDescriptor currentDescriptor = arrayContext.getCurrentDescriptor();
                    if (currentDescriptor != targetArrayDescriptor)
                    {
                        writeableTargetStructure.SetDescriptor(targetArray, currentDescriptor);
                    }
                }
            }
        }