Database Reference
In-Depth Information
Let's reflect on this implementation. You used a simple algorithm, implementing the solu-
tion in a series of steps: finding all friends, then movies friends have seen, and finally re-
movingthemoviestheuserhasseen.Whileunderstandableandeasytoread,thisapproach
hasonemajorflaw:itusesalotofmemory.Aftereachstep,youstoretheintermediate res-
ultsinthelocalvariableusingJavaheapspace.Thisisn'taproblemwhendealingwithfew
users and movies, but if your data set grows to hundreds of thousands, you'd most likely
getthedreaded
OutOfMemoryError
exceptionwhilerunningtheapplication.That'snot
a concern with this example, because you only have three users and three movies in total.
But now is a good time to look at how Neo4j deals with large traversal results.
4.1.4. Memory usage considerations
You've seen that
Node.getRelationships(...)
methods return an
Iter-
able<Relationship>
object. An
Iterable
interface allows theimplementing class
to be used in Java's
for
loop, which you did a few times in the previous examples. There
are a lot of examples of classes implementing the
Iterable
interface throughout Java
code—for example, all
java.util.Collection
classes, such as
java.util.Set
and
java.util.List
implementations, as well as
java.util.Vector
and
java.util.Stack
. But
Node.getRelationships(...)
methods don't return
any of these well-known classes. They return Neo4j's
Iterable
implementation,
org.neo4j.kernel.impl.util.ArrayIntIterator
, which implements both
Java
Iterable
and
Iterator
interfaces and is a thin wrapper around the
java.util.Iterator
class.Noelementscontainedinthe
Iterable
resultareactu-
ally accessed before you iterate through the result. This implementation is lazily loaded on
first access, and once used, it can't be used again—it becomes spent (this is the expected
behavior for Java iterators).
This is very important when working with the Neo4j Core Java API. The
Iterable
al-
lows Neo4j to return very large result sets, and it's the developer's responsibility to make
sure elements are accessed in the correct manner.Aswe mentioned, if youload a large res-
ult from a Neo4j
Iterable
into a Java
List
or
Set
in your code, you have to be aware
that your code will require a large amount of Java heap memory, and that you're in danger
of generating
OutOfMemoryError
exceptions at runtime. This is why it's a good prac-
tice to use
Iterable
as much as possible in your code, without converting the code to
memory-hungry structures whenever possible.