A lightweight persisted graph library, based on Voron - a new transactional key value store developed from scratch by Hibernating Rhinos.
It is a pet project - a sandbox to play with graph theory related stuff, and perhaps also make something usefull out of it.
By something useful I mean easy to use rich graph library functionality, with persisted graph data, and without the need to load entire graph into memory.
(with emphasis on easy to use :) )
Note : this project is work in progress and is far from finished
Voron.Graph depends on Voron storage, and if you choose to download and compile, you need to:
- Get Voron sources
- Update references to Voron in the project
- Compile!
And how do I use it?
Usage of the library is simple. The following code creates graph, creates hierarchy of objects
and then queries for adjacent nodes of a certain node.
All code snippets presented here are taken from unit tests with minor adaptation
using (var storage = new StorageEnvironment(StorageEnvironmentOptions.CreateMemoryOnly()))
{
var graph = new GraphStorage("TestGraph", storage);
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"));
graph.Commands.CreateEdgeBetween(tx, node3, node1);
graph.Commands.CreateEdgeBetween(tx, node3, node2);
//looping edge also ok!
//adding multiple loops will overwrite each other
graph.Commands.CreateEdgeBetween(tx, node2, node2);
tx.Commit();
}
using (var tx = graph.NewTransaction(TransactionFlags.Read))
{
var adjacentNodes = graph.Queries.GetAdjacentOf(tx, node3).ToList();
adjacentNodes.Select(x => x.Key).Should().Contain(new[] { node1.Key, node2.Key });
}
}
#### Algorithms Using algorithm implementations in Voron.Graph is also simple.
In this code snippet a graph with hierarchy is created, and then with shortest & cheapest path is found between node1 and node4
*Assume that Env is StorageEnvironment of the Voron that was initialized earlier.*
```C# 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 shortestPathAlgorithm = new DijkstraShortestPath(tx, graph, node1, cancelTokenSource.Token); var shortestPathsData = shortestPathAlgorithm.Execute();
var shortestNodePath = shortestPathsData.GetShortestPathToNode(node4); shortestNodePath.Should().ContainInOrder(node1.Key, node2.Key, node3.Key, node4.Key); }
####License
Apache v2 License for the code of this project. Probably having/not having a license doesn't matter at this point, but still, just in case, I've added one. <br/>
About licensing of the Voron project - you need to contact [Hibernating Rhinos](http://hibernatingrhinos.com/) to inquire more about it.