예제 #1
0
        public void Put_edge_between_nodes_in_different_session_should_work()
        {
            var graph = new GraphStorage("TestGraph", Env);
            Node node1, node2, node3;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue("test2"));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue("test3"));
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                graph.Commands.CreateEdgeBetween(tx, node2, node3);
                graph.Commands.CreateEdgeBetween(tx, node2, node1);

                //looping edge also ok!
                //adding multiple loops will overwrite each other
                //TODO: add support for multiple edges that have the same keyFrom and keyTo
                graph.Commands.CreateEdgeBetween(tx, node2, node2);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var adjacentNodes = graph.Queries.GetAdjacentOf(tx, node2);
                adjacentNodes.Select(x => x.Key).Should().Contain(new []{ node1.Key, node2.Key, node3.Key});
            }
        }
예제 #2
0
        public async Task BFS_FindOne_with_connected_root_should_return_correct_results()
        {
            var graph = new GraphStorage("TestGraph", Env);
            Node node2;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var node1 = graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue("test2"));
                var node3 = graph.Commands.CreateNode(tx, JsonFromValue("test3"));

                graph.Commands.CreateEdgeBetween(tx, node3, node1);
                graph.Commands.CreateEdgeBetween(tx, node3, node2);

                graph.Commands.CreateEdgeBetween(tx, node2, node2);
                graph.Commands.CreateEdgeBetween(tx, node1, node3);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var bfs = new BreadthFirstSearch(graph, CancelTokenSource.Token);
                var node = await bfs.FindOne(tx, data => ValueFromJson<string>(data).Equals("test2"));

                node.Should().NotBeNull();
                node.Key.Should().Be(node2.Key);
            }
        }
        public void Simple_shortest_path_with_constant_edge_weight_should_work()
        {
            var graph = new GraphStorage("TestGraph", Env);

            Node node1, node2, node3;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue(2));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue(3));

                node1.ConnectWith(tx, node2, graph);
                node1.ConnectWith(tx, node3, graph);
                node2.ConnectWith(tx, node3, graph);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var shortestPathsData = GetAlgorithm(tx,graph,node1).Execute();

                var shortestNodePath = shortestPathsData.GetShortestPathToNode(node3).ToList();
                shortestNodePath.Should().ContainInOrder(node1.Key, node3.Key);
            }
        }
예제 #4
0
        public async Task BFS_FindOne_with_disconnected_root_should_return_null()
        {
            var graph = new GraphStorage("TestGraph", Env);
            Node node2;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var node1 = graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue("test2"));
                var node3 = graph.Commands.CreateNode(tx, JsonFromValue("test3"));

                graph.Commands.CreateEdgeBetween(tx, node3, node1);
                graph.Commands.CreateEdgeBetween(tx, node3, node2);

                //note: root node is selected by using a first node that was added
                //since Voron.Graph is a directed graph - no node leads from the root node means nothing
                //can be found

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var bfs = new BreadthFirstSearch(graph, CancelTokenSource.Token);
                var node = await bfs.FindOne(tx, data => ValueFromJson<string>(data).Equals("test2"));

                node.Should().BeNull();
            }
        }
예제 #5
0
        public async Task BFS_FindOne_with_only_root_node_in_graph_returns_correct_results()
        {
            var graph = new GraphStorage("TestGraph", Env);
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var bfs = new BreadthFirstSearch(graph, CancelTokenSource.Token);
                var node = await bfs.FindOne(tx, data => ValueFromJson<string>(data).Equals("test1"));

                node.Should().NotBeNull();
            }
        }
        public void Between_two_equivalent_paths_first_created_should_be_chosen()
        {
            var graph = new GraphStorage("TestGraph", Env);

            Node node1, node2, node3, node4;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue(2));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue(3));
                node4 = graph.Commands.CreateNode(tx, JsonFromValue(4));

                node1.ConnectWith(tx, node2, graph, 2);
                node2.ConnectWith(tx, node4, graph, 1);

                node1.ConnectWith(tx, node3, graph, 1);
                node3.ConnectWith(tx, node4, graph, 2);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var shortestPathsData = GetAlgorithm(tx, graph, node1).Execute();

                var shortestNodePath = shortestPathsData.GetShortestPathToNode(node4).ToList();
                shortestNodePath.Should().ContainInOrder(node1.Key, node2.Key, node4.Key);
            }
        }
        public void Simple_shortest_path_with_equal_weights_and_alternative_path2()
        {
            var graph = new GraphStorage("TestGraph", Env);

            Node node1, node2, node3, node4, node5, node6;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node4 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node5 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node6 = graph.Commands.CreateNode(tx, JsonFromValue(1));

                node1.ConnectWith(tx, node2, graph,1);
                node1.ConnectWith(tx, node3, graph,15);
                node3.ConnectWith(tx, node6, graph,1);
                node2.ConnectWith(tx, node4, graph,1);
                node4.ConnectWith(tx, node5, graph,1);
                node5.ConnectWith(tx, node6, graph,1);
                
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var shortestPathsData = GetAlgorithm(tx, graph, node1).Execute();

                var shortestNodePath = shortestPathsData.GetShortestPathToNode(node6).ToList();
                shortestNodePath.Should().ContainInOrder(node1.Key,node2.Key, node4.Key, node5.Key);
            }
        }
        public void No_path_between_nodes_should_result_in_null()
        {
            var graph = new GraphStorage("TestGraph", Env);

            Node node1, node2;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue(2));

             
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var shortestPathsData = GetAlgorithm(tx, graph, node1).Execute();

                var shortestNodePath = shortestPathsData.GetShortestPathToNode(node2);
                shortestNodePath.Should().BeNull();
            }
        }
예제 #9
0
        public async Task Can_Avoid_Duplicate_Nodes_InParallel_Adds()
        {
            var graph = new GraphStorage("TestGraph",Env);

            Parallel.For(0, 100, i =>
            {
                using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
                {
	                graph.Commands.CreateNode(tx, JsonFromValue("newNode" + i));
	                tx.Commit();
                }
            });
           
            var fetchedKeys = new List<long>();

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var nodesList = await graph.AdminQueries.GetAllNodes(tx, CancelTokenSource.Token);
                nodesList.Select(node => node.Key).Should().OnlyHaveUniqueItems();
            }
        }
예제 #10
0
        public void Get_edges_between_existing_and_nonexisting_node_should_return_empty_collection()
        {
            var graph = new GraphStorage("TestGraph", Env);
            long node1Id = 0;

            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var node1 = graph.Commands.CreateNode(tx, JsonFromValue("node1"));

                Assert.IsNotNull(node1);
                node1Id = node1.Key;
                
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                Node node1 = graph.Queries.LoadNode(tx, node1Id);
                Node node2 = new Node(-2, JsonFromValue("node2"));

                var edgesList = graph.Queries.GetEdgesBetween(tx, node1, node2);
                edgesList.Should().BeEmpty();
            }
        }
예제 #11
0
        public void Edge_predicate_should_filter_edge_types_correctly()
        {
            var graph = new GraphStorage("TestGraph", Env);
            Node node1, node2, node3, node4, node5;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue("test2"));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue("test3"));
                node4 = graph.Commands.CreateNode(tx, JsonFromValue("test4"));
                node5 = graph.Commands.CreateNode(tx, JsonFromValue("test5"));
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                graph.Commands.CreateEdgeBetween(tx, node1, node2,type: 1);
                graph.Commands.CreateEdgeBetween(tx, node1, node3, type: 2);
                graph.Commands.CreateEdgeBetween(tx, node1, node4, type: 3);
                graph.Commands.CreateEdgeBetween(tx, node1, node5, type: 2);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var adjacentNodes = graph.Queries.GetAdjacentOf(tx, node1, type => type == 2);
                adjacentNodes.Select(x => x.Node.Key).Should().Contain(new[] { node3.Key, node5.Key });
            }
        }
예제 #12
0
        public void Load_nonexisting_node_should_return_null() {
            var graph = new GraphStorage("TestGraph", Env);


            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var illegalNode = graph.Commands.CreateNode(tx,JsonFromValue("onlyNode"));
                illegalNode.Should().NotBeNull();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read)) {
                var noneExistingNode = graph.Queries.LoadNode(tx, 1);
                noneExistingNode.Should().BeNull();
            }

        }
예제 #13
0
        private long Create2DepthHierarchy(GraphStorage graph)
        {
            long centerNodeKey = 0;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var centerNode = graph.Commands.CreateNode(tx, JsonFromValue("centerNode"));
                centerNodeKey = centerNode.Key;


                for (var i = 1; i < 6; i++)
                {
                    var curChild = graph.Commands.CreateNode(tx,JsonFromValue("childNode" + i.ToString()));
                    graph.Commands.CreateEdgeBetween(tx, centerNode, curChild, JsonFromValue(i.ToString()));

                    for (var j = 1; j < 6; j++)
                    {
                        var curGrandChild = graph.Commands.CreateNode(tx, JsonFromValue(string.Concat("grandchild", i.ToString(), "child", i.ToString())));
                        graph.Commands.CreateEdgeBetween(tx, curChild, curGrandChild,JsonFromValue((i * 10 + j).ToString()));
                    }
                }
                tx.Commit();
            }
            return centerNodeKey;
        }
예제 #14
0
        public void Can_Iterate_On_Nearest_Nodes()
        {
            var graph = new GraphStorage("TestGraph", Env);
            long centerNodeKey = 0;

            centerNodeKey = Create2DepthHierarchy(graph);

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var centerNode = graph.Queries.LoadNode(tx, centerNodeKey);
                var nodeValues = new Dictionary<string, string>();
	            string curEdgeVal;
                string curNodeVal;

                foreach (var curNode in graph.Queries.GetAdjacentOf(tx, centerNode))
                {
                    var curEdge = graph.Queries.GetEdgesBetween(tx, centerNode, curNode).FirstOrDefault();              
                    Assert.IsNotNull(curEdge);

                    curEdgeVal = curEdge.Data.Value<string>("Value");
                    curNodeVal = curNode.Data.Value<string>("Value");

                    nodeValues.Add(curNodeVal, curEdgeVal);

                }

                nodeValues.Values.Should().NotContain("grandchild");
                Assert.AreEqual(nodeValues.Count, 5);
            }
        }
예제 #15
0
        public async Task BFS_FindMany_with_connected_root_returns_correct_results()
        {
            var graph = new GraphStorage("TestGraph", Env);
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var node1 = graph.Commands.CreateNode(tx, JsonFromValue("test1"));
                var node2 = graph.Commands.CreateNode(tx, JsonFromValue("test2"));
                var node3 = graph.Commands.CreateNode(tx, JsonFromValue("test3"));
                var node4 = graph.Commands.CreateNode(tx, JsonFromValue("test4"));

                graph.Commands.CreateEdgeBetween(tx, node3, node1);
                graph.Commands.CreateEdgeBetween(tx, node3, node2);

                graph.Commands.CreateEdgeBetween(tx, node3, node4);
                graph.Commands.CreateEdgeBetween(tx, node2, node2);
                graph.Commands.CreateEdgeBetween(tx, node2, node4);
                graph.Commands.CreateEdgeBetween(tx, node1, node3);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var bfs = new BreadthFirstSearch(graph, CancelTokenSource.Token);
                var nodes = await bfs.FindMany(tx, data => ValueFromJson<string>(data).Contains("2") ||
                                                           ValueFromJson<string>(data).Contains("4"));

                nodes.Select(x => ValueFromJson<string>(x.Data)).Should().Contain("test2", "test4");
            }
        }
        public void Cheap_long_path_over_short_expensive_path_should_be_chosen()
        {
            var graph = new GraphStorage("TestGraph", Env);

            Node node1, node2, node3, node4;
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                node1 = graph.Commands.CreateNode(tx, JsonFromValue(1));
                node2 = graph.Commands.CreateNode(tx, JsonFromValue(2));
                node3 = graph.Commands.CreateNode(tx, JsonFromValue(3));
                node4 = graph.Commands.CreateNode(tx, JsonFromValue(4));

                node1.ConnectWith(tx, node2, graph, 1);
                node2.ConnectWith(tx, node3, graph, 1);
                node3.ConnectWith(tx, node4, graph, 1);

                node1.ConnectWith(tx, node4, graph, 10);

                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var shortestPathsData = GetAlgorithm(tx, graph, node1).Execute();

                var shortestNodePath = shortestPathsData.GetShortestPathToNode(node4);
                shortestNodePath.Should().ContainInOrder(node1.Key, node2.Key, node3.Key, node4.Key);
            }
        }
예제 #17
0
        public void Get_edges_between_two_nonexisting_nodes_should_return_empty_collection()
        {
            var graph = new GraphStorage("TestGraph", Env);

            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                var node1 = new Node(-1,JsonFromValue("node1"));
                var node2 = new Node(-2,JsonFromValue("node2"));

                var edgesList = graph.Queries.GetEdgesBetween(tx, node1, node2);
                edgesList.Should().BeEmpty();
            }                        
        }
예제 #18
0
        public void Read_and_writing_system_metadata_should_work()
        {
            var graph = new GraphStorage("TestGraph", Env);
            using (var tx = graph.NewTransaction(TransactionFlags.ReadWrite))
            {
                graph.Commands.PutToSystemMetadata(tx, "Foo", "Bar");
                graph.Commands.PutToSystemMetadata(tx, "FooNum", 123);
                graph.Commands.PutToSystemMetadata(tx, "FooBoolean", false);
                
                tx.Commit();
            }

            using (var tx = graph.NewTransaction(TransactionFlags.Read))
            {
                var bar = graph.Queries.GetFromSystemMetadata<string>(tx, "Foo");
                var fooNum = graph.Queries.GetFromSystemMetadata<int>(tx, "FooNum");
                var fooBoolean = graph.Queries.GetFromSystemMetadata<bool>(tx, "FooBoolean");

                Assert.AreEqual("Bar", bar);
                Assert.AreEqual(123, fooNum);
                Assert.AreEqual(false, fooBoolean);
            }
        }