/// <summary> /// Creates the and enqueue operations. /// </summary> /// <param name="targetContainerContext">The target container context.</param> /// <param name="treeNode">The tree node.</param> /// <param name="sourceContainers">The source containers.</param> /// <param name="alwaysDefined">if set to <c>true</c> [always defined].</param> public void CreateAndEnqueueOperations(ITargetContainerContext targetContainerContext, MemoryIndexTreeNode treeNode, List <ContainerContext> sourceContainers, bool alwaysDefined) { // Creates and enques merge operations for all child nodes of given node foreach (var childNode in treeNode.ChildNodes) { string childName = childNode.Key; MemoryIndexTreeNode childTreeNode = childNode.Value; MergeOperation operation = new MergeOperation(); bool isChildDefined = collectIndexes(childName, sourceContainers, operation); if (isChildDefined) { // Child is defined at least in one collection - enqueue merge operation enqueueMergeOperation(childName, operation, targetContainerContext, childTreeNode, alwaysDefined); } else { // Child is not defined - enqueue delete operation enqueueDeleteOperation(childName, operation, targetContainerContext, childTreeNode); } } // Enqueue merge operation for unknown index if is defined if (treeNode.AnyChild != null) { enqueueMergeUnknownOperation(targetContainerContext, treeNode.AnyChild, sourceContainers); } }
protected override MemoryIndex createNewTargetIndex(ITargetContainerContext targetContainerContext, string childName) { MemoryIndex targetIndex = targetContainerContext.createMemoryIndex(childName); targetContainerContext.getWriteableSourceContainer().AddIndex(childName, targetIndex); return(targetIndex); }
/// <summary> /// Enqueues the merge unknown operation. /// </summary> /// <param name="targetContainerContext">The target container context.</param> /// <param name="anyNode">Any node.</param> /// <param name="sourceContainers">The source containers.</param> private void enqueueMergeUnknownOperation(ITargetContainerContext targetContainerContext, MemoryIndexTreeNode anyNode, List <ContainerContext> sourceContainers) { MergeOperation unknownOperation = new MergeOperation(); foreach (ContainerContext containerContext in sourceContainers) { unknownOperation.Add(new MergeOperationContext( containerContext.IndexContainer.UnknownIndex, containerContext.SnapshotContext)); } IReadonlyIndexContainer targetContainer = targetContainerContext.getSourceContainer(); unknownOperation.TreeNode = anyNode; unknownOperation.SetTargetIndex(targetContainer.UnknownIndex); unknownOperation.SetUndefined(); operationQueue.AddLast(unknownOperation); }
protected override void deleteChild(ITargetContainerContext targetContainerContext, string childName) { throw new Exception("Error merging structure in readonly mode - deleting index: " + childName); }
protected override MemoryIndex createNewTargetIndex(ITargetContainerContext targetContainerContext, string childName) { //throw new Exception("Error merging structure in readonly mode - adding new index into collection: " + childName); return(null); }
protected override void deleteChild(ITargetContainerContext targetContainerContext, string childName) { targetContainerContext.getWriteableSourceContainer().RemoveIndex(childName); }
/// <summary> /// Enqueues the delete operation. /// </summary> /// <param name="childName">Name of the child.</param> /// <param name="operation">The operation.</param> /// <param name="targetContainerContext">The target container context.</param> /// <param name="childTreeNode">The child tree node.</param> private void enqueueDeleteOperation(string childName, MergeOperation operation, ITargetContainerContext targetContainerContext, MemoryIndexTreeNode childTreeNode) { IReadonlyIndexContainer targetContainer = targetContainerContext.getSourceContainer(); MemoryIndex targetIndex; if (targetContainer.TryGetIndex(childName, out targetIndex)) { // Enque delete operation only if target index exists in paret snapshot operation.TreeNode = childTreeNode; operation.SetTargetIndex(targetIndex); operation.SetDeleteOperation(); operationQueue.AddLast(operation); // Delete child from parent container targetContainerContext.getWriteableSourceContainer().RemoveIndex(childName); } }
/// <summary> /// Enqueues the merge operation. /// </summary> /// <param name="childName">Name of the child.</param> /// <param name="operation">The operation.</param> /// <param name="targetContainerContext">The target container context.</param> /// <param name="childTreeNode">The child tree node.</param> /// <param name="alwaysDefined">if set to <c>true</c> [always defined].</param> private void enqueueMergeOperation(string childName, MergeOperation operation, ITargetContainerContext targetContainerContext, MemoryIndexTreeNode childTreeNode, bool alwaysDefined) { IReadonlyIndexContainer targetContainer = targetContainerContext.getSourceContainer(); MemoryIndex targetIndex; // Use index from target collection or crete and add it to the target collection if (!targetContainer.TryGetIndex(childName, out targetIndex)) { targetIndex = createNewTargetIndex(targetContainerContext, childName); if (targetIndex == null) { return; } } // Set parameters and add it to collection operation.TreeNode = childTreeNode; operation.SetTargetIndex(targetIndex); if (!alwaysDefined) { operation.SetUndefined(); } operationQueue.AddLast(operation); }
/// <summary> /// Creates the and enqueue operations. /// </summary> /// <param name="targetContainerContext">The target container context.</param> /// <param name="treeNode">The tree node.</param> /// <param name="sourceContainers">The source containers.</param> /// <param name="alwaysDefined">if set to <c>true</c> [always defined].</param> private void createAndEnqueueOperations( ITargetContainerContext targetContainerContext, MemoryIndexTreeNode treeNode, List <ContainerContext> sourceContainers, bool alwaysDefined) { IReadonlyIndexContainer targetContainer = targetContainerContext.getSourceContainer(); // Creates and enques merge operations for all child nodes of given node foreach (var childNode in treeNode.ChildNodes) { string childName = childNode.Key; MemoryIndexTreeNode childTreeNode = childNode.Value; MergeOperation operation = new MergeOperation(); bool isChildDefined = collectIndexes(childName, sourceContainers, operation); if (isChildDefined) { // Child is defined at least in one collection - enqueue merge operation MemoryIndex targetIndex; // Use index from target collection or crete and add it to the target collection if (!targetContainer.TryGetIndex(childName, out targetIndex)) { targetIndex = createNewTargetIndex(targetContainerContext, childName); if (targetIndex == null) { continue; } } // Set parameters and add it to collection operation.TreeNode = childTreeNode; operation.SetTargetIndex(targetIndex); if (!alwaysDefined) { operation.SetUndefined(); } operationQueue.AddLast(operation); } else { // Child is not defined - enqueue delete operation MemoryIndex targetIndex; if (targetContainer.TryGetIndex(childName, out targetIndex)) { // Enque delete operation only if target index exists in paret snapshot operation.TreeNode = childTreeNode; operation.SetTargetIndex(targetIndex); operation.SetDeleteOperation(); operationQueue.AddLast(operation); deleteChild(targetContainerContext, childName); } } } // Enqueue merge operation for unknown index if is defined if (treeNode.AnyChild != null) { MergeOperation unknownOperation = new MergeOperation(); foreach (ContainerContext containerContext in sourceContainers) { unknownOperation.Add(new MergeOperationContext( containerContext.IndexContainer.UnknownIndex, containerContext.SnapshotContext)); } unknownOperation.TreeNode = treeNode.AnyChild; unknownOperation.SetTargetIndex(targetContainer.UnknownIndex); unknownOperation.SetUndefined(); operationQueue.AddLast(unknownOperation); } }
/// <summary> /// Deletes the child. /// </summary> /// <param name="targetContainerContext">The target container context.</param> /// <param name="childName">Name of the child.</param> protected abstract void deleteChild(ITargetContainerContext targetContainerContext, string childName);
/// <summary> /// Creates the new index of the target. /// </summary> /// <param name="targetContainerContext">The target container context.</param> /// <param name="childName">Name of the child.</param> /// <returns></returns> protected abstract MemoryIndex createNewTargetIndex(ITargetContainerContext targetContainerContext, string childName);