c#,multikey,dictionary

Erhan 8/7/2016 0

This code shows how to create a multikey dictionaryin c#

C#
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Aron.Weiler
{
                /// <summary>
                /// Multi-Key Dictionary Class
                /// </summary>
                /// <typeparam name="V">Value Type</typeparam>
                /// <typeparam name="K">Primary Key Type</typeparam>
                /// <typeparam name="L">Sub Key Type</typeparam>
                public class MultiKeyDictionary<K, L, V> : Dictionary<K, V>
                {
                                internal readonly Dictionary<L, K> subDictionary = new Dictionary<L, K>();
                                internal readonly Dictionary<K, L> primaryToSubkeyMapping = new Dictionary<K, L>();

                                readonly object lockBase = new object();
                                readonly object lockSub = new object();

                                public V this[L subKey]
                                {
                                                get
                                                {
                                                                V item;
                                                                if (TryGetValue(subKey, out item))
                                                                                return item;

                                                                throw new KeyNotFoundException("sub key not found: "   subKey.ToString());
                                                }
                                }

                                public new V this[K primaryKey]
                                {
                                                get
                                                {
                                                                V item;
                                                                if (TryGetValue(primaryKey, out item))
                                                                                return item;

                                                                throw new KeyNotFoundException("primary key not found: "   primaryKey.ToString());
                                                }
                                }

                                public void Associate(L subKey, K primaryKey)
                                {
                                                lock (lockBase)
                                                {
                                                                if (!base.ContainsKey(primaryKey))
                                                                                throw new KeyNotFoundException(string.Format("The base dictionary does not contain the key '{0}'", primaryKey));

                                                                lock (lockSub)
                                                                {
                                                                                if (subDictionary.ContainsKey(subKey))
                                                                                {
                                                                                                subDictionary[subKey] = primaryKey;
                                                                                                primaryToSubkeyMapping[primaryKey] = subKey;
                                                                                }
                                                                                else
                                                                                {
                                                                                                subDictionary.Add(subKey, primaryKey);
                                                                                                primaryToSubkeyMapping.Add(primaryKey, subKey);
                                                                                }                                                                              
                                                                }
                                                }
                                }

                                public bool TryGetValue(L subKey, out V val)
                                {
                                                val = default(V);

                                                lock (lockSub)
                                                {
                                                                K ep;
                                                                if (subDictionary.TryGetValue(subKey, out ep))
                                                                {
                                                                                if (!TryGetValue(ep, out val))
                                                                                {
                                                                                                return false;
                                                                                }
                                                                }
                                                                else
                                                                {
                                                                                return false;
                                                                }
                                                }

                                                return true;
                                }

                                public new bool TryGetValue(K primaryKey, out V val)
                                {
                                                lock (lockBase)
                                                {
                                                                if (!base.TryGetValue(primaryKey, out val))
                                                                {
                                                                                return false;
                                                                }
                                                }

                                                return true;
                                }

                                public bool ContainsKey(L subKey)
                                {
                                                V val;

                                                return TryGetValue(subKey, out val);
                                }

                                public new bool ContainsKey(K primaryKey)
                                {
                                                V val;

                                                return TryGetValue(primaryKey, out val);
                                }

                                public new void Remove(K primaryKey)
                                {                              
                                                lock(lockSub)
                                                {
                                                                subDictionary.Remove(primaryToSubkeyMapping[primaryKey]);
                                                                primaryToSubkeyMapping.Remove(primaryKey);
                                                }

                                                lock (lockBase)
                                                                base.Remove(primaryKey);
                                }

                                public void Remove(L subKey)
                                {
                                                lock (lockSub)
                                                {
                                                                lock (lockBase)
                                                                                base.Remove(subDictionary[subKey]);

                                                                primaryToSubkeyMapping.Remove(subDictionary[subKey]);
                                                                subDictionary.Remove(subKey);
                                                }                                              
                                }

                                public new void Add(K primaryKey, V val)
                                {
                                                lock (lockBase)
                                                                base.Add(primaryKey, val);
                                }

                                public void Add(K primaryKey, L subKey, V val)
                                {
                                                lock (lockBase)
                                                                base.Add(primaryKey, val);

                                                Associate(subKey, primaryKey);
                                }

                                public V[] CloneValues()
                                {
                                                lock (lockBase)
                                                {
                                                                V[] values = new V[Values.Count];

                                                                Values.CopyTo(values, 0);

                                                                return values;
                                                }
                                }

                                public K[] ClonePrimaryKeys()
                                {
                                                lock (lockBase)
                                                {
                                                                K[] values = new K[Keys.Count];

                                                                Keys.CopyTo(values, 0);

                                                                return values;
                                                }
                                }

                                public L[] CloneSubKeys()
                                {
                                                lock (lockBase)
                                                {
                                                                L[] values = new L[subDictionary.Keys.Count];

                                                                subDictionary.Keys.CopyTo(values, 0);

                                                                return values;
                                                }
                                }
                }
}
 

Report Bug

Please Login to Report Bug

Reported Bugs

Comments

Please Login to Comment

Comments