Question

What I want to do is to start out using some implementation of a Map and accumulate data into it by iterating over a parallel collection. Keys can "overlap" between threads as the keys are probabilistically generated (related to random number generation).

Ex. Thread 1 wants to add key = A value = 1 to the map. If it already exists, add 1 to the existing value (since value is 1) - if not, create the mapping. Meanwhile, another thread has key = A and value = 2, and wants to do the same thing.

Is there a way to do this without creating an entire Actor system?

ConcurrentHashMap from Java's library seems to look interesting, but the "weakly consistent" iterators are bothering me regarding safety of upating the map across threads..

Was it helpful?

Solution

That's a very trivial thing to do without Actors.

class CountMap[K <: AnyRef](mapSize: Int = 16) extends ConcurrentHashMap[K, AtomicLong](mapSize) {
  def addCount(key: K): Long = (get(key) match { // Check value for key
    case null =>  // If not mapped yet
      val al = new AtomicLong(0) // Create a new memory slot to keep the count in that is thread safe
      putIfAbsent(key, al) match { // Try to put our memory slot in atomically
        case null => al // If we succeeded then our memory slot should be used
        case some => some // if there already was a memory slot, use that one
      }
    case some => some // If there already was a memory slot, use that one
    }).incrementAndGet() // increment and get the current value of the slot associated with the given key

  def getCount(key: K): Long = get(key) match { // get the memory slot associated with the key
    case null => 0L // if none, say it's 0
    case some => some.get() // if some get its value
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top