2010-08-27 11 views
2

J'ai cette classeComment la collecte index à l'aide clé composite

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

et la collection IEnumerable<Item>

Je veux créer des index sur les éléments de cette collection par Touche1, ou par Touche2 ou un composite (Key1 et Key4). Le nombre d'articles dans la collection est d'environ 10 000 ou plus. L'objectif principal est la performance. Plusieurs appelants peuvent avoir plusieurs accès en lecture/écriture. Les collections retournées doivent être protégées (protégées contre les modifications externes). Quelqu'un pourrait-il expliquer une solution, un modèle, quelles classes de collection je dois utiliser pour mettre en œuvre.

J'ai rejeté la variante de l'utilisation des index de la table de base de données, en raison de certaines raisons (performances et ainsi de suite).

Répondre

1

Vous pouvez utiliser deux applications: l'une pour le magasin et l'autre comme une table de recherche à la clé primaire. Comme toutes les mises à jour utilisent la clé primaire qui doit être corrigée, vous pouvez utiliser l'effacement des verrous pour autoriser les écritures simultanées. Sous cette forme, un écrivain doit acquérir un verrou (primaryKey serrures mod #) de sorte qu'une mise à jour/Enlève ne sont pas la course pour une entrée. Et, bien sûr, les lectures n'ont pas besoin d'être verrouillées si les dictionnaires de sauvegarde sont concurrents.

Vous pouvez voir Java version de cette idée qui se cache derrière une façade de mise en cache pour fournir une API agréable. serrure

+0

Merci, Ben. C'est ce que je cherchais. – garik

0

Vous pouvez utiliser LINQ pour retourner une collection indexée par une propriété:

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

Puisque vous avez une petite liste déterministe des clés, vous pouvez mettre en œuvre une classe qui expose les groupes pour lire comme IEnumerable ou List Propriétés. Ajouter une seule méthode pour ajouter des éléments à la collection (pas besoin de méthodes distinctes car ils vont se regrouper pour la lecture en fonction de leur valeur). Utilisez le mot-clé lock dans votre méthode Add pour protéger les collections objet tout en ajoutant.

+0

? pourquoi pas ReaderWriterLockSlim? :) – garik

+0

et pourquoi seulement sur Ajouter (que diriez-vous Get?) – garik

+0

@igor: Utilisez les propriétés groupées pour obtenir. En ce qui concerne votre mécanisme de verrouillage, utilisez tout ce que vous pensez qui fonctionnera le mieux;) –

0

Vous groupe pourrait les éléments à l'aide d'un type anonyme et de créer un dictionnaire avec les groupes:

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

Cependant, les types anonymes ne peuvent être utilisés pour les variables locales (ou des paramètres de méthode générique), donc si vous allez stocker le dictionnaire pour une réutilisation ultérieure, vous aurez besoin d'un type non-anonyme. Ainsi, vous pouvez créer des types pour chaque combinaison de touches possible, ou utilisez la Tuple classe:

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