TrieMap.getOrElseUpdate

302 views
Skip to first unread message

Mikael Ståldal

unread,
Sep 17, 2014, 9:38:37 AM9/17/14
to scala...@googlegroups.com
How does the getOrElseUpdate method from scala.collection.mutable.MapLike work on a TrieMap?

Will it be properly thread-safe and atomic? Will it protect against race conditions, so that for any given key only one value is ever added to the map (given that no other mutating method is used)?

Sonnenschein

unread,
Sep 17, 2014, 10:25:45 AM9/17/14
to scala...@googlegroups.com
Yes, it will. Scaladoc states:
"A concurrent hash-trie or TrieMap is a concurrent thread-safe lock-free implementation of a hash array mapped trie. It is used to implement the concurrent map abstraction. It has particularly scalable concurrent insert and remove operations and is memory-efficient. It supports O(1), atomic, lock-free snapshots which are used to implement linearizable lock-free size, iterator and clear operations."

Tim Underwood

unread,
Sep 17, 2014, 11:08:07 AM9/17/14
to scala...@googlegroups.com
Are you sure about that?  According to the Scaladocs for scala.collection.concurrent.TrieMap[1], the implementation for getOrElseUpdate comes from scala.collection.mutable.MapLike[2] which looks like:

def getOrElseUpdate(key: A, op: => B): B =
  get(key) match {
    case Some(v) => v
    case None => val d = op; this(key) = d; d
  }

That doesn't look very thread safe to me.

Mikael Ståldal

unread,
Sep 17, 2014, 11:23:54 AM9/17/14
to scala...@googlegroups.com
That's what I suspected as well.

Is there any way to accomplish this?

Will this work?

def getOrElseUpdate(key: A, op: => B): B = get(key) match {    
 
case Some(v) => v    
 
case None =>
    val d
=
op
   
putIfAbsent(key, d).getOrElse(d)  
}  

Nils Kilden-Pedersen

unread,
Sep 17, 2014, 11:26:41 AM9/17/14
to Tim Underwood, scala-user

On Wed, Sep 17, 2014 at 10:08 AM, Tim Underwood <timund...@gmail.com> wrote:

Are you sure about that?  According to the Scaladocs for scala.collection.concurrent.TrieMap[1], the implementation for getOrElseUpdate comes from scala.collection.mutable.MapLike[2] which looks like:

def getOrElseUpdate(key: A, op: => B): B =
  get(key) match {
    case Some(v) => v
    case None => val d = op; this(key) = d; d
  }

That doesn't look very thread safe to me.

It isn’t. getOrElseUpdate is not a concurrent method. Use putIfAbsent for something like this.


[2] - https://github.com/scala/scala/blob/v2.11.2/src/library/scala/collection/mutable/MapLike.scala#L185



On Wednesday, September 17, 2014 7:25:45 AM UTC-7, Sonnenschein wrote:
Yes, it will. Scaladoc states:
"A concurrent hash-trie or TrieMap is a concurrent thread-safe lock-free implementation of a hash array mapped trie. It is used to implement the concurrent map abstraction. It has particularly scalable concurrent insert and remove operations and is memory-efficient. It supports O(1), atomic, lock-free snapshots which are used to implement linearizable lock-free size, iterator and clear operations."

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tim Underwood

unread,
Sep 17, 2014, 12:32:59 PM9/17/14
to scala...@googlegroups.com
I've used patterns similar to this in a rich wrapper over Java's ConcurrentHashMap to accomplish what you are trying to do when I want to minimize unnecessary evaluations of the op parameter
but when it's okay if op is evaluated and then doesn't get stored in the map.

-Tim

Jason Zaugg

unread,
Sep 17, 2014, 8:35:21 PM9/17/14
to Mikael Ståldal, scala-user
On Wed, Sep 17, 2014 at 11:38 PM, Mikael Ståldal <m...@appearnetworks.com> wrote:
How does the getOrElseUpdate method from scala.collection.mutable.MapLike work on a TrieMap?

Will it be properly thread-safe and atomic? Will it protect against race conditions, so that for any given key only one value is ever added to the map (given that no other mutating method is used)?

There is an interesting discussion about this method in SI-7943

-jason

Reply all
Reply to author
Forward
0 new messages