Exemplo n.º 1
0
        /// <summary>
        /// Creates new delta tree describing the new snapshot
        /// </summary>
        /// <param name="baseSnapshotId">Base snapshot of the change set</param>
        /// <param name="newSnapshotId">New snapshot of the change set</param>
        /// <returns>Delta tree nodes</returns>
        private INodeProvider<Guid, object, EdgeData> CreateAppendableChangeSetTree(Guid baseSnapshotId, Guid newSnapshotId, IKeyValueStorage<Guid, object> storage, Dictionary<Guid, Guid> nodeMapping, Dictionary<Guid, NodeState> nodeStates, IsolatedChangeSet<Guid, object, EdgeData> changeSet, Hashtable reusedNodes)
        {
            DirectNodeProviderUnsafe<Guid, object, EdgeData> delta = new DirectNodeProviderUnsafe<Guid, object, EdgeData>(storage, storage is IForceUpdateStorage);

            // Create snapshot in delta
            nodeMapping.Add(baseSnapshotId, newSnapshotId);
            var snapshotNode = new Node<Guid, object, EdgeData>(NodeType.Snapshot, null);
            snapshotNode.Previous = baseSnapshotId;
            // Link to root object
            snapshotNode.AddEdge(new Edge<Guid, EdgeData>(snapshotsService.GetRootObjectId(baseSnapshotId), new EdgeData(EdgeType.RootObject, null)));
            // Set node to provider
            delta.SetNode(newSnapshotId, snapshotNode);

            // Add all changes and parent nodes
            foreach (Guid nodeId in changeSet.Nodes.EnumerateNodes())
            {
                AddNodeToAppendableTreeRecursive(delta, nodeId, nodeMapping, nodeStates, changeSet);
            }

            // Prepare list of unreferenced node IDs
            Dictionary<Guid, Collection<Guid>> references = new Dictionary<Guid, Collection<Guid>>();

            // Resolve edges based on mapping
            foreach (Guid nodeId in delta.EnumerateNodes())
            {
                references.Add(nodeId, new Collection<Guid>());
            }

            // Resolve edges based on mapping
            foreach (Guid nodeId in delta.EnumerateNodes())
            {
                var node = delta.GetNode(nodeId, NodeAccess.ReadWrite);

                foreach (var edge in node.Edges.Values)
                {
                    // Permanent edges should not be touched
                    if (!Utils.IsPermanentEdge(edge))
                    {
                        // Reroute based on node mapping
                        if (nodeMapping.ContainsKey(edge.ToNodeId))
                        {
                            edge.ToNodeId = nodeMapping[edge.ToNodeId];
                        }
                        else
                        {
                            if (!reusedNodes.ContainsKey(edge.ToNodeId))
                            {
                                reusedNodes.Add(edge.ToNodeId, null);
                            }
                        }

                        // Change edge data if it points to changed node
                        if (edge.Data.Data != null && edge.Data.Data is Guid)
                        {
                            if (nodeMapping.ContainsKey((Guid)edge.Data.Data))
                            {
                                edge.Data = new EdgeData(edge.Data.Semantic, nodeMapping[(Guid)edge.Data.Data]);
                            }
                        }
                    }
                    else
                    {
                        if (!reusedNodes.ContainsKey(edge.ToNodeId))
                        {
                            reusedNodes.Add(edge.ToNodeId, null);
                        }
                    }

                    if (references.ContainsKey(edge.ToNodeId))
                    {
                        references[edge.ToNodeId].Add(nodeId);
                    }
                }
            }

            // Remove remaining unreferenced nodes
            bool removed = false;

            do
            {
                removed = false;

                foreach (Guid key in delta.EnumerateNodes())
                {
                    // There are no references to the key
                    if ((key!=newSnapshotId) && (references[key].Count == 0))
                    {
            #if DEBUG
                        Debug.WriteLine("Removed unreferenced key " + key);
            #endif
                        delta.Remove(key);

                        reusedNodes.Remove(key);

                        nodeStates.Remove(key);

                        foreach (Guid otherKey in references.Keys)
                        {
                            references[otherKey].Remove(key);
                        }

                        foreach (var mappingKey in nodeMapping.Keys)
                        {
                            if (nodeMapping[mappingKey] == key)
                            {
                                nodeMapping.Remove(mappingKey);
                                break;
                            }
                        }

                        removed = true;
                        break;
                    }
                }
            }
            while (removed);

            // Isolated provider nodes have been corrupted, perform clear
            changeSet.Nodes.Clear();
            changeSet.NodeStates.Clear();

            return delta;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates new delta tree describing the new snapshot
        /// </summary>
        /// <param name="baseSnapshotId">Base snapshot of the change set</param>
        /// <param name="newSnapshotId">New snapshot of the change set</param>
        /// <returns>Delta tree nodes</returns>
        private INodeProvider <Guid, object, EdgeData> CreateAppendableChangeSetTree(Guid baseSnapshotId, Guid newSnapshotId, IKeyValueStorage <Guid, object> storage, Dictionary <Guid, Guid> nodeMapping, Dictionary <Guid, NodeState> nodeStates, IsolatedChangeSet <Guid, object, EdgeData> changeSet, Hashtable reusedNodes)
        {
            DirectNodeProviderUnsafe <Guid, object, EdgeData> delta = new DirectNodeProviderUnsafe <Guid, object, EdgeData>(storage, storage is IForceUpdateStorage);

            // Create snapshot in delta
            nodeMapping.Add(baseSnapshotId, newSnapshotId);
            var snapshotNode = new Node <Guid, object, EdgeData>(NodeType.Snapshot, null);

            snapshotNode.Previous = baseSnapshotId;
            // Link to root object
            snapshotNode.AddEdge(new Edge <Guid, EdgeData>(snapshotsService.GetRootObjectId(baseSnapshotId), new EdgeData(EdgeType.RootObject, null)));
            // Set node to provider
            delta.SetNode(newSnapshotId, snapshotNode);

            // Add all changes and parent nodes
            foreach (Guid nodeId in changeSet.Nodes.EnumerateNodes())
            {
                AddNodeToAppendableTreeRecursive(delta, nodeId, nodeMapping, nodeStates, changeSet);
            }

            // Prepare list of unreferenced node IDs
            Dictionary <Guid, Collection <Guid> > references = new Dictionary <Guid, Collection <Guid> >();

            // Resolve edges based on mapping
            foreach (Guid nodeId in delta.EnumerateNodes())
            {
                references.Add(nodeId, new Collection <Guid>());
            }

            // Resolve edges based on mapping
            foreach (Guid nodeId in delta.EnumerateNodes())
            {
                var node = delta.GetNode(nodeId, NodeAccess.ReadWrite);

                foreach (var edge in node.Edges.Values)
                {
                    // Permanent edges should not be touched
                    if (!Utils.IsPermanentEdge(edge))
                    {
                        // Reroute based on node mapping
                        if (nodeMapping.ContainsKey(edge.ToNodeId))
                        {
                            edge.ToNodeId = nodeMapping[edge.ToNodeId];
                        }
                        else
                        {
                            if (!reusedNodes.ContainsKey(edge.ToNodeId))
                            {
                                reusedNodes.Add(edge.ToNodeId, null);
                            }
                        }

                        // Change edge data if it points to changed node
                        if (edge.Data.Data != null && edge.Data.Data is Guid)
                        {
                            if (nodeMapping.ContainsKey((Guid)edge.Data.Data))
                            {
                                edge.Data = new EdgeData(edge.Data.Semantic, nodeMapping[(Guid)edge.Data.Data]);
                            }
                        }
                    }
                    else
                    {
                        if (!reusedNodes.ContainsKey(edge.ToNodeId))
                        {
                            reusedNodes.Add(edge.ToNodeId, null);
                        }
                    }

                    if (references.ContainsKey(edge.ToNodeId))
                    {
                        references[edge.ToNodeId].Add(nodeId);
                    }
                }
            }

            // Remove remaining unreferenced nodes
            bool removed = false;

            do
            {
                removed = false;

                foreach (Guid key in delta.EnumerateNodes())
                {
                    // There are no references to the key
                    if ((key != newSnapshotId) && (references[key].Count == 0))
                    {
#if DEBUG
                        Debug.WriteLine("Removed unreferenced key " + key);
#endif
                        delta.Remove(key);

                        reusedNodes.Remove(key);

                        nodeStates.Remove(key);

                        foreach (Guid otherKey in references.Keys)
                        {
                            references[otherKey].Remove(key);
                        }

                        foreach (var mappingKey in nodeMapping.Keys)
                        {
                            if (nodeMapping[mappingKey] == key)
                            {
                                nodeMapping.Remove(mappingKey);
                                break;
                            }
                        }

                        removed = true;
                        break;
                    }
                }
            }while (removed);

            // Isolated provider nodes have been corrupted, perform clear
            changeSet.Nodes.Clear();
            changeSet.NodeStates.Clear();

            return(delta);
        }