2014-11-03 22 views
1

什麼是合併兩個併發地圖的最佳方式。如何合併collection.concurrent.Map

這裏是我當前的IMPL:

private def merge[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B]) : concurrent.Map[A, B] = { 
    val mergedMap = map1 ++ map2 
    val concurrentMap = new TrieMap[A, B]() 
    mergedMap.foreach {case (k, v) => concurrentMap.put(k, v)} 
    concurrentMap 
} 

回答

2

你要照顧的競爭條件在地圖的訪問。在你的代碼中,當你合併這兩個地圖並且它們被同時修改時,你可能會錯過元素甚至是「脫離邊緣」。

我提出以下幾點建議(但需要更嚴格的打字TrieMap):

private def merge[A, B](map1: TrieMap[A, B], map2: TrieMap[A, B]) : TrieMap[A, B] = { 
    val res = map1.snapshot() 
    res ++= map2.snapshot() 
    res 
} 

(沒有測試這一點,但我希望這個想法是清楚的)。

如果你不關心這個方法的併發訪問,你也可以只是簡單的用一個建設者:

private def merge[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B]) : concurrent.Map[A, B] = { 
    val builder = TrieMap.newBuilder[A, B] 
    map1.foreach(builder += _) 
    map2.foreach(builder += _) 
    builder.result() 
} 

這將避免產生任何中間結構。