public void Traversal_without_limits_should_traverse_all_edges1() { using (var storage = new GraphStorage()) { long id1, id2; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); storage.AddEdge(tx, id1, id2); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .Execute(id1); results.Should() .HaveCount(2) .And .Contain(id1).And.Contain(id2); results = storage.Traverse() .Execute(id2); results.Should() .HaveCount(1) .And .OnlyContain(r => r == id2); } } }
public void Traversal_with_DFS_should_handle_loops_properly1() { using (var storage = new GraphStorage()) { long id1, id2, id3; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 1, 1, 1 }); storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id3); storage.AddEdge(tx, id3, id1); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .Execute(id1); results.Should() .HaveCount(3) .And .Contain(new[] { id1, id2, id3 }); } } }
public void Traversal_should_travel_loops_once1() { using (var storage = new GraphStorage()) { long id1, id2; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id1); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .Execute(id1); results.Should() .HaveCount(2) .And .ContainInOrder(id1, id2); results = storage.Traverse() .Execute(id2); results.Should() .HaveCount(2) .And .ContainInOrder(id2, id1); } } }
public unsafe void Simple_edge_read_write_without_data_should_work() { using (var storage = new GraphStorage()) { long vertexId1, vertexId2, edgeId; using (var tx = storage.WriteTransaction()) { vertexId1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); vertexId2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); edgeId = storage.AddEdge(tx, vertexId1, vertexId2); tx.Commit(); } using (var tx = storage.ReadTransaction()) { Assert.Empty(storage.ReadEdgeData(tx, edgeId)); int size; var data = storage.ReadEdgeData(tx, edgeId, out size); Assert.Equal(0, size); //will return valid ptr, but the size of data chunk is zero Assert.False(null == data); } } }
public void Simple_edge_delete_should_work() { using (var storage = new GraphStorage()) { long vertexId1, vertexId2, edgeId; using (var tx = storage.WriteTransaction()) { vertexId1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); vertexId2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); edgeId = storage.AddEdge(tx, vertexId1, vertexId2, new byte[] { 5, 6, 7, 8 }); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var data = storage.ReadEdgeData(tx, edgeId); Assert.NotNull(data); } using (var tx = storage.WriteTransaction()) { storage.RemoveEdge(tx, edgeId); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var data = storage.ReadEdgeData(tx, edgeId); Assert.Null(data); } } }
public unsafe void GetAdjacent_should_work() { using (var storage = new GraphStorage()) { long vertexId1, vertexId2, vertexId3, vertexId4, vertexId5; using (var tx = storage.WriteTransaction()) { vertexId1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); vertexId2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); vertexId3 = storage.AddVertex(tx, new byte[] { 4, 5, 6 }); vertexId4 = storage.AddVertex(tx, new byte[] { 7 }); vertexId5 = storage.AddVertex(tx, new byte[] { 8 }); storage.AddEdge(tx, vertexId1, vertexId2); storage.AddEdge(tx, vertexId1, vertexId3); storage.AddEdge(tx, vertexId1, vertexId5); storage.AddEdge(tx, vertexId4, vertexId2); storage.AddEdge(tx, vertexId4, vertexId4); storage.AddEdge(tx, vertexId4, vertexId1); storage.AddEdge(tx, vertexId2, vertexId3); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var adjacentVertices = storage.GetAdjacent(tx, vertexId1).ToList(); adjacentVertices.Should() .HaveCount(3) .And.Contain(new[] { vertexId2, vertexId3, vertexId5 }); adjacentVertices = storage.GetAdjacent(tx, vertexId2).ToList(); adjacentVertices.Should() .HaveCount(1) .And.Contain(new[] { vertexId3 }); adjacentVertices = storage.GetAdjacent(tx, vertexId4).ToList(); adjacentVertices.Should() .HaveCount(3) .And.Contain(new[] { vertexId1, vertexId2, vertexId4 }); } } }
public void Traversal_with_min_depth_should_traverse_relevant_edges1_with_DFS() { using (var storage = new GraphStorage()) { long id1, id2, id3, id4, id5; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id4 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id5 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id3); storage.AddEdge(tx, id2, id4); storage.AddEdge(tx, id4, id5); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .WithMinDepth(1) .Execute(id1); results.Should() .HaveCount(4) .And .Contain(new[] { id2, id3, id4, id5 }); results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .WithMinDepth(2) .Execute(id1); results.Should() .HaveCount(3) .And .Contain(new[] { id3, id4, id5 }); results = storage.Traverse() //zero-based depth, //4 levels in total .WithStrategy(Traversal.Strategy.Dfs) .WithMinDepth(3) .Execute(id1); results.Should() .HaveCount(1) .And .Contain(id5); } } }
public void Traversal_without_edges_should_return_first_vertex() { using (var storage = new GraphStorage()) { long id1, id2; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); tx.Commit(); } //test both dfs and bfs using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .WithStrategy(Traversal.Strategy.Bfs) .Execute(id1); results.Should() .HaveCount(1) .And .OnlyContain(r => r == id1); results = storage.Traverse() .Execute(id2); results.Should() .HaveCount(1) .And .OnlyContain(r => r == id2); results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .Execute(id1); results.Should() .HaveCount(1) .And .OnlyContain(r => r == id1); results = storage.Traverse() .Execute(id2); results.Should() .HaveCount(1) .And .OnlyContain(r => r == id2); } } }
public void Traversal_with_DFS_and_with_vertex_visitor_should_visit_vertices_once() { using (var storage = new GraphStorage()) { long id1, id2, id3, id4; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 1, 1, 1 }); id4 = storage.AddVertex(tx, new byte[] { 1, 0, 1 }); //create well connected graph storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id3); storage.AddEdge(tx, id3, id1); storage.AddEdge(tx, id2, id4); storage.AddEdge(tx, id1, id4); storage.AddEdge(tx, id3, id4); storage.AddEdge(tx, id4, id3); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var fetchedData = new List <byte[]>(); var expectedData = new[] { new byte[] { 1, 2, 3 }, new byte[] { 3, 2, 1 }, new byte[] { 1, 1, 1 }, new byte[] { 1, 0, 1 } }; var results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .Execute(id1, vertexVisitor: reader => { var data = reader.ReadData((int)VertexTableFields.Data); fetchedData.Add(data); }); //DFS has reverse traversal order Assert.Equal(expectedData.Reverse(), fetchedData); } } }
public void Traversal_with_DFS_and_with_edges_visitor_should_visit_vertices_once() { using (var storage = new GraphStorage()) { long id1, id2, id3; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 1, 1, 1 }); storage.AddEdge(tx, id1, id2, new byte[] { 12 }); storage.AddEdge(tx, id2, id3, new byte[] { 23 }); storage.AddEdge(tx, id3, id1, new byte[] { 31 }); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var fetchedData = new List <byte[]>(); var expectedData = new[] { new byte[] { 12 }, new byte[] { 23 }, new byte[] { 31 } }; var results = storage.Traverse() .WithStrategy(Traversal.Strategy.Dfs) .Execute(id1, edgeVisitor: reader => { var data = reader.ReadData((int)EdgeTableFields.Data); fetchedData.Add(data); }); //DFS visits edges in the same manner as BFS, but vertices it visits in reverse Assert.Equal(expectedData, fetchedData); } } }
public void Traversal_with_max_results_should_return_proper_number_of_results() { using (var storage = new GraphStorage()) { long id1, id2, id3; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 1, 1, 1 }); storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id3); storage.AddEdge(tx, id3, id1); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .WithMaxResults(2) .Execute(id1); results.Should() .HaveCount(2) .And .Contain(new[] { id1, id2 }); results = storage.Traverse() .WithMaxResults(2) .Execute(id2); results.Should() .HaveCount(2) .And .Contain(new[] { id2, id3 }); } } }
public void Simple_vertex_read_write_should_work() { using (var storage = new GraphStorage()) { long id1, id2; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var data1 = storage.ReadVertexData(tx, id1); Assert.NotNull(data1); Assert.Equal(new byte[] { 1, 2, 3 }, data1); var data2 = storage.ReadVertexData(tx, id2); Assert.NotNull(data2); Assert.Equal(new byte[] { 3, 2, 1 }, data2); } } }
public void Traversal_with_max_results_lower_than_actual_results_should_have_no_effect() { using (var storage = new GraphStorage()) { long id1, id2, id3; using (var tx = storage.WriteTransaction()) { id1 = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); id2 = storage.AddVertex(tx, new byte[] { 3, 2, 1 }); id3 = storage.AddVertex(tx, new byte[] { 1, 1, 1 }); storage.AddEdge(tx, id1, id2); storage.AddEdge(tx, id2, id3); storage.AddEdge(tx, id3, id1); tx.Commit(); } using (var tx = storage.ReadTransaction()) { var results = storage.Traverse() .WithMaxResults(50) .Execute(id1); results.Should() .HaveCount(3) .And .ContainInOrder(id1, id2, id3); results = storage.Traverse() .Execute(id2); results.Should() .HaveCount(3) .And .ContainInOrder(id2, id3, id1); } } }
public void Simple_vertex_delete_should_work() { using (var storage = new GraphStorage()) { long id; using (var tx = storage.WriteTransaction()) { id = storage.AddVertex(tx, new byte[] { 1, 2, 3 }); tx.Commit(); } using (var tx = storage.WriteTransaction()) { storage.RemoveVertex(tx, id); tx.Commit(); } using (var tx = storage.ReadTransaction()) Assert.Null(storage.ReadVertexData(tx, id)); } }