Threadsafe可变集合,快速元素删除和随机获取

时间:2014-11-05 13:39:36

标签: multithreading scala collections

我需要一个包含三个操作的线程安全数据结构:remove,getRandom,reset。 我现在只有两个想法。

首先:seq in syncronized var。

val all: Array[String] =  ... //all possible.
var current: Array[String] = Array.empty[String]

def getRandom(): = {
  val currentAvailable = current
  currentAvailable(Random.nextInt(currentAvailable.length))
}

def remove(s: String) = {
  this.syncronized {
     current = current diff Seq(s)
  }
}

def reset(s: String) = {
  this.syncronized {
     current = all
  }
}

第二: 保持一些Map [String,Boolean],当元素当前存在时,bool为true。主要问题是制作一个快速的getRandom方法(在最坏的情况下不是O(n))。

有没有更好的方法来实现这个?

2 个答案:

答案 0 :(得分:6)

Scala's Trie是一种无锁数据结构,支持快照(又名您的currentAvailable)和快速删除

答案 1 :(得分:3)

由于我不是Scala专家所以这个答案是通用的,我使用的是Java编码。

简而言之,答案是肯定的。 如果您使用地图,例如:

Map<Integer,String> map=new HashMap<Integer,String>();  //is used to get random in constant time
Map<String,Integer> map1=new HashMap<String,Integer>();  //is used to remove in constant time

存储日期, 主要思想是将密钥(在本例中为整数)保持同步为{1 ... map of map} 例如,为了填充这个结构,你需要这样的东西:

int counter=0; //this is a global variable
for(/* all your string (s) in all */ ){
  map.put(counter++, s);
}   
//then , if you want the removal to be in constant time you need to fill the second map
for(Entry e : map.EntrySet(){
  map1.put(e.getValue(),e.getKey());
}

上面的代码是初始化。每次你想要设置你需要做的事情

然后你可以用O(1)复杂度

来实现随机值
String getRandom(){
int i; /*random number between 0 to counter*/
return map.get(i);
}

现在删除你使用map1的东西,以恒定的时间O(1);

void remove(String s){
   if(!map1.containsKey(s))
      return; //s doesn't exists

   String val=map.get(counter);  //value of the last 
   map.remove(counter)           //removing the last element
   int thisCounter= map1.get(s); //pointer to this
   map1.remove(s);               // remove from map1
   map.remove(counter);          //remove from map
   map1.put(thisCounter,val);    //the val of the last element with the current pointer
   counter--;                    //reducing the counter by one
}

显然,这里的主要问题是确保同步。但是通过仔细分析代码,你应该能够做到这一点。