2

我有这门课

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

和收藏IEnumerable<Item>

我想通过Key1Key2或复合项(Key1 和 Key4)为此集合的项目创建索引。收集的项目数量约为 10 000 件或更多。主要目标是性能。多个调用者可以有许多读/一写访问。返回的集合应该受到保护(防止外部修改)。有人可以解释任何解决方案、模式、我必须使用哪些集合类来实现。

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

4

3 回答 3

1

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

你可以看到这个想法的 Java版本,它隐藏在缓存外观后面,以提供一个很好的 API。

于 2010-08-28T01:20:19.523 回答
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属性的类。添加一个方法来将项目添加到集合中(不需要单独的方法,因为它们会根据它们的值被分组以供读取。)在添加时使用lockAdd 方法中的关键字来保护项目集合。

于 2010-08-27T16:08:40.103 回答
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());
于 2010-08-27T17:14:08.853 回答