如何使用组合键索引集合

发布于 2024-09-16 10:20:06 字数 488 浏览 7 评论 0原文

我有这个类

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

和集合 IEnumerable

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

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

I have this class

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

and the collection IEnumerable<Item>

I want to create indexes on items of this collection by Key1, or by Key2, or composite one (Key1 and Key4). The number of items in collection is about 10 000 or more. The main goal is performance. Multiple callers can have many read / one write access. Returned collections should be guarded (protected from external modification). Could somebody explain any solution, pattern, what collection classes I have to use to implement.

I have rejected the variant of using database table's indexes, because of some reasons (performance and so on).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倦话 2024-09-23 10:20:06

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

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

You can use two mappings: one for the store and one as a lookup table to the primary key. As all updates use the primary key which should be fixed, you can use lock stripping to allow concurrent writes. In this form a writer must acquire a lock (primaryKey mod # locks) so that an updates/removes do not race for an entry. And, of course, reads don't need locking if the backing dictionaries are concurrent.

You can see a Java version of this idea which was hidden behind a caching facade to provide a nice API.

冷︶言冷语的世界 2024-09-23 10:20:06

您可以使用 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 关键字来保护项目集合添加时。

You can use LINQ to return a collection indexed by a property:

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;
...

Since you have a small, deterministic list of keys, you could implement a class that exposes the groups for read as IEnumerable or List properties. Add a single method for adding items to the collection (no need for separate methods since they'll get grouped for reading based on their value.) Use the lock keyword in your Add method to protect the item collections while adding.

橘亓 2024-09-23 10:20:06

您可以使用匿名类型对项目进行分组,并使用这些组创建一个字典:

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());

You could group the items using an anonymous type and create a dictionary with the groups:

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

However, anonymous types can only be used for local variables (or generic method parameters), so if you're going to store the dictionary for later reuse, you will need a non-anonymous type. So you can either create types for each possible key combination, or use the Tuple class :

Dictionary<Tuple<int, int>, Item> grouped =
              items.GroupBy(item => Tuple.Create(item.Key1, item.Key2))
                   .ToDictionary(g => g.Key, g => g.ToList());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文