Ejemplo n.º 1
0
        public string ObjectsReport()
        {
            Hashtable usedNodes = new Hashtable();

            // Collect used nodes
            AddUsedNodesRecursive(LastSnapshotId(), usedNodes);

            StringBuilder sb = new StringBuilder();

            foreach (Guid nodeId in usedNodes.Keys)
            {
                // We found a node which is not used and should be collected
                var node = provider.GetNode(nodeId, NodeAccess.Read);

                string line = nodeId.ToString() + "\t" + node.NodeType.ToString() + "\t";

                var typeData = new EdgeData(EdgeType.OfType, null);

                if (node.Edges.ContainsKey(typeData))
                {
                    var typeEdge = node.FindEdge(typeData);

                    if (typeEdge != null)
                    {
                        line += typesService.GetTypeFromIdCached(typeEdge.ToNodeId).Name + "\t";
                    }
                }

                sb.AppendLine(line);
            }

            return(sb.ToString());
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets next leaf in tree compared to given sample data
        /// </summary>
        /// <param name="nodes">Node provider</param>
        /// <param name="rootNodeId">Root node id</param>
        /// <param name="sampleData">Sample data in the current leaf</param>
        /// <returns>Leaf node next in comparison to sample data, or null if no more leaves are found</returns>
        private static Node <Guid, object, EdgeData> NextLeaf(INodeProvider <Guid, object, EdgeData> nodes, Guid rootNodeId, EdgeData sampleData)
        {
            var  node = nodes.GetNode(rootNodeId, NodeAccess.Read);
            Guid id   = rootNodeId;

            Guid nextInternalParentId = Guid.Empty;

            while (node.Data.Equals(InternalNodeData))
            {
                var leadingEdgeIndex = FindLeadingEdgeIndex(sampleData, node);

                if (leadingEdgeIndex < node.Edges.Count - 1)
                {
                    nextInternalParentId = node.Edges[node.Edges.Keys[leadingEdgeIndex + 1]].ToNodeId;
                }

                // Advance to next internal node
                node = nodes.GetNode(node.Edges[node.Edges.Keys[leadingEdgeIndex]].ToNodeId, NodeAccess.Read);
            }

            if (nextInternalParentId.Equals(Guid.Empty))
            {
                return(null);
            }
            else
            {
                return(LeftLeaf(nodes, nodes.GetNode(nextInternalParentId, NodeAccess.Read)));
            }
        }
Ejemplo n.º 3
0
 void CachedWriteNodeProvider_OnBeforeKeysEvicted(object sender, KeysEvictedEventArgs <TIdentifier> e)
 {
     // Move data to parent provider
     foreach (var key in e.Keys)
     {
         var node = cacheProvider.GetNode(key, NodeAccess.Read);
         parentProvider.SetNode(key, node);
         cacheProvider.Remove(key);
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Returns the Id of the type that represents the root of the database (the representation of the Data Model)
        /// </summary>
        /// <returns></returns>
        public Guid GetRootTypeId()
        {
            var snapshotRootNode = provider.GetNode(Constants.SnapshotsNodeId, NodeAccess.Read);
            var snapshotNode     = provider.GetNode(snapshotRootNode.Edges.Values[0].ToNodeId, NodeAccess.Read);
            var objectNode       = provider.GetNode(snapshotNode.Edges.Values[0].ToNodeId, NodeAccess.Read);

            foreach (var edge in objectNode.Edges.Values)
            {
                if (edge.Data.Semantic.Equals(EdgeType.OfType))
                {
                    return(edge.ToNodeId);
                }
            }

            return(Guid.Empty);
        }
Ejemplo n.º 5
0
        internal bool ContainsScalar(Guid instanceId, object value)
        {
            using (var enumerator = GetEnumerator(instanceId))
            {
                while (enumerator.MoveNext())
                {
                    var node = provider.GetNode(enumerator.Current.ToNodeId, NodeAccess.Read);
                    if (node.Data.Equals(value))
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets node from collection by an identifier. First attempt to read from cache.
        /// </summary>
        /// <param name="nodeId">Node identifier</param>
        /// <returns>Node object</returns>
        public Node <TIdentifier, TNodeData, TEdgeData> GetNode(TIdentifier identifier, NodeAccess access)
        {
            rwLock.AcquireReaderLock(-1);
            try
            {
                // Read from cache
                var node = cacheProvider.GetNode(identifier, access);

                if (node != null)
                {
                    return(node);
                }
                else
                {
                    // Read from parent
                    node = parentProvider.GetNode(identifier, access);
                    cacheProvider.SetNode(identifier, node);
                    return(node);
                }
            }
            finally
            {
                rwLock.ReleaseLock();
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Looks for leaf tree node which is supposed to have an edge with given hash
        /// </summary>
        /// <param name="nodes">Node provider</param>
        /// <param name="rootNodeId">Root node ID to start the search from</param>
        /// <param name="edgeHash">Hash to find</param>
        /// <returns>Leaf node which is supposed to contain the edge</returns>
        private static FindResult FindLeafNode(INodeProvider <Guid, object, EdgeData> nodes, Guid rootNodeId, EdgeData data)
        {
            var  node = nodes.GetNode(rootNodeId, NodeAccess.Read);
            Guid id   = rootNodeId;

            while (node.Data.Equals(InternalNodeData))
            {
                var leadingEdge = FindLeadingEdge(data, node);

                // Advance to next internal node
                node = nodes.GetNode(leadingEdge.ToNodeId, NodeAccess.Read);
                id   = leadingEdge.ToNodeId;
            }

            return(new FindResult(id, node));
        }
Ejemplo n.º 8
0
        private void GetCollectedNodesRecursive(Guid nodeId, AppendableChangeSet <Guid, object, EdgeData> changeSet, IParentMapProvider <Guid, object, EdgeData> mutableParentMap, IParentMapProvider <Guid, object, EdgeData> immutableParentMap, Hashtable collectedNodes, Hashtable visitedNodes)
        {
            if (visitedNodes.ContainsKey(nodeId))
            {
                return;
            }

            visitedNodes.Add(nodeId, null);

            if (changeSet.ReusedNodes.ContainsKey(nodeId))
            {
                // Reused nodes and their children are not to be collected
                return;
            }

            if (HasReusedParent(nodeId, changeSet, mutableParentMap, immutableParentMap, collectedNodes, new Hashtable()))
            {
                return;
            }

            collectedNodes.Add(nodeId, null);

            var node = dataNodes.GetNode(nodeId, NodeAccess.Read);

            foreach (var edge in node.Edges.Values)
            {
                if (edge.Data.Semantic != EdgeType.OfType && edge.ToNodeId != Constants.NullReferenceNodeId)
                {
                    GetCollectedNodesRecursive(edge.ToNodeId, changeSet, mutableParentMap, immutableParentMap, collectedNodes, visitedNodes);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Runs a recursive pass and prints tree nodes
        /// </summary>
        /// <param name="nodes">Node provider which contains tree nodes</param>
        /// <param name="nodeId">Node to print</param>
        /// <param name="sb">String builder which contains the string</param>
        /// <param name="level">Current indentation level</param>
        private static void PrintTreeRecursive(INodeProvider <Guid, object, EdgeData> nodes, Guid nodeId, StringBuilder sb, int level)
        {
            var node = nodes.GetNode(nodeId, NodeAccess.Read);

            AppendTabs(sb, level);

            if (node.Data.Equals(InternalNodeData))
            {
                sb.AppendFormat("Internal\n");
                foreach (var edge in node.Edges.Values)
                {
                    AppendTabs(sb, level);
                    sb.AppendFormat("MAX[{0}]\n", edge.Data.Equals(EdgeData.MaxValue) ? "*" : edge.Data.Data.ToString());
                    PrintTreeRecursive(nodes, edge.ToNodeId, sb, level + 1);
                }
            }
            else
            {
                sb.AppendFormat("Leaf\n");
                foreach (var edge in node.Edges.Values)
                {
                    AppendTabs(sb, level);
                    sb.AppendFormat("TO[{0}]\n", edge.ToNodeId.ToString());
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates clone of existing tree under different ID
        /// </summary>
        /// <param name="nodes">Node provider which stores the nodes</param>
        /// <param name="sourceId">ID of source tree root</param>
        /// <param name="destinationId">ID of destination tree root</param>
        public static void Clone(INodeProvider <Guid, object, EdgeData> nodes, Guid sourceId, Guid destinationId)
        {
            var node = nodes.GetNode(sourceId, NodeAccess.Read);

            if (node.Data.Equals(InternalNodeData))
            {
                Node <Guid, object, EdgeData> newNode = new Node <Guid, object, EdgeData>(node.NodeType, node.Data);
                foreach (var edge in node.Edges.Values)
                {
                    Guid subId = Guid.NewGuid();
                    Clone(nodes, edge.ToNodeId, subId);
                    newNode.AddEdge(new Edge <Guid, EdgeData>(subId, edge.Data));
                }

                nodes.SetNode(destinationId, newNode);
            }
            else
            if (node.Data.Equals(LeafNodeData))
            {
                Node <Guid, object, EdgeData> newNode = new Node <Guid, object, EdgeData>(node.NodeType, node.Data, node.Edges);
                nodes.SetNode(destinationId, newNode);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Returns number of edges in the tree
        /// </summary>
        /// <param name="nodes">Node provider which hosts the nodes</param>
        /// <param name="rootNodeId">Tree root node ID</param>
        /// <param name="data">Edge to find</param>
        /// <returns></returns>
        public static int Count(INodeProvider <Guid, object, EdgeData> nodes, Guid rootNodeId, EdgeType data)
        {
            var node = nodes.GetNode(rootNodeId, NodeAccess.Read);

            if (node.Data.Equals(LeafNodeData))
            {
                int sum = 0;
                foreach (var edge in node.Edges.Values)
                {
                    if (edge.Data.Semantic.Equals(data))
                    {
                        sum++;
                    }
                }
                return(sum);
            }
            else
            {
                int sum = 0;
                foreach (var edge in node.Edges.Values)
                {
                    sum += Count(nodes, edge.ToNodeId, data);
                }
                return(sum);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Adds new edge to the tree.
        /// </summary>
        /// <param name="nodes">Node provider which hosts the nodes</param>
        /// <param name="rootNodeId">Tree root node ID</param>
        /// <param name="edge">Edge to add</param>
        public static void InsertEdge(INodeProvider <Guid, object, EdgeData> nodes, Guid rootNodeId, Edge <Guid, EdgeData> edge, int treeOrder)
        {
            if (treeOrder < 6)
            {
                throw new ArgumentException();
            }

            var result = FindLeafNode(nodes, rootNodeId, edge.Data);

            if (result.Node.Edges.Count == treeOrder)
            {
                SplitTree(nodes, rootNodeId, true, edge.Data, treeOrder);
                result = FindLeafNode(nodes, rootNodeId, edge.Data);
            }

            if (!result.Node.Data.Equals(LeafNodeData))
            {
                throw new InvalidOperationException("Leaf node expected");
            }

            var node = nodes.GetNode(result.NodeId, NodeAccess.ReadWrite);

            node.AddEdge(edge);
            nodes.SetNode(result.NodeId, node);
        }
Ejemplo n.º 13
0
            /// <summary>
            /// Creates new instance of BPlusTreeEnumerator type
            /// </summary>
            /// <param name="nodes">Node provider which contains tree nodes</param>
            /// <param name="rootNodeId">Root item ID</param>
            /// <param name="edgeType">Edge type to use as a filter for enumeration</param>
            public BPlusTreeEnumerator(INodeProvider <Guid, object, EdgeData> nodes, Guid rootNodeId, EdgeType edgeType)
            {
                this.nodes      = nodes;
                this.rootNodeId = rootNodeId;
                this.edgeType   = edgeType;
                var currentLeaf = BPlusTreeOperations.LeftLeaf(nodes, nodes.GetNode(rootNodeId, NodeAccess.Read));

                this.currentLeafEnumerator = currentLeaf.Edges.Values.GetEnumerator();
            }
Ejemplo n.º 14
0
 /// <summary>
 /// Gets leftmost edge in the given subtree
 /// </summary>
 /// <param name="nodes"></param>
 /// <param name="node"></param>
 /// <returns></returns>
 private static Edge <Guid, EdgeData> LeftEdge(INodeProvider <Guid, object, EdgeData> nodes, Node <Guid, object, EdgeData> node)
 {
     if (node.Data.Equals(LeafNodeData))
     {
         return(node.Edges[node.Edges.Keys[0]]);
     }
     else
     {
         return(LeftEdge(nodes, nodes.GetNode(node.Edges[node.Edges.Keys[0]].ToNodeId, NodeAccess.Read)));
     }
 }
Ejemplo n.º 15
0
            /// <summary>
            /// Resets the enumerator
            /// </summary>
            public void Reset()
            {
                if (currentLeafEnumerator != null)
                {
                    currentLeafEnumerator.Dispose();
                }

                var currentLeaf = BPlusTreeOperations.LeftLeaf(nodes, nodes.GetNode(rootNodeId, NodeAccess.Read));

                this.currentLeafEnumerator = currentLeaf.Edges.Values.GetEnumerator();
            }
Ejemplo n.º 16
0
        /// <summary>
        /// Gets node from collection by an identifier
        /// </summary>
        /// <param name="nodeId">Node identifier</param>
        /// <returns>Node object</returns>
        public Node <Guid, object, EdgeData> GetNode(Guid nodeId, NodeAccess access)
        {
            CheckThread();

            if (access == NodeAccess.ReadWrite)
            {
                EnsureNode(nodeId);
                return(isolatedProvider.GetNode(nodeId, access));
            }
            else
            {
                if (isolatedProvider.Contains(nodeId))
                {
                    return(isolatedProvider.GetNode(nodeId, access));
                }
                else
                {
                    return(parentProvider.GetNode(nodeId, access));
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Gets node from collection by an identifier. First attempt to read from cache.
        /// </summary>
        /// <param name="nodeId">Node identifier</param>
        /// <returns>Node object</returns>
        public Node <TIdentifier, TNodeData, TEdgeData> GetNode(TIdentifier identifier, NodeAccess access)
        {
            if (cacheProvider.Contains(identifier))
            {
                return(cacheProvider.GetNode(identifier, access));
            }

            // Read from parent -> move to cache
            Node <TIdentifier, TNodeData, TEdgeData> node = parentProvider.GetNode(identifier, access);

            parentProvider.Remove(identifier);
            cacheProvider.SetNode(identifier, node);
            return(node);
        }
Ejemplo n.º 18
0
        private void DeleteTree(Guid nodeId)
        {
            var node = nodes.GetNode(nodeId, NodeAccess.Read);

            if (node.Data.Equals(BPlusTreeOperations.InternalNodeData))
            {
                foreach (var edge in node.Edges)
                {
                    DeleteTree(edge.Value.ToNodeId);
                }
            }

            nodes.Remove(nodeId);
        }
Ejemplo n.º 19
0
        private static RemovalResult RemoveEdgeRecursive(INodeProvider <Guid, object, EdgeData> nodes, Guid nodeId, EdgeData data, int treeOrder)
        {
            var node = nodes.GetNode(nodeId, NodeAccess.ReadWrite);

            try
            {
                if (node.Data.Equals(LeafNodeData))
                {
                    var removeResult = node.Edges.Remove(data);
                    return(new RemovalResult(node.Edges.Count, removeResult, false));
                }
                else
                {
                    var edgeIndex = FindLeadingEdgeIndex(data, node);
                    var edge      = node.Edges[node.Edges.Keys[edgeIndex]];

                    var res = RemoveEdgeRecursive(nodes, edge.ToNodeId, data, treeOrder);

                    if (!res.WasRemoved)
                    {
                        return(res);
                    }

                    if (res.RemainingCount < treeOrder / 2)
                    {
                        #region Reorganize sub nodes
                        // Take data from a sibling
                        if (edgeIndex < node.Edges.Count - 1)
                        {
                            return(MergeNodes(nodes, node, edgeIndex, edgeIndex + 1, treeOrder));
                        }
                        else
                        {
                            return(MergeNodes(nodes, node, edgeIndex - 1, edgeIndex, treeOrder));
                        }

                        #endregion
                    }
                    else
                    {
                        return(res);
                    }
                }
            }
            finally
            {
                nodes.SetNode(nodeId, node);
            }
        }
Ejemplo n.º 20
0
        internal bool TryGetScalar(Guid instanceId, object key, out object value)
        {
            Edge <Guid, EdgeData> edge = null;

            if (BPlusTreeOperations.TryFindEdge(provider, instanceId, new EdgeData(EdgeType.ListItem, key), out edge))
            {
                value = provider.GetNode(edge.ToNodeId, NodeAccess.Read).Data;
                return(true);
            }
            else
            {
                value = null;
                return(false);
            }
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Gets the rightmost edge in given subtree
 /// </summary>
 /// <param name="nodes"></param>
 /// <param name="node"></param>
 /// <returns></returns>
 public static Edge <Guid, EdgeData> RightEdge(INodeProvider <Guid, object, EdgeData> nodes, Node <Guid, object, EdgeData> node)
 {
     if (node.Data.Equals(LeafNodeData))
     {
         if (node.Edges.Count > 0)
         {
             return(node.Edges[node.Edges.Keys[node.Edges.Count - 1]]);
         }
         else
         {
             return(null);
         }
     }
     else
     {
         return(RightEdge(nodes, nodes.GetNode(node.Edges[node.Edges.Keys[node.Edges.Count - 1]].ToNodeId, NodeAccess.Read)));
     }
 }
Ejemplo n.º 22
0
        internal static void LogNodesRecursive(Guid nodeId, INodeProvider <Guid, object, EdgeData> nodes, INodeProvider <Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            if (visited.ContainsKey(nodeId))
            {
                Debug.WriteLine(LogTabs(tabLevel) + nodeId);
                return;
            }

            visited.Add(nodeId, null);

            if (changes.Contains(nodeId))
            {
                var node = changes.GetNode(nodeId, NodeAccess.Read);
                switch (node.NodeType)
                {
                case NodeType.Object:
                    LogObject(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                    break;

                case NodeType.Collection:
                    LogCollection(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                    break;

                case NodeType.Dictionary:
                    LogCollection(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                    break;

                default:
                    Debug.WriteLine(LogTabs(tabLevel) + node.Previous + "->" + nodeId + "[" + node.NodeType + "]");
                    foreach (var edge in node.Edges)
                    {
                        Debug.WriteLine(LogTabs(tabLevel) + edge.Key + "=");
                        LogNodesRecursive(edge.Value.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                    }
                    break;
                }
            }
            else
            {
                Debug.WriteLine(LogTabs(tabLevel) + nodeId);
            }
        }
Ejemplo n.º 23
0
        public ICollection <object> ParentNodes(object instance)
        {
            var id = Utils.GetItemId(instance);
            ICollection <object> result = new Collection <object>();
            var node = nodeProvider.GetNode(id, NodeAccess.Read);

            if (node != null)
            {
                foreach (var parentNode in node.ParentNodes)
                {
                    object proxy = null;
                    if (!immutableProxyMap.TryGetProxy(parentNode, out proxy))
                    {
                        proxy = proxyCreatorService.NewObject(runtimeProxyFacade, typesService.GetInstanceTypeId(parentNode), parentNode, true);
                        immutableProxyMap.AddProxy(parentNode, proxy);
                    }
                    result.Add(proxy);
                }
            }
            return(result);
        }
Ejemplo n.º 24
0
        private void AddNodesRecursive(Guid nodeId, INodeProvider <Guid, object, EdgeData> source, INodeProvider <Guid, object, EdgeData> destination, Hashtable visitedNodes)
        {
            if (visitedNodes.ContainsKey(nodeId))
            {
                return;
            }

            visitedNodes.Add(nodeId, null);

            var node    = source.GetNode(nodeId, NodeAccess.Read);
            var newNode = new Node <Guid, object, EdgeData>(node.NodeType, node.Data, node.Edges, node.Values);

            destination.SetNode(nodeId, newNode);

            foreach (var edge in node.Edges.Values)
            {
                if (edge.ToNodeId != Constants.NullReferenceNodeId)
                {
                    AddNodesRecursive(edge.ToNodeId, source, destination, visitedNodes);
                }
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Makes room in the tree for new data
        /// </summary>
        /// <param name="nodes">Node provider which contains tree nodes</param>
        /// <param name="nodeId">Current node ID</param>
        /// <param name="isRoot">Determines if current node is root node</param>
        /// <param name="data">Data to make room for</param>
        /// <returns>Result of the operation</returns>
        private static SplitResult SplitTree(INodeProvider <Guid, object, EdgeData> nodes, Guid nodeId, bool isRoot, EdgeData data, int treeOrder)
        {
            var currentNode = nodes.GetNode(nodeId, NodeAccess.ReadWrite);

            if (isRoot)
            {
                if (currentNode.Data.Equals(InternalNodeData))
                {
                    #region Is root internal ?

                    var leadingEdge = FindLeadingEdge(data, currentNode);
                    var result      = SplitTree(nodes, leadingEdge.ToNodeId, false, data, treeOrder);

                    if (result != null)
                    {
                        currentNode.AddEdge(new Edge <Guid, EdgeData>(result.CreatedNodeId, result.RightKey));

                        if (currentNode.Edges.Count == (treeOrder + 1))
                        {
                            // Split root to 2 internal nodes
                            Guid leftNodeId  = Guid.NewGuid();
                            Guid rightNodeId = Guid.NewGuid();
                            Node <Guid, object, EdgeData> leftNode  = new Node <Guid, object, EdgeData>(NodeType.TreeInternal, InternalNodeData);
                            Node <Guid, object, EdgeData> rightNode = new Node <Guid, object, EdgeData>(NodeType.TreeInternal, InternalNodeData);

                            var keys = currentNode.Edges.Keys;
                            for (int i = 0; i < keys.Count; i++)
                            {
                                if (i < keys.Count / 2)
                                {
                                    leftNode.AddEdge(currentNode.Edges[keys[i]]);
                                }
                                else
                                {
                                    rightNode.AddEdge(currentNode.Edges[keys[i]]);
                                }
                            }

                            //Set last edges
                            SetLastInternalKey(leftNode);
                            SetLastInternalKey(rightNode);

                            currentNode.Edges.Clear();
                            currentNode.AddEdge(new Edge <Guid, EdgeData>(leftNodeId, LeftEdge(nodes, rightNode).Data));
                            currentNode.AddEdge(new Edge <Guid, EdgeData>(rightNodeId, EdgeData.MaxValue));


                            nodes.SetNode(leftNodeId, leftNode);
                            nodes.SetNode(rightNodeId, rightNode);
                        }

                        nodes.SetNode(nodeId, currentNode);
                    }
                    else
                    {
                        return(null);
                    }
                    #endregion
                }
                else
                {
                    #region Root is a leaf
                    if (currentNode.Edges.Count == treeOrder)
                    {
                        // Split root to internal nodes
                        Guid leftNodeId  = Guid.NewGuid();
                        Guid rightNodeId = Guid.NewGuid();
                        Node <Guid, object, EdgeData> leftNode  = new Node <Guid, object, EdgeData>(NodeType.TreeLeaf, LeafNodeData);
                        Node <Guid, object, EdgeData> rightNode = new Node <Guid, object, EdgeData>(NodeType.TreeLeaf, LeafNodeData);

                        var keys = currentNode.Edges.Keys;
                        for (int i = 0; i < keys.Count; i++)
                        {
                            if (i < keys.Count / 2)
                            {
                                leftNode.AddEdge(currentNode.Edges[keys[i]]);
                            }
                            else
                            {
                                rightNode.AddEdge(currentNode.Edges[keys[i]]);
                            }
                        }

                        currentNode.Edges.Clear();
                        currentNode.AddEdge(new Edge <Guid, EdgeData>(leftNodeId, LeftEdge(nodes, rightNode).Data));
                        currentNode.AddEdge(new Edge <Guid, EdgeData>(rightNodeId, EdgeData.MaxValue));
                        currentNode.SetData(InternalNodeData);


                        nodes.SetNode(leftNodeId, leftNode);
                        nodes.SetNode(rightNodeId, rightNode);
                        nodes.SetNode(nodeId, currentNode);
                    }
                    #endregion
                }

                return(null);
            }
            else
            {
                if (currentNode.Data.Equals(InternalNodeData))
                {
                    var leadingEdge = FindLeadingEdge(data, currentNode);
                    var result      = SplitTree(nodes, leadingEdge.ToNodeId, false, data, treeOrder);

                    if (result != null)
                    {
                        currentNode.AddEdge(new Edge <Guid, EdgeData>(result.CreatedNodeId, result.RightKey));

                        if (currentNode.Edges.Count == treeOrder)
                        {
                            Guid newInternalId = Guid.NewGuid();
                            Node <Guid, object, EdgeData> newInternal = new Node <Guid, object, EdgeData>(NodeType.TreeInternal, InternalNodeData);
                            var keys = currentNode.Edges.Keys;

                            for (int i = 0; i < keys.Count / 2; i++)
                            {
                                newInternal.AddEdge(currentNode.Edges[keys[i]]);
                            }

                            int nrToRemove = keys.Count / 2;
                            for (int i = 0; i < nrToRemove; i++)
                            {
                                currentNode.Edges.RemoveAt(0);
                            }

                            // Set last edge of left internal node to MaxInt
                            SetLastInternalKey(newInternal);

                            nodes.SetNode(newInternalId, newInternal);
                            nodes.SetNode(nodeId, currentNode);

                            return(new SplitResult(newInternalId, newInternal, LeftEdge(nodes, currentNode).Data));
                        }
                        else
                        {
                            nodes.SetNode(nodeId, currentNode);
                            return(null);
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                if (currentNode.Data.Equals(LeafNodeData))
                {
                    Guid newLeafId = Guid.NewGuid();
                    Node <Guid, object, EdgeData> newLeaf = new Node <Guid, object, EdgeData>(NodeType.TreeLeaf, LeafNodeData);
                    var keys = currentNode.Edges.Keys;

                    for (int i = 0; i < keys.Count / 2; i++)
                    {
                        newLeaf.AddEdge(currentNode.Edges[keys[i]]);
                    }

                    int nrToRemove = keys.Count / 2;
                    for (int i = 0; i < nrToRemove; i++)
                    {
                        currentNode.Edges.RemoveAt(0);
                    }

                    nodes.SetNode(newLeafId, newLeaf);
                    nodes.SetNode(nodeId, currentNode);

                    return(new SplitResult(newLeafId, newLeaf, LeftEdge(nodes, currentNode).Data));
                }
                else
                {
                    throw new ArgumentException("Unexpected node data");
                }
            }
        }
Ejemplo n.º 26
0
        internal static void LogNodesRecursive(Guid nodeId, INodeProvider<Guid, object, EdgeData> nodes, INodeProvider<Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            if (visited.ContainsKey(nodeId))
            {
                Debug.WriteLine(LogTabs(tabLevel) + nodeId);
                return;
            }

            visited.Add(nodeId, null);

            if (changes.Contains(nodeId))
            {
                var node = changes.GetNode(nodeId, NodeAccess.Read);
                switch (node.NodeType)
                {
                    case NodeType.Object:
                        LogObject(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                        break;
                    case NodeType.Collection:
                        LogCollection(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                        break;
                    case NodeType.Dictionary:
                        LogCollection(nodeId, node, nodes, changes, tabLevel, visited, typesService);
                        break;
                    default:
                        Debug.WriteLine(LogTabs(tabLevel) + node.Previous + "->" + nodeId + "[" + node.NodeType + "]");
                        foreach (var edge in node.Edges)
                        {
                            Debug.WriteLine(LogTabs(tabLevel) + edge.Key + "=");
                            LogNodesRecursive(edge.Value.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                        }
                        break;
                }
            }
            else
            {
                Debug.WriteLine(LogTabs(tabLevel) + nodeId);
            }
        }
Ejemplo n.º 27
0
        private void AddNodesRecursive(Guid nodeId, INodeProvider<Guid, object, EdgeData> source, INodeProvider<Guid, object, EdgeData> destination, Hashtable visitedNodes)
        {
            if (visitedNodes.ContainsKey(nodeId))
            {
                return;
            }

            visitedNodes.Add(nodeId, null);

            var node = source.GetNode(nodeId, NodeAccess.Read);
            var newNode = new Node<Guid, object, EdgeData>(node.NodeType, node.Data, node.Edges, node.Values);
            destination.SetNode(nodeId, newNode);

            foreach (var edge in node.Edges.Values)
            {
                if (edge.ToNodeId != Constants.NullReferenceNodeId)
                {
                    AddNodesRecursive(edge.ToNodeId, source, destination, visitedNodes);
                }
            }
        }
Ejemplo n.º 28
0
        public Guid GetRootObjectId(Guid snapshotId)
        {
            var node = archiveProvider.GetNode(Constants.SnapshotsNodeId, NodeAccess.Read);

            return(node.FindEdge(new EdgeData(EdgeType.Contains, null)).ToNodeId);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Defines new type, it shall add used sub-types, such as member types
        /// </summary>
        /// <param name="t">Type to add</param>
        /// <returns>Type Id</returns>
        public Guid AddType(Type t)
        {
            ValidateType(t);

            // Try finding the type first
            Guid typeId = GetTypeId(t);

            // Type not found?
            if (typeId == Guid.Empty)
            {
                // Assign new ID
                typeId = Guid.NewGuid();
                // Create new node
                var node = new Node<Guid, object, EdgeData>(NodeType.Type, GetTypeName(t));
                // Types "group" node ---> The type
                var typesNode = provider.GetNode(Constants.TypesNodeId, NodeAccess.ReadWrite);
                typesNode.AddEdge(new Edge<Guid, EdgeData>(typeId, new EdgeData(EdgeType.Contains, typeId)));
                provider.SetNode(Constants.TypesNodeId, typesNode);
                // Add node to collection
                provider.SetNode(typeId, node);

                if (t.IsInterface)
                {
                    // Extract properties
                    var properties = new Collection<PropertyInfo>();
                    Utils.ExtractProperties(t, properties);

                    // Property member types are also added
                    foreach (PropertyInfo p in properties)
                    {
                        bool isPermanent = p.GetCustomAttributes(typeof(ImmutableAttribute), false).Length == 1;

                        bool isPrimaryKey = p.GetCustomAttributes(typeof(PrimaryKeyAttribute), false).Length == 1;

                        bool saveParentNodes = p.GetCustomAttributes(typeof(StoreParentNodesAttribute), false).Length == 1;

                        // Add the type
                        AddType(p.PropertyType);
                        // Add the member to type
                        Guid memberId = AddTypeMember(p.Name, p.PropertyType, isPrimaryKey);

                        //Add edge to the member
                        node.AddEdge(new Edge<Guid, EdgeData>(memberId, new EdgeData(EdgeType.Property, CalculateEdgeFlags(isPermanent, saveParentNodes), memberId)));
                    }

                    Type collectionType=null;
                    Type dictionaryType= null;

                    // Find all base interfaces and add them too, but not for collections/dictionary
                    if (!Utils.IsCollectionType(t, ref collectionType) &&
                        !Utils.IsDictionaryType(t, ref dictionaryType))
                    {
                        foreach (var baseType in t.GetInterfaces())
                        {
                            var id = AddType(baseType);
                            node.AddEdge(new Edge<Guid, EdgeData>(id, new EdgeData(EdgeType.OfType, id)));
                        }

                        provider.SetNode(typeId, node);
                    }
                    else
                    {
                        foreach (var baseType in t.GetGenericArguments())
                        {
                            AddType(baseType);
                        }
                    }
                }

                // For types with constant list of values, add the values
                var values = GetConstantValues(t);

                if (values.Count > 0)
                {
                    foreach (var value in values)
                    {
                        Guid valueId = Guid.NewGuid();
                        var valueNode = new Node<Guid, object, EdgeData>(NodeType.Scalar, value.ToString());
                        provider.SetNode(valueId, valueNode);
                        node.AddEdge(new Edge<Guid, EdgeData>(valueId, new EdgeData(EdgeType.Contains, value.ToString())));
                    }
                }

                // Add node to collection
                provider.SetNode(typeId, node);
            }

            return typeId;
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Returns root object id for given snapshot
 /// </summary>
 /// <param name="snapshotId">Snapshot ID</param>
 /// <returns>Root object ID</returns>
 public Guid GetRootObjectId(Guid snapshotId)
 {
     return(provider.GetNode(snapshotId, NodeAccess.Read).FindEdge(new EdgeData(EdgeType.RootObject, null)).ToNodeId);
 }
Ejemplo n.º 31
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;
            }
        }
Ejemplo n.º 32
0
        private static RemovalResult MergeNodes(INodeProvider <Guid, object, EdgeData> nodes, Node <Guid, object, EdgeData> node, int leftIndex, int rightIndex, int treeOrder)
        {
            var leftKey    = node.Edges.Keys[leftIndex];
            var leftNodeId = node.Edges[leftKey].ToNodeId;
            var leftNode   = nodes.GetNode(leftNodeId, NodeAccess.ReadWrite);

            var rightKey    = node.Edges.Keys[rightIndex];
            var rightNodeId = node.Edges[rightKey].ToNodeId;
            var rightNode   = nodes.GetNode(rightNodeId, NodeAccess.ReadWrite);

            if (!leftNode.Data.Equals(rightNode.Data))
            {
                throw new InvalidOperationException("Both nodes must be of same type");
            }

            if (leftNode.Data.Equals(InternalNodeData))
            {
                var maxEdgeKey = leftNode.Edges.Keys[leftNode.Edges.Count - 1];
                var maxEdge    = leftNode.Edges[maxEdgeKey];
                leftNode.Edges.Remove(maxEdgeKey);
                leftNode.AddEdge(new Edge <Guid, EdgeData>(maxEdge.ToNodeId, LeftEdge(nodes, rightNode).Data));
            }

            if ((leftNode.Edges.Count + rightNode.Edges.Count) <= treeOrder)
            {
                // Take all from left node
                for (int i = 0; i < leftNode.Edges.Count; i++)
                {
                    EdgeData removalKey = leftNode.Edges.Keys[i];
                    rightNode.AddEdge(leftNode.Edges[removalKey]);
                }

                nodes.SetNode(rightNodeId, rightNode);

                nodes.Remove(leftNodeId);
                node.Edges.Remove(leftKey);

                if (node.Edges.Count == 1)
                {
                    // When no more nodes remaining copy from child
                    node.SetData(rightNode.Data);
                    node.Edges.Clear();

                    foreach (var childEdge in rightNode.Edges.Values)
                    {
                        node.AddEdge(childEdge);
                    }

                    nodes.Remove(rightNodeId);
                }

                return(new RemovalResult(node.Edges.Count, true, true));
            }
            else
            {
                // Decide how many edges to take from right node
                int numberToTake = (leftNode.Edges.Count + rightNode.Edges.Count) / 2 - leftNode.Edges.Count;

                // Copy or merge?
                if (numberToTake > 0)
                {
                    // Copy edges from right -> left
                    for (int i = 0; i < numberToTake; i++)
                    {
                        EdgeData removalKey = rightNode.Edges.Keys[0];

                        leftNode.AddEdge(rightNode.Edges[removalKey]);
                        rightNode.Edges.Remove(removalKey);
                    }

                    node.Edges.Remove(leftKey);
                    node.AddEdge(new Edge <Guid, EdgeData>(leftNodeId, LeftEdge(nodes, rightNode).Data));

                    nodes.SetNode(leftNodeId, leftNode);
                    nodes.SetNode(rightNodeId, rightNode);

                    // No edges were removed
                    return(new RemovalResult(node.Edges.Count, true, true));
                }
                else
                if (numberToTake < 0)
                {
                    // Copy edges from left -> right
                    for (int i = 0; i < Math.Abs(numberToTake); i++)
                    {
                        EdgeData removalKey = leftNode.Edges.Keys[leftNode.Edges.Count - 1];

                        rightNode.AddEdge(leftNode.Edges[removalKey]);
                        leftNode.Edges.Remove(removalKey);
                    }

                    node.Edges.Remove(leftKey);
                    node.AddEdge(new Edge <Guid, EdgeData>(leftNodeId, LeftEdge(nodes, rightNode).Data));

                    nodes.SetNode(leftNodeId, leftNode);
                    nodes.SetNode(rightNodeId, rightNode);

                    // No edges were removed
                    return(new RemovalResult(node.Edges.Count, true, true));
                }

                throw new ArgumentException("Nothing to copy");
            }
        }