2010-08-27 77 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());