2010-08-27 54 views
2

指数集合有这个类我如何通过使用组合键

public class Item 
{ 
    public int UniqueKey; 
    public int Key1; 
    public int Key2; 
    public int Key3; 
    public int Key4; 
    public string Value; 
} 

和收集IEnumerable<Item>

我想键1,或键2创建这个集合的项目指标,或复合一个(Key1和Key4)。收集的物品数量约为10 000个或更多。主要目标是表现。多个呼叫者可以有多个读/写访问权限。返回的集合应该被保护(不受外部修改)。有人可以解释任何解决方案,模式,我必须使用哪些集合类来实现。

由于某些原因(性能等),我拒绝了使用数据库表索引的变体。

回答

1

你可以用两个映射:一个用于存储和一个查找表的主键。由于所有更新都使用应修复的主键,因此可以使用锁定剥离来允许并发写入。在这种形式下,作者必须获得一个锁(primaryKey mod#locks),以便更新/删除不会争用条目。当然,如果支持字典是并发的,则读取操作不需要锁定。

你可以看到这个想法里面藏着一个缓存门面背后提供了一个很好的API的一个Java version

+0

谢谢,本。这正是我所期待的。 – garik 2010-08-28 19:45:40

0

您可以使用LINQ返回的属性索引的集合:

var key1 = from i in Items 
      group i by i.Key1 into g 
      select g; 

var key2 = from i in Items 
      group i by i.Key2 into g 
      select g; 
... 

既然你有钥匙的小,确定性的列表,你可以实现一个公开组进行解读为IEnumerableList类属性。添加单个方法以将项目添加到集合中(不需要单独的方法,因为它们将根据它们的值进行分组以读取。)使用Add方法中的lock关键字在添加时保护项目集合。

+0

锁?为什么不用ReaderWriterLockSlim? :) – garik 2010-08-27 16:29:55

+0

和为什么只有在添加(获取?) – garik 2010-08-27 16:35:42

+0

@igor:使用Get的分组属性。至于你的锁定机制,请使用你认为最好的方法;) – 2010-08-27 17:16:25

0

你可以组使用匿名类型,并与集团的字典中的项目:

var grouped = items.GroupBy(item => new { item.Key1, item.Key4 }) 
        .ToDictionary(g => g.Key, g => g.ToList()); 

然而,匿名类型只能用于局部变量(或泛型方法参数),所以如果你”要重新存储字典供以后重新使用,您需要一个非匿名类型。所以,你可以创建类型为每个可能的组合键,或使用Tuple类:

Dictionary<Tuple<int, int>, Item> grouped = 
       items.GroupBy(item => Tuple.Create(item.Key1, item.Key2)) 
        .ToDictionary(g => g.Key, g => g.ToList());