Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala bug with immutable Map in concurrent program?

I've written a Monte Carlo player for the board game Nine Men's Morris. Everything is basically immutable. The program involves lots of futures (hundreds) and a lot of modifying immutable Maps. Sometimes I get a crash with the following exception:

java.lang.NullPointerException
    at scala.collection.mutable.HashTable$class.elemHashCode(HashTable.scala:154)
    at scala.collection.immutable.HashMap.elemHashCode(HashMap.scala:41)
    at scala.collection.mutable.HashTable$class.findEntry(HashTable.scala:66)
    at scala.collection.immutable.HashMap.findEntry(HashMap.scala:41)
    at scala.collection.immutable.HashMap.undo$1(HashMap.scala:132)
    at scala.collection.immutable.HashMap.undo$1(HashMap.scala:130)
    at scala.collection.immutable.HashMap.makeCopy(HashMap.scala:154)
    at scala.collection.immutable.HashMap.makeCopyIfUpdated(HashMap.scala:161)
    at scala.collection.immutable.HashMap.update(HashMap.scala:66)
    at scala.collection.immutable.Map$class.$plus(Map.scala:66)
    at scala.collection.immutable.HashMap.$plus(HashMap.scala:41)
    at morris.players.MapBasedMorrisBoard.applyMove(MapBasedMorrisBoard.scala:30)
    at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
    at morris.players.MonteCarloPlayer$$anonfun$main$1$$anonfun$apply$1.apply(MonteCarloPlayer.scala:77)
    at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:45)
    at scala.actors.Futures$$anonfun$2$$anonfun$apply$1.apply(Future.scala:44)
    at scala.actors.Reaction.run(Reaction.scala:78)
    at scala.actors.FJTask$Wrap.run(Unknown Source)
    at scala.actors.FJTaskRunner.scanWhileIdling(Unknown Source)
    at scala.actors.FJTaskRunner.run(Unknown Source)

I'm only using immutable Maps, so I wonder whether this is caused by a bug in my own code or maybe a bug in the scala library. When looking at the trace you can see, that there are calls to mutable HashTable further down the stack. Maybe this is causing problems with concurrency?

The code inside my program, where the exception occurs is just adding another collection to an immutable Map:

myMap ++ (someInteger -> aValue)

Edit: The same program without concurrency runs flawlessly.

like image 566
ziggystar Avatar asked Nov 05 '22 18:11

ziggystar


1 Answers

I've filed a bug report for the Scala-library. As it turns out this is a known problem. The implementation of HashMap (which is used for as the standard Map type in Scala) is not suited to be used in concurrent programs since behind the scenes, it uses mutable types. This can also be observed in the stack-trace. The Scala people are hoping to replace the implementation in 2.8.

As a work-around it is suggested to use TreeHashMap, which is truly immutable. I've done this and can confirm that it works.

Link to original bug report

like image 93
ziggystar Avatar answered Dec 05 '22 07:12

ziggystar