This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Problem with Multics.scala in Beginning Scala book.

3 replies
Amador Cuenca
Joined: 2010-08-12,
User offline. Last seen 1 year 30 weeks ago.
Hi all,
I'm reading the Beginning Scala book(Nice book, well explained) and at this moment I'm stuck in the section "Concurrency Without Synchronization" with this exercise:
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.TreeHashMap

object Multics {
  type MT = Map[String, Int]

  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
  val clashCnt = new AtomicLong

  def main(argv: Array[String]) {
    runThread {
      repeatEvery(1000) {
        println("Clash Count: "+clashCnt+" Total: "+
                info.get.foldLeft(0)(_ + _._2))
      } }
    for (i <- 1 to 2000) runThread {
      var cnt = 0
      val ran = new Random
      val name = "K"+i
      doSet(info){old => old + (name -> 0)}
      repeatEvery(ran.nextInt(100)) {
        doSet(info){old => old + (name -> (old(name) + 1))}
        cnt = cnt + 1
        if (cnt != info.get()(name))
          throw new Exception("Thread: "+name+" failed")
      } }
  }

  def runThread(f: => Unit) =
    (new Thread(new Runnable {def run(): Unit = f})).start
  def doSet[T](atom: AtomR[T])(update: T => T) {
    val old = atom.get
    if (atom.compareAndSet(old, update(old))) ()
    else {
      clashCnt.incrementAndGet
      doSet(atom)(update)
    }
  }

  def repeatEvery(len: => Int)(body: => Unit): Unit = {
    try {
      while(true) {
        Thread.sleep(len)
        body
      }
    } catch {
      case e => e.printStackTrace; System.exit(1)
    }
  }
  
}

The following exception appears:
error: not found: value TreeHashMap
  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
one error found

I'm using Netbeans 6.9.1 + Scala plugin over Win 7 x64.
I'll really appreciate if you can help me guys.
Regards,
Amador Cuenca
Joined: 2010-08-12,
User offline. Last seen 1 year 30 weeks ago.
Re: Problem with Multics.scala in Beginning Scala book.
I've noticed that the TreeHashMap namespace is empty, I think that library is missing in Scala 2.8.0, so I've decided to change the TreeHashMap type to TreeMap. It works, but I wonder if on this way the results (and perfomance) are the same?
Regards,

--
TSU. Amador Cuenca
Sylvain HENRY
Joined: 2009-05-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Problem with Multics.scala in Beginning Scala book.
Hi,
It seems like TreeHashMap isn't in 2.8: http://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_0_final/src/library/scala/collection/immutable/TreeHashMap.scala

Try replacing TreeHashMap by HashMap:
import scala.collection.immutable.{HashMap => TreeHashMap}

Cheers
Sylvain


Le 03/11/2010 17:13, Amador Antonio Cuenca a écrit :
TT [at] mail [dot] gmail [dot] com" type="cite">Hi all,
I'm reading the Beginning Scala book(Nice book, well explained) and at this moment I'm stuck in the section "Concurrency Without Synchronization" with this exercise:
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.TreeHashMap

object Multics {
  type MT = Map[String, Int]

  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
  val clashCnt = new AtomicLong

  def main(argv: Array[String]) {
    runThread {
      repeatEvery(1000) {
        println("Clash Count: "+clashCnt+" Total: "+
                info.get.foldLeft(0)(_ + _._2))
      } }
    for (i <- 1 to 2000) runThread {
      var cnt = 0
      val ran = new Random
      val name = "K"+i
      doSet(info){old => old + (name -> 0)}
      repeatEvery(ran.nextInt(100)) {
        doSet(info){old => old + (name -> (old(name) + 1))}
        cnt = cnt + 1
        if (cnt != info.get()(name))
          throw new Exception("Thread: "+name+" failed")
      } }
  }

  def runThread(f: => Unit) =
    (new Thread(new Runnable {def run(): Unit = f})).start
  def doSet[T](atom: AtomR[T])(update: T => T) {
    val old = atom.get
    if (atom.compareAndSet(old, update(old))) ()
    else {
      clashCnt.incrementAndGet
      doSet(atom)(update)
    }
  }

  def repeatEvery(len: => Int)(body: => Unit): Unit = {
    try {
      while(true) {
        Thread.sleep(len)
        body
      }
    } catch {
      case e => e.printStackTrace; System.exit(1)
    }
  }
  
}

The following exception appears:
error: not found: value TreeHashMap
  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
one error found

I'm using Netbeans 6.9.1 + Scala plugin over Win 7 x64.
I'll really appreciate if you can help me guys.
Regards, --
TSU. Amador Cuenca


-- 
Sylvain HENRY
PhD Student INRIA/LaBRI RunTime Team
Tel: +33 (0)6-70-94-86-76
http://hsyl20.fr
David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Problem with Multics.scala in Beginning Scala book.
Howdy,

Scala 2.7.3 had a problem with scala.collection.immutable.HashMap... it wasn't threadsafe, so I used TreeHashMap.  Turns out it was silently removed from the Scala distribution in 2.8.0.  See https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src///library/scala/collection/immutable/TreeHashMap.scala

You can subsitution HashMap for TreeHashMap.  I'm enclosing a working version of the program with this note.

Thanks,

David

On Wed, Nov 3, 2010 at 9:13 AM, Amador Antonio Cuenca <sphi02ac [at] gmail [dot] com> wrote:
Hi all,
I'm reading the Beginning Scala book(Nice book, well explained) and at this moment I'm stuck in the section "Concurrency Without Synchronization" with this exercise:
import java.util.concurrent.atomic.{AtomicReference => AtomR, AtomicLong}
import java.util.Random
import scala.collection.immutable.TreeHashMap

object Multics {
  type MT = Map[String, Int]

  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
  val clashCnt = new AtomicLong

  def main(argv: Array[String]) {
    runThread {
      repeatEvery(1000) {
        println("Clash Count: "+clashCnt+" Total: "+
                info.get.foldLeft(0)(_ + _._2))
      } }
    for (i <- 1 to 2000) runThread {
      var cnt = 0
      val ran = new Random
      val name = "K"+i
      doSet(info){old => old + (name -> 0)}
      repeatEvery(ran.nextInt(100)) {
        doSet(info){old => old + (name -> (old(name) + 1))}
        cnt = cnt + 1
        if (cnt != info.get()(name))
          throw new Exception("Thread: "+name+" failed")
      } }
  }

  def runThread(f: => Unit) =
    (new Thread(new Runnable {def run(): Unit = f})).start
  def doSet[T](atom: AtomR[T])(update: T => T) {
    val old = atom.get
    if (atom.compareAndSet(old, update(old))) ()
    else {
      clashCnt.incrementAndGet
      doSet(atom)(update)
    }
  }

  def repeatEvery(len: => Int)(body: => Unit): Unit = {
    try {
      while(true) {
        Thread.sleep(len)
        body
      }
    } catch {
      case e => e.printStackTrace; System.exit(1)
    }
  }
  
}

The following exception appears:
error: not found: value TreeHashMap
  val info: AtomR[MT] = new AtomR(TreeHashMap.empty)
one error found

I'm using Netbeans 6.9.1 + Scala plugin over Win 7 x64.
I'll really appreciate if you can help me guys.
Regards,

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland