New and Notable Features of IG 3.4

Printer-friendly version


InfiniteGraph's 3.4 release provides many performance enhancements that affect various operations, from adding data to performing navigation queries. Most enhancements are behind the scenes and can be leveraged through existing API methods, but some enhancements are available only through new API. Some notable API enhancements include:
  • A built-in result handler called a PathCollector that can optimize complex navigations by collecting results into an array instead of iterating over the results as they are found
  • A transaction policy called PreloadCacheForHandlesPolicy that optimizes object access when using methods on the Vertex interface
These methods can lead to a huge performance boost in certain circumstances, as described below.

Path Collector

There are two approaches for handling the results of navigational queries. You can iterate over results as they are encountered, or you can collect the results and examine them when the navigation is complete. The iterative approach is preferred when the graph database is a backend engine to a visualization or web application that presents results to the user in real-time. Alternately, in many analytic applications, the entire result set is preferred over iterative results. If you want the entire result set or if you simply want to optimize the navigation as much as possible, you can use a new type of built-in result handler called a PathCollector.

An iterating built-in or custom result handler will allow you to utilize the default asynchronous behavior of the navigation engine. This will be useful in two cases:

  1. long running navigations in which any results are preferred over the entire set
  2. navigation results are post-processed one at a time as they are returned in Java
If neither of these cases apply to you, then you should consider using the built-in result handler, PathCollector, in your navigations.

A PathCollector allows you to optimize the navigation performance by avoiding iteration and returning the entire set of results at the end of the navigation. The PathCollector class is not intended to be overriden, but instead is meant to be instantiated and used as a NavigationResultHandler in the context of a navigation. The paths can be accessed through the PathCollector#getPaths() method after the navigation has been completed. Alternately, you can get the path count using getPathCount() and/or print the paths using printPaths().

Since more of the qualification of the path steps can now be expressed through the path-match syntax or through filtering using graph views and navigation policies, there may be a reduced demand for iterative results. By using the PathCollector instead of an iterative result handler, you can achieve about a 20-30% improvement in performance depending on the size of results. This can be a very helpful feature for those who are interested in getting the greatest performance out of their navigational queries.

Code Sample 1: Using a PathCollector

// query for start vertex
Vertex startVertex = ...; 
PathCollector pathCollector = new PathCollector();
// create a navigator
Navigator navigator = startVertex.navigate(myView, pathExpr, myPolicies, pathCollector);
// begin navigation
// get path results
Path[] paths = pathCollector.getPaths();

As a way of comparison, with IG 3.4 using the PathCollector result handler to navigate to two or three levels deep using the IMDB data sample, we have measured about a 50% improvement in performance (with 1K and 10K result paths) when compared with the same navigations in IG 3.3.


In InfiniteGraph, we use handles for our vertex and edge objects. This allows us to utilize the underlying C++ cache in the native kernel without unnecessarily filling up the Java cache. It also allows us to optimize the performance of calls like Vertex#getEdges() and Vertex#getNeighbors() on the vertex, for example, in a situation where the user is say only looking for the first edge out of 100 total edges. However, now that we have new qualification methods on the Vertex interface, this existing optimization does not provide the best performance when accessing the entire set of results via a collection.

By using the PreloadCacheForHandlesPolicy on the transaction, we have measured a 10-20% improvement in performance (depending on the result set size) when using these edge discovery methods to access collections of vertex and edge objects. This policy must be explicitly added to the PolicyChain that is used on the transaction. The reason that it is called the PreloadCacheForHandlesPolicy is because it loads all of the vertex and edge objects into cache up front so that when a user calls VertexHandle#getVertex() or EdgeHandle#getEdge(), it is optimized and doesn't cost them any time.

Code Sample 2: Using the PreloadCacheForHandlesPolicy

PolicyChain policies = new PolicyChain(new PreloadCacheForHandlesPolicy());
Transaction tx = graph.beginTransaction(AccessMode.READ, policies);
// query for start vertex
Vertex startVertex = ...;
Collection<EdgeHandle> handles = startVertex.getAllEdges(Call.class.getName(), null);
for(EdgeHandle handle : handles)

Along with the ability to preload the cache for accessing vertex and edge objects, we have exposed new qualification methods on the Vertex interface. These qualifications return collections instead of iterables and so allow fast action to the entire set of results rather than iterating over them one at a time. This is a similar enhancement to the PathCollector. Now that we are exposing new ways to qualify the results at a native level through API, there may not be a need to iterate over the results one at a time because the entire result set is equally important. Here is a graph of a single call to get all edges on a vertex for increasing size of results. By "open", it is referring to whether or not the PreloadCacheForHandlesPolicy is being used on the transaction.

Image 1: Comparing iterative vs collection results
Iterative vs. Collection

As you can see, using the Vertex#getAllEdges(...) method with the PreloadCacheForHandlesPolicy on the transaction shows the most optimal performance.


We are super excited to allow our users to exploit these new features and optimize the performance of graph operations for their applications. As always, if you have any feedback or questions, feel free to check out our google group and for more information about Objectivity or InfiniteGraph, please visit our website or contact Objectivity support at Happy Trails!

Vertex Interface