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