Ejemplo n.º 1
0
        /// <summary>
        /// Processes the merge operation.
        /// </summary>
        /// <param name="operation">The operation.</param>
        private void processMergeOperation(MergeOperation operation)
        {
            MemoryIndex targetIndex            = operation.TargetIndex;
            var         targetIndexDatasources = targetSnapshot.MergeInfo.GetOrCreateDatasourcesContaier(targetIndex);

            // 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);

                // Collect array and aliases data
                arrayWorker.collectSourceArray(targetIndex, operation, operationContext, sourceDefinition.Array);
                aliasWorker.collectSourceAliases(sourceDefinition.Aliases);
                objectWorker.collectSourceObjects(sourceDefinition.Objects);

                // Store datasource for data and info merging
                targetIndexDatasources.SetDatasource(context.SourceSnapshot, sourceIndex);
            }

            IIndexDefinition targetDefinition;

            if (targetStructure.TryGetIndexDefinition(targetIndex, out targetDefinition))
            {
                // Index is set in target snapshot
                if (targetDefinition.Array != null)
                {
                    arrayWorker.SetTargetArray(targetDefinition.Array);
                }
            }
            else
            {
                // Index is not set in target snapshot - create it
                writeableTargetStructure.NewIndex(targetIndex);
            }

            aliasWorker.MergeAliasesAndClear(targetIndex, operation);
            arrayWorker.MergeArraysAndClear(targetSnapshot, targetIndex, operation);
            objectWorker.MergeObjectsAndClear(targetIndex);
        }
Ejemplo n.º 2
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;
        }
Ejemplo n.º 3
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);
                    }
                }
            }
        }