示例#1
0
        public void TestFillRemove()
        {
            INodeProvider <Guid, object, EdgeData> nodes = new DirectNodeProviderSafe <Guid, object, EdgeData>(new MemoryStorageUnsafe <Guid, object>(), false);

            Guid rootId = Guid.NewGuid();
            Node <Guid, object, EdgeData> node = BPlusTreeOperations.CreateRootNode(NodeType.Collection, rootId);

            nodes.SetNode(rootId, node);

            Collection <Guid> references = new Collection <Guid>();

            for (int i = 0; i < 1000; i++)
            {
                references.Add(Guid.NewGuid());
            }

            int count = 0;

            foreach (var reference in references)
            {
                Assert.AreEqual(count, BPlusTreeOperations.Count(nodes, rootId, EdgeType.ListItem));
                BPlusTreeOperations.InsertEdge(nodes, rootId, new Edge <Guid, EdgeData>(reference, new EdgeData(EdgeType.ListItem, reference)), TreeOrder);
                count++;
            }

            foreach (var reference in references)
            {
                Assert.AreEqual(count, BPlusTreeOperations.Count(nodes, rootId, EdgeType.ListItem));
                BPlusTreeOperations.RemoveEdge(nodes, rootId, new EdgeData(EdgeType.ListItem, reference), TreeOrder);
                count--;
            }
        }
示例#2
0
 internal void SetReference(Guid instanceId, object key, Guid referenceId)
 {
     if (!BPlusTreeOperations.TrySetEdgeToNode(provider, instanceId, new EdgeData(EdgeType.ListItem, key), referenceId))
     {
         throw new KeyNotFoundException("Item not found with the specified key");
     }
 }
 /// <summary>
 /// Initialize global root node if not found
 /// </summary>
 private void InitializeRoot()
 {
     if (!nodes.Contains(Constants.SnapshotsNodeId))
     {
         var node = BPlusTreeOperations.CreateRootNode(NodeType.Collection, Constants.SnapshotsNodeId);
         nodes.SetNode(Constants.SnapshotsNodeId, node);
     }
 }
 /// <summary>
 /// Determines if there is change set information for given snapshot
 /// </summary>
 /// <param name="snapshotId">Snapshot Id to query</param>
 /// <returns>True if data exists</returns>
 public bool ContainsSnapshot(Guid snapshotId)
 {
     lock (sync)
     {
         Edge <Guid, EdgeData> edge = null;
         return(BPlusTreeOperations.TryFindEdge(nodes, Constants.SnapshotsNodeId, new EdgeData(EdgeType.ListItem, snapshotId), out edge));
     }
 }
 /// <summary>
 /// Removes information for a snapshot
 /// </summary>
 /// <param name="snapshotId">Snapshot ID to remove</param>
 public void RemoveChangeSet(Guid snapshotId)
 {
     lock (sync)
     {
         // Remove from snapshots list
         if (BPlusTreeOperations.RemoveEdge(nodes, Constants.SnapshotsNodeId, new EdgeData(EdgeType.ListItem, snapshotId), TreeOrder))
         {
             DeleteTree(snapshotId);
         }
     }
 }
示例#6
0
        internal void AddScalar(Guid instanceId, Guid itemTypeId, object key, object value)
        {
            Guid id = Guid.NewGuid();

            // Create new value node
            var node = new Node <Guid, object, EdgeData>(NodeType.Scalar, value);

            provider.SetNode(id, node);

            BPlusTreeOperations.InsertEdge(provider, instanceId, new Edge <Guid, EdgeData>(id, new EdgeData(EdgeType.ListItem, key)), BPlusTreeOrder);
        }
示例#7
0
 internal long MaxOrderedIdentifier(Guid instanceId)
 {
     if (Count(instanceId) == 0)
     {
         return((long)0);
     }
     else
     {
         return((long)BPlusTreeOperations.RightEdge(provider, provider.GetNode(instanceId, NodeAccess.Read)).Data.Data);
     }
 }
示例#8
0
        private void FindTreeAddedElements(Guid nodeId, RecursiveResolutionParameters parameters, out Dictionary <EdgeData, Edge <Guid, EdgeData> > addedElements, out Dictionary <EdgeData, Edge <Guid, EdgeData> > removedElements)
        {
            addedElements   = new Dictionary <EdgeData, Edge <Guid, EdgeData> >();
            removedElements = new Dictionary <EdgeData, Edge <Guid, EdgeData> >();

            // TODO (nsabo) Optimize searching by new ID value
            Guid originalNodeId = Guid.Empty;

            foreach (var item in parameters.IntermediateChanges)
            {
                if (item.Value.Equals(nodeId))
                {
                    originalNodeId = item.Key;
                    break;
                }
            }

            if (originalNodeId == Guid.Empty)
            {
                originalNodeId = nodeId;
            }

            // Go through changed list and see if some item has not been included in the last version
            using (var enumerator = BPlusTreeOperations.GetEnumerator(parameters.SourceProvider, originalNodeId, EdgeType.ListItem))
            {
                while (enumerator.MoveNext())
                {
                    var edge = enumerator.Current;
                    Edge <Guid, EdgeData> foundEdge = null;

                    // Try finding the element in last version
                    if (!BPlusTreeOperations.TryFindEdge(nodes, originalNodeId, edge.Data, out foundEdge))
                    {
                        addedElements.Add(edge.Data, edge);
                    }
                }
            }

            // Go through last version and see if there are elements which are not found in changed list
            using (var enumerator = BPlusTreeOperations.GetEnumerator(nodes, originalNodeId, EdgeType.ListItem))
            {
                while (enumerator.MoveNext())
                {
                    var edge = enumerator.Current;
                    Edge <Guid, EdgeData> foundEdge = null;

                    // Try finding the element in last version
                    if (!BPlusTreeOperations.TryFindEdge(parameters.SourceProvider, originalNodeId, edge.Data, out foundEdge))
                    {
                        removedElements.Add(edge.Data, edge);
                    }
                }
            }
        }
示例#9
0
        internal Guid GetInstanceTypeId(Guid referenceId)
        {
            Edge <Guid, EdgeData> edge = null;

            if (BPlusTreeOperations.TryFindEdge(provider, referenceId, new EdgeData(EdgeType.OfType, null), out edge))
            {
                return(edge.ToNodeId);
            }
            else
            {
                return(Guid.Empty);
            }
        }
示例#10
0
        internal void SetScalar(Guid instanceId, Guid itemTypeId, object key, object value)
        {
            Guid id = Guid.NewGuid();

            // Create new value node
            var node = new Node <Guid, object, EdgeData>(NodeType.Scalar, value);

            provider.SetNode(id, node);

            if (!BPlusTreeOperations.TrySetEdgeToNode(provider, instanceId, new EdgeData(EdgeType.ListItem, key), id))
            {
                throw new KeyNotFoundException("Item not found with the specified key");
            }
        }
示例#11
0
        internal bool RemoveReference(Guid instanceId, Guid referenceId)
        {
            using (var enumerator = GetEnumerator(instanceId))
            {
                while (enumerator.MoveNext())
                {
                    if (enumerator.Current.ToNodeId.Equals(referenceId))
                    {
                        return(BPlusTreeOperations.RemoveEdge(provider, instanceId, enumerator.Current.Data, BPlusTreeOrder));
                    }
                }

                return(false);
            }
        }
示例#12
0
        internal bool TryGetReference(Guid instanceId, object key, out Guid referenceId)
        {
            Edge <Guid, EdgeData> edge = null;

            if (BPlusTreeOperations.TryFindEdge(provider, instanceId, new EdgeData(EdgeType.ListItem, key), out edge))
            {
                referenceId = edge.ToNodeId;
                return(true);
            }
            else
            {
                referenceId = Guid.Empty;
                return(false);
            }
        }
示例#13
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);
            }
        }
示例#14
0
        internal bool RemoveScalar(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(BPlusTreeOperations.RemoveEdge(provider, instanceId, enumerator.Current.Data, BPlusTreeOrder));
                    }
                }

                return(false);
            }
        }
示例#15
0
        /// <summary>
        /// Initializes new dictionary instance
        /// </summary>
        /// <param name="typeId">Type ID of dictionary</param>
        /// <returns>Instance ID</returns>
        public Guid NewInstance(Guid typeId)
        {
            //Determine new id
            Guid id = Guid.NewGuid();
            // Create node as root of B+ tree
            var node = BPlusTreeOperations.CreateRootNode(NodeType.Dictionary, id);

            // Add node in provider
            provider.SetNode(id, node);
            // Add edge from node to the type of node
            BPlusTreeOperations.InsertEdge(provider, id, new Edge <Guid, EdgeData>(typeId, new EdgeData(EdgeType.OfType, null)), BPlusTreeOrder);
            // Add node in provider
            provider.SetNode(id, node);
            // Return the instance id
            return(id);
        }
示例#16
0
 /// <summary>
 /// Provides change set edges for given snapshot
 /// </summary>
 /// <param name="snapshotId">Snapshot ID</param>
 /// <returns>Change set edge enumerator</returns>
 public IEnumerator <Edge <Guid, EdgeData> > GetChangeSetEdges(Guid snapshotId)
 {
     lock (sync)
     {
         Edge <Guid, EdgeData> edge = null;
         if (BPlusTreeOperations.TryFindEdge(nodes, Constants.SnapshotsNodeId, new EdgeData(EdgeType.ListItem, snapshotId), out edge))
         {
             return(BPlusTreeOperations.GetEnumerator(nodes, snapshotId, EdgeType.ListItem));
         }
         else
         {
             // Returtn empty enumerator
             return(new Collection <Edge <Guid, EdgeData> >().GetEnumerator());
         }
     }
 }
示例#17
0
        internal void Clear(Guid instanceId)
        {
            var removalKeys = new Collection <EdgeData>();

            using (var enumerator = GetEnumerator(instanceId))
            {
                while (enumerator.MoveNext())
                {
                    removalKeys.Add(enumerator.Current.Data);
                }
            }

            foreach (var key in removalKeys)
            {
                BPlusTreeOperations.RemoveEdge(provider, instanceId, key, BPlusTreeOrder);
            }
        }
示例#18
0
        /// <summary>
        /// Stores collectable nodes for a change set
        /// </summary>
        /// <param name="changeSet">Change set</param>
        /// <param name="mutableParentMap">Parent map of mutable data</param>
        /// <param name="immutableParentMap">Parent map of immutable data</param>
        public void StoreChangeset(AppendableChangeSet <Guid, object, EdgeData> changeSet, IParentMapProvider <Guid, object, EdgeData> mutableParentMap, IParentMapProvider <Guid, object, EdgeData> immutableParentMap)
        {
            Guid snapshotId = changeSet.SourceSnapshotId;

            var snapshotRoot = BPlusTreeOperations.CreateRootNode(NodeType.Collection, snapshotId);

            nodes.SetNode(snapshotId, snapshotRoot);

            Hashtable collectedNodes = new Hashtable();

            GetCollectedNodesRecursive(changeSet.SourceSnapshotId, changeSet, mutableParentMap, immutableParentMap, collectedNodes, new Hashtable());

            foreach (Guid nodeId in collectedNodes.Keys)
            {
                BPlusTreeOperations.InsertEdge(nodes, snapshotId, new Edge <Guid, EdgeData>(nodeId, new EdgeData(EdgeType.ListItem, nodeId)), TreeOrder);
            }
        }
示例#19
0
        /// <summary>
        /// Stores the change set
        /// </summary>
        /// <param name="changeSet">Change set to store</param>
        public void SetChangeSet(AppendableChangeSet <Guid, object, EdgeData> changeSet)
        {
            lock (sync)
            {
                var snapshotNode = BPlusTreeOperations.CreateRootNode(NodeType.Dictionary, changeSet.DestinationSnapshotId);

                nodes.SetNode(changeSet.DestinationSnapshotId, snapshotNode);

                // Add all changes from changeset to snapshot tree.
                foreach (var item in changeSet.Mapping)
                {
                    BPlusTreeOperations.InsertEdge(nodes, changeSet.DestinationSnapshotId, new Edge <Guid, EdgeData>(item.Value, new EdgeData(EdgeType.ListItem, item.Key)), TreeOrder);
                }

                // Add snapshot to collection
                BPlusTreeOperations.InsertEdge(nodes, Constants.SnapshotsNodeId, new Edge <Guid, EdgeData>(changeSet.DestinationSnapshotId, new EdgeData(EdgeType.ListItem, changeSet.DestinationSnapshotId)), TreeOrder);
            }
        }
示例#20
0
        /// <summary>
        /// Recursive breadth-first pass through node graph which generates parent information
        /// </summary>
        /// <param name="snapshotId">Snapshot to generate</param>
        /// <param name="nodeId">Visited node</param>
        /// <param name="visitedNodes">List of visited nodes</param>
        private void AddParentsRecursive(Guid nodeId, Hashtable visitedNodes, INodeProvider <Guid, object, EdgeData> nodes)
        {
            if (nodeId.Equals(Constants.NullReferenceNodeId))
            {
                return;
            }

            if (visitedNodes.ContainsKey(nodeId))
            {
                return;
            }
            else
            {
                visitedNodes.Add(nodeId, null);
            }

            // Add the node as parent of all child nodes
            foreach (var edge in dataNodeProvider.GetNode(nodeId, NodeAccess.Read).Edges.Values)
            {
                if (EdgeFilter(edge))
                {
                    if (!nodes.Contains(edge.ToNodeId))
                    {
                        var holderNode = BPlusTreeOperations.CreateRootNode(NodeType.Collection, edge.ToNodeId);
                        nodes.SetNode(edge.ToNodeId, holderNode);
                    }

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

            foreach (var edge in dataNodeProvider.GetNode(nodeId, NodeAccess.Read).Edges.Values)
            {
                AddParentsRecursive(edge.ToNodeId, visitedNodes, nodes);
            }
        }
示例#21
0
        public void TestConsistency()
        {
            INodeProvider <Guid, object, EdgeData> nodes = new DirectNodeProviderSafe <Guid, object, EdgeData>(new MemoryStorageUnsafe <Guid, object>(), false);

            Guid rootId = Guid.NewGuid();
            Node <Guid, object, EdgeData> node = BPlusTreeOperations.CreateRootNode(NodeType.Collection, rootId);

            nodes.SetNode(rootId, node);

            Collection <Guid> references      = new Collection <Guid>();
            Collection <Guid> referencesAdded = new Collection <Guid>();

            for (int i = 0; i < 1000; i++)
            {
                references.Add(Guid.NewGuid());
            }

            foreach (var reference in references)
            {
                var data = new EdgeData(EdgeType.ListItem, reference);
                BPlusTreeOperations.InsertEdge(nodes, rootId, new Edge <Guid, EdgeData>(reference, data), TreeOrder);
                referencesAdded.Add(reference);

                foreach (var addedReference in referencesAdded)
                {
                    var dataAdded = new EdgeData(EdgeType.ListItem, addedReference);
                    Edge <Guid, EdgeData> edge;
                    Assert.IsTrue(BPlusTreeOperations.TryFindEdge(nodes, rootId, dataAdded, out edge));
                    Assert.AreEqual(addedReference, edge.Data.Data);
                }
            }

            foreach (var reference in references)
            {
                var data = new EdgeData(EdgeType.ListItem, reference);
                Edge <Guid, EdgeData> edge;
                Assert.IsTrue(BPlusTreeOperations.TryFindEdge(nodes, rootId, data, out edge));
                Assert.AreEqual(reference, edge.Data.Data);
                Assert.AreEqual(reference, edge.ToNodeId);
            }
        }
示例#22
0
        /// <summary>
        /// Returns list of parents for given node witin a snapshot
        /// </summary>
        /// <param name="snapshotId">Snapshot within parents are requested</param>
        /// <param name="nodeId">Node which parents are returned</param>
        /// <returns>List of parent node identifiers for each node in dictionary format, or null if there are no parent edges</returns>
        public IEnumerator <Edge <Guid, EdgeData> > ParentEdges(Guid snapshotId, Guid nodeId)
        {
            lock (dataSync)
            {
                // Generate parents if they dont exist
                if (!createdNodes)
                {
                    createdNodes = true;
                    AddParentsRecursive(snapshotId, new Hashtable(), nodes);
                    lastSnapshotId = snapshotId;
                }

                // Do we have the last snapshot in the memory
                if (snapshotId != lastSnapshotId)
                {
                    // Try going for fallback provider
                    if (fallbackParentMapProvider != null)
                    {
                        return(fallbackParentMapProvider.ParentEdges(snapshotId, nodeId));
                    }
                    else
                    {
                        // If not, generate asked snapshot
                        nodes.Clear();
                        AddParentsRecursive(snapshotId, new Hashtable(), nodes);
                        lastSnapshotId = snapshotId;
                    }
                }

                // Find edge leading to holder node for given ID
                if (nodes.Contains(nodeId))
                {
                    return(BPlusTreeOperations.GetEnumerator(nodes, nodeId, EdgeType.Contains));
                }
                else
                {
                    return(null);
                }
            }
        }
示例#23
0
        private static void LogCollection(Guid nodeId, Node <Guid, object, EdgeData> node, INodeProvider <Guid, object, EdgeData> nodes, INodeProvider <Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            Edge <Guid, EdgeData> typeEdge = null;

            BPlusTreeOperations.TryFindEdge(nodes, nodeId, new EdgeData(EdgeType.OfType, null), out typeEdge);

            var typeId   = typeEdge.ToNodeId;
            var typeName = typesService.GetTypeFromId(typeId).Name;

            Debug.WriteLine(LogTabs(tabLevel) + nodeId + "(" + typeName + ")");
            Debug.WriteLine(LogTabs(tabLevel) + "Previous=" + node.Previous);


            using (var enumeration = BPlusTreeOperations.GetEnumerator(nodes, nodeId, EdgeType.ListItem))
            {
                while (enumeration.MoveNext())
                {
                    Debug.WriteLine(LogTabs(tabLevel) + enumeration.Current.Data + "=");
                    LogNodesRecursive(enumeration.Current.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                }
            }
        }
示例#24
0
 internal bool Remove(Guid instanceId, object key)
 {
     return(BPlusTreeOperations.RemoveEdge(provider, instanceId, new EdgeData(EdgeType.ListItem, key), BPlusTreeOrder));
 }
示例#25
0
 internal IEnumerator <Edge <Guid, EdgeData> > GetEnumerator(Guid instanceId)
 {
     return(BPlusTreeOperations.GetEnumerator(provider, instanceId, EdgeType.ListItem));
 }
示例#26
0
        internal bool ContainsKey(Guid instanceId, object key)
        {
            Edge <Guid, EdgeData> edge = null;

            return(BPlusTreeOperations.TryFindEdge(provider, instanceId, new EdgeData(EdgeType.ListItem, key), out edge));
        }
示例#27
0
 internal void AddReference(Guid instanceId, object key, Guid referenceId)
 {
     BPlusTreeOperations.InsertEdge(provider, instanceId, new Edge <Guid, EdgeData>(referenceId, new EdgeData(EdgeType.ListItem, key)), BPlusTreeOrder);
 }
示例#28
0
 internal int Count(Guid instanceId)
 {
     return(BPlusTreeOperations.Count(provider, instanceId, EdgeType.ListItem));
 }
示例#29
0
 /// <summary>
 /// Returns edges to collectable nodes for a snapshot
 /// </summary>
 /// <param name="snapshotId">Snapshot identifier</param>
 /// <returns>Enumerator of edges towards collectable nodes</returns>
 public IEnumerator <Edge <Guid, EdgeData> > GetEdges(Guid snapshotId)
 {
     return(BPlusTreeOperations.GetEnumerator(nodes, snapshotId, EdgeType.ListItem));
 }
示例#30
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;
            }
        }