A lightweight persisted graph library, based on Voron - a new transactional key value store developed from scratch by Hibernating Rhinos.
The aim of this project is to supply rich graph library functionality, with persisted graph data, and without the need to load entire graph into memory.
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 BFS find all nodes that contain either test2 or test4 in their data
*Assume that Env is StorageEnvironment of the Voron that was initialized earlier.*
```C# 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(data).Contains("2") || ValueFromJson(data).Contains("4"));
nodes.Select(x => ValueFromJson(x.Data)).Should().Contain("test2", "test4"); }
####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.