Esempio n. 1
0
        /// <summary>
        /// Direct commit of data is appended on the existing nodes
        /// </summary>
        /// <param name="changeSet">Changes</param>
        private void CommitDirect(AppendableChangeSet <Guid, object, EdgeData> changeSet)
        {
            // Add all nodes to the provider
            foreach (Guid nodeId in changeSet.Nodes.EnumerateNodes())
            {
                var node = changeSet.Nodes.GetNode(nodeId, NodeAccess.Read);
                nodes.SetNode(nodeId, node);
            }

            // Store the change set in the change set provider
            changeSetProvider.SetChangeSet(changeSet);

            // Calculate collected nodes in the source changeset
            collectedNodesProvider.StoreChangeset(changeSet, mutableParentProvider, immutableParentProvider);

            // Update parent information in the parent map provider
            mutableParentProvider.UpdateParents(changeSet, collectedNodesProvider);

            // Update parent information in the immutable parent map provider
            immutableParentProvider.UpdateParents(changeSet, collectedNodesProvider);

            // Add new snapshot making it visible
            snapshotsService.AddSnapshot(changeSet.DestinationSnapshotId);

#if DEBUG
            Debug.WriteLine("Created snapshot " + changeSet.DestinationSnapshotId);

            Utils.LogNodesRecursive(changeSet.DestinationSnapshotId, nodes, changeSet.Nodes, 0, new Hashtable(), typesService);

            Debug.WriteLine("---------------------------------------------");

            Debug.WriteLine("Collected nodes are:");

            var enumerator = collectedNodesProvider.GetEdges(changeSet.SourceSnapshotId);

            if (enumerator != null)
            {
                using (enumerator)
                {
                    while (enumerator.MoveNext())
                    {
                        Debug.WriteLine(enumerator.Current.ToNodeId);
                    }
                }
            }

            Debug.WriteLine("---------------------------------------------");
#endif
        }
Esempio n. 2
0
        /// <summary>
        /// Performs cleanup of historic data which is not used
        /// </summary>
        public void Cleanup()
        {
            lock (cleanupSync)
            {
                // Clean expired workspaces
                trackingWorkspaceStateProvider.Cleanup();

                // Determine which snapshots are used
                var usedSnapshots = trackingWorkspaceStateProvider.UsedSnapshotIds();

                // Ensure that last is always used
                var lastSnapshot = snapshotsService.GetLatestSnapshotId();
                if (!usedSnapshots.Contains(lastSnapshot))
                {
                    usedSnapshots.Add(lastSnapshot);
                }

                // Determine which snapshots are not used, remove them from shapshots list
                var unusedSnapshots = snapshotsService.RemoveUnusedSnapshots(usedSnapshots);

                // Process removed snapshots
                foreach (var snapshotId in unusedSnapshots)
                {
                    // Garbage collect nodes which are not used
                    var collectedNodesEnumerator = collectedNodesProvider.GetEdges(snapshotId);

                    if (collectedNodesEnumerator != null)
                    {
                        using (collectedNodesEnumerator)
                        {
                            while (collectedNodesEnumerator.MoveNext())
                            {
                                provider.Remove(collectedNodesEnumerator.Current.ToNodeId);
                            }
                        }
                    }

                    // Remove change set history information
                    changeSetProvider.RemoveChangeSet(snapshotId);

                    // Remove information about collected nodes in the snapshot
                    collectedNodesProvider.Cleanup(snapshotId);

                    // Remove the snapshot node
                    provider.Remove(snapshotId);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Updates parent information based on change set
        /// </summary>
        /// <param name="changeSet">Data change description</param>
        public void UpdateParents(AppendableChangeSet <Guid, object, EdgeData> changeSet, ICollectedNodesProvider <Guid, object, EdgeData> collectedNodesProvider)
        {
            lock (dataSync)
            {
                if (changeSet.SourceSnapshotId != lastSnapshotId)
                {
                    // If the last snapshot is not in the memory, clear and return
                    nodes.Clear();
                    createdNodes = false;
                    return;
                }

                using (var enumerator = collectedNodesProvider.GetEdges(changeSet.SourceSnapshotId))
                {
                    if (enumerator != null)
                    {
                        while (enumerator.MoveNext())
                        {
                            if (nodes.Contains(enumerator.Current.ToNodeId))
                            {
                                DeleteTree(enumerator.Current.ToNodeId);
                            }

                            // Get the old node
                            var node = dataNodeProvider.GetNode(enumerator.Current.ToNodeId, NodeAccess.Read);
                            // For every edge in old node
                            foreach (var edge in node.Edges.Values)
                            {
                                if (EdgeFilter(edge))
                                {
                                    // Find holder in destination snapshot for referenced node
                                    if (nodes.Contains(edge.ToNodeId))
                                    {
                                        BPlusTreeOperations.RemoveEdge(nodes, edge.ToNodeId, new EdgeData(EdgeType.Contains, enumerator.Current.ToNodeId), ParentsTreeOrder);
                                    }
                                }
                            }
                        }
                    }
                }


                // Add new node ids to map
                foreach (Guid nodeId in changeSet.Nodes.EnumerateNodes())
                {
                    var holderNode = BPlusTreeOperations.CreateRootNode(NodeType.Collection, nodeId);
                    nodes.SetNode(nodeId, holderNode);
                }

                // Add reused nodes if needed
                foreach (Guid nodeId in changeSet.ReusedNodes.Keys)
                {
                    if (!nodes.Contains(nodeId))
                    {
                        var holderNode = BPlusTreeOperations.CreateRootNode(NodeType.Collection, nodeId);
                        nodes.SetNode(nodeId, holderNode);
                    }
                }

                // Add new node edges to map
                foreach (Guid nodeId in changeSet.Nodes.EnumerateNodes())
                {
                    var node = changeSet.Nodes.GetNode(nodeId, NodeAccess.Read);

                    // Add this id into all referenced nodes
                    foreach (var edge in node.Edges.Values)
                    {
                        if (EdgeFilter(edge))
                        {
                            var edgeData = new EdgeData(EdgeType.Contains, nodeId);
                            Edge <Guid, EdgeData> existingEdge = null;
                            if (!BPlusTreeOperations.TryFindEdge(nodes, edge.ToNodeId, edgeData, out existingEdge))
                            {
                                BPlusTreeOperations.InsertEdge(nodes, edge.ToNodeId, new Edge <Guid, EdgeData>(nodeId, edgeData), ParentsTreeOrder);
                            }
                        }
                    }
                }

                // Set last snapshot as the destination ID
                lastSnapshotId = changeSet.DestinationSnapshotId;
            }
        }