I'm porting an algorithm from Java to Scala that does a range search on a VP Tree. Briefly, the nodes in the tree have coordinates in space and a radius: nodes within that radius can be found on the left subtree, whilst nodes outside that radius are found on the right subtree. A range search attempts to find all objects in the tree within a specified distance to a query object.
In Java I passed the function an arraylist in which it accumulated results, possibly recursing down one of either or both subtrees. Here's a straight port into Scala:
def search(node: VPNode[TPoint, TObject], query: TPoint, radius: Double,
results: collection.mutable.Set[TObject]) {
var dist = distance(query, node.point)
if (dist < radius)
results += node.obj
if (node.left != null && dist <= radius + node.radius)
search(node.left, query, radius, results)
if (node.right != null && dist >= radius + node.radius)
search(node.right, query, radius, results)
}
Scala's default collection types are immutable, and I was thinking it was a bit annoying having to type collection.mutable.
all the time, so I started looking into it. It seems to be recommended that using the immutable collections are nearly always fine: I'm using this code to do millions of lookups though, and it seems to me that copying and concatenating the results array would slow it down.
Answers like this for example suggest that the problem needs to be approached more 'functionally'.
So, what should I do to solve this problem in a more Scala-esque fashion? Ideally I'd like it to be as fast as the Java version, but I'm interested in solutions regardless (and can always profile them to see if it makes much difference).
Note, I only just started learning Scala (figured I may as well cut my teeth on something useful) but I'm not new to functional programming, having used Haskell before (although I don't think I'm that good at it!).
ArrayList
in Java but aSet
in Scala? It would be more similar to useArrayBuffer
. – huynhjl