我有这个班级
public class Item
{
public int UniqueKey;
public int Key1;
public int Key2;
public int Key3;
public int Key4;
public string Value;
}
和集合IEnumerable<Item>
我想通过 Key1 或 Key2 或复合一个( Key1和Key4 )为此集合的项目创建索引。收集的物品数量约为10 000或更多。主要目标是表现。多个呼叫者可以具有许多读/写访问权限。应保护退回的集合(防止外部修改)。有人可以解释任何解决方案,模式,我必须用来实现的集合类。
由于某些原因(性能等),我拒绝使用数据库表索引的变体。
答案 0 :(得分:1)
您可以使用两个映射:一个用于存储,另一个用作主键的查找表。由于所有更新都使用应修复的主键,因此可以使用锁定剥离来允许并发写入。在这种形式下,编写者必须获取一个锁(primaryKey mod#locks),以便更新/删除不会竞争条目。当然,如果后备字典是并发的,则读取不需要锁定。
你可以看到这个想法的Java version隐藏在缓存外观背后,以提供一个很好的API。
答案 1 :(得分: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;
...
由于您有一个小的,确定性的键列表,您可以实现一个类,该类公开组以供读取IEnumerable
或List
属性。添加一个方法可以将项添加到集合中(不需要单独的方法,因为它们将根据其值进行分组以进行读取。)使用Add方法中的lock
关键字在添加时保护项集合。
答案 2 :(得分: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());