Scala Programming Language
  1. Scala Programming Language
  2. SI-7498

ParTrieMap iteration fails with ClassCastException

    Details

      Description

      Performing a foreach on a ParTrieMap instance sometimes causes the following ClassCastException to be thrown:

      java.lang.ClassCastException: scala.collection.LinearSeqLike$$anon$1 cannot be cast to scala.collection.parallel.IterableSplitter
              at scala.collection.parallel.IterableSplitter$$anonfun$splitWithSignalling$1.apply(RemainsIterator.scala:398)
              at scala.collection.immutable.List.foreach(List.scala:309)
              at scala.collection.parallel.IterableSplitter$class.splitWithSignalling(RemainsIterator.scala:398)
              at scala.collection.parallel.mutable.ParTrieMapSplitter.splitWithSignalling(ParTrieMap.scala:123)
              at scala.collection.parallel.ParIterableLike$Accessor$class.split(ParIterableLike.scala:905)
              at scala.collection.parallel.ParIterableLike$Foreach.split(ParIterableLike.scala:972)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.split(Tasks.scala:516)
              at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.spawnSubtasks(Tasks.scala:197)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.spawnSubtasks(Tasks.scala:514)
              at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.internal(Tasks.scala:170)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.internal(Tasks.scala:514)
              at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.compute(Tasks.scala:162)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:514)
              at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:160)
              at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
              at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runSubtask(ForkJoinPool.java:994)
              at scala.concurrent.forkjoin.ForkJoinPool.tryHelpStealer(ForkJoinPool.java:1702)
              at scala.concurrent.forkjoin.ForkJoinPool.awaitJoin(ForkJoinPool.java:1830)
              at scala.concurrent.forkjoin.ForkJoinTask.doJoin(ForkJoinTask.java:344)
              at scala.concurrent.forkjoin.ForkJoinTask.join(ForkJoinTask.java:648)
              at scala.collection.parallel.ForkJoinTasks$WrappedTask$class.sync(Tasks.scala:444)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.sync(Tasks.scala:514)
              at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.internal(Tasks.scala:187)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.internal(Tasks.scala:514)
              at scala.collection.parallel.AdaptiveWorkStealingTasks$WrappedTask$class.compute(Tasks.scala:162)
              at scala.collection.parallel.AdaptiveWorkStealingForkJoinTasks$WrappedTask.compute(Tasks.scala:514)
              at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:160)
              at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
              at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
              at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
              at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)
      

        Activity

        Hide
        William Robertson added a comment -

        I did some instrumentation of the code for ParTrieMap, and it looks like subiter can refer to a TrieMap iterator rather than a ParTrieMap iterator (see around TrieMap.scala:1018 in 2.10.1). A possible fix would be to make sure that subiter is always assigned the result of newIterator which is overloaded in ParTrieMap, although I'm not familiar enough with the codebase to know whether that's the right solution.

        Show
        William Robertson added a comment - I did some instrumentation of the code for ParTrieMap, and it looks like subiter can refer to a TrieMap iterator rather than a ParTrieMap iterator (see around TrieMap.scala:1018 in 2.10.1). A possible fix would be to make sure that subiter is always assigned the result of newIterator which is overloaded in ParTrieMap, although I'm not familiar enough with the codebase to know whether that's the right solution.
        Hide
        Jason Zaugg added a comment -

        Alex: could you please take a look at this one?

        Show
        Jason Zaugg added a comment - Alex: could you please take a look at this one?
        Hide
        Aleksandar Prokopec added a comment -

        Sure. William's analysis is correct - this is due to a cast in the `ParTrieMap` of the return value of `subdivide` from `TrieMap`, that internally does not call `newIterator` when it deals with `LNode`s. I will fix this.

        Show
        Aleksandar Prokopec added a comment - Sure. William's analysis is correct - this is due to a cast in the `ParTrieMap` of the return value of `subdivide` from `TrieMap`, that internally does not call `newIterator` when it deals with `LNode`s. I will fix this.
        Hide
        Aleksandar Prokopec added a comment -
        Show
        Aleksandar Prokopec added a comment - Should do the trick: https://github.com/scala/scala/pull/2610
        Hide
        James Iry added a comment -

        Pull request hasn't been merged. We'll close when it has.

        Show
        James Iry added a comment - Pull request hasn't been merged. We'll close when it has.
        Hide
        Jason Zaugg added a comment -

        Reopening for the backport for 2.10.3

        https://github.com/scala/scala/pull/2644

        Show
        Jason Zaugg added a comment - Reopening for the backport for 2.10.3 https://github.com/scala/scala/pull/2644

          People

          • Assignee:
            Aleksandar Prokopec
            Reporter:
            William Robertson
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development