Пример #1
0
        /// <summary>
        /// Attempts to add the <paramref name="value"/> with the keys
        /// <paramref name="key1"/>, <paramref name="key2"/>.
        /// </summary>
        /// <param name="key1">The <typeparamref name="TKey1"/> which
        /// is the first key of the <paramref name="value"/>
        ///  to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/>.</param>
        /// <param name="key2">The <typeparamref name="TKey2"/> which
        /// is the second key of the <paramref name="value"/>
        ///  to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/>.</param>
        /// <param name="value">The <typeparamref name="TValue"/> to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/></param>
        public bool TryAdd(TKey1 key1, TKey2 key2, TValue value)
        {
            // Declare the locals relative to the different levels.
            LevelOne levelOne;

            /* ------------------------------------------------------\
            |  Check each level individually, if the key set is      |
            |  already present, indicate that nothing was done, and  |
            |  yield; otherwise note that it was inserted.           |
            \------------------------------------------------------ */
            if (((object)(key1)) == null)
            {
                throw new ArgumentNullException("key1");
            }
            bool topLevelLock = false;

            Monitor.Enter(this.dataCopy, ref topLevelLock);
            if (this.dataCopy.TryGetValue(key1, out levelOne))
            {
                if (topLevelLock)
                {
                    Monitor.Exit(this.dataCopy);
                }
                if (((object)(key2)) == null)
                {
                    throw new ArgumentNullException("key2");
                }
                bool levelOneLock = false;
                Monitor.Enter(levelOne, ref levelOneLock);
                if (levelOne.ContainsKey(key2))
                {
                    if (levelOneLock)
                    {
                        Monitor.Exit(levelOne);
                    }
                    return(false);
                }
                else
                {
                    levelOne.Add(key2, value);
                    if (levelOneLock)
                    {
                        Monitor.Exit(levelOne);
                    }
                }
            }
            else
            {
                this.dataCopy.Add(key1, (levelOne = new LevelOne()));
                levelOne.Add(key2, value);
                if (topLevelLock)
                {
                    Monitor.Exit(this.dataCopy);
                }
            }
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Adds the <paramref name="value"/> with the keys
        /// <paramref name="key1"/>, <paramref name="key2"/>.
        /// </summary>
        /// <param name="key1">The <typeparamref name="TKey1"/> which
        /// is the first key of the <paramref name="value"/>
        /// to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/>.</param>
        /// <param name="key2">The <typeparamref name="TKey2"/> which
        /// is the second key of the <paramref name="value"/>
        /// to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/>.</param>
        /// <param name="value">The <typeparamref name="TValue"/> to add to the <see cref="MultikeyedDictionary{TKey1, TKey2, TValue}"/>.</param>
        public void Add(TKey1 key1, TKey2 key2, TValue value)
        {
            // Declare the locals relative to the different levels.
            LevelOne levelOne;

            /* ------------------------------------------------------\
            |  Check each level individually, if the key set is      |
            |  already present, throw an the appropriate exception.  |
            \------------------------------------------------------ */
            if (((object)(key1)) == null)
            {
                throw new ArgumentNullException("key1");
            }
            bool topLevelLock = false;

            Monitor.Enter(this.dataCopy, ref topLevelLock);
            if (this.dataCopy.TryGetValue(key1, out levelOne))
            {
                if (topLevelLock)
                {
                    Monitor.Exit(this.dataCopy);
                }
                if (((object)(key2)) == null)
                {
                    throw new ArgumentNullException("key2");
                }
                bool levelOneLock = false;
                Monitor.Enter(levelOne, ref levelOneLock);
                if (levelOne.ContainsKey(key2))
                {
                    if (levelOneLock)
                    {
                        Monitor.Exit(levelOne);
                    }
                    throw new InvalidOperationException();
                }
                else
                {
                    levelOne.Add(key2, value);
                    if (levelOneLock)
                    {
                        Monitor.Exit(levelOne);
                    }
                }
            }
            else
            {
                this.dataCopy.Add(key1, (levelOne = new LevelOne()));
                levelOne.Add(key2, value);
                if (topLevelLock)
                {
                    Monitor.Exit(this.dataCopy);
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Returns/sets the value with the <paramref name="key1"/>, <paramref name="key2"/>, <paramref name="key3"/>, <paramref name="key4"/> provided.
 /// </summary>
 /// <param name="key1">The <typeparamref name="TKey1"/> which
 /// is the first key of the element to set/retrieve.</param>
 /// <param name="key2">The <typeparamref name="TKey2"/> which
 /// is the second key of the element to set/retrieve.</param>
 /// <param name="key3">The <typeparamref name="TKey3"/> which
 /// is the third key of the element to set/retrieve.</param>
 /// <param name="key4">The <typeparamref name="TKey4"/> which
 /// is the fourth key of the element to set/retrieve.</param>
 public TValue this[TKey1 key1, TKey2 key2, TKey3 key3, TKey4 key4]
 {
     get
     {
         LevelOne   levelOne;
         LevelTwo   levelTwo;
         LevelThree levelThree;
         if (((object)(key1)) == null)
         {
             throw new ArgumentNullException("key1");
         }
         bool topLevelLock = false;
         Monitor.Enter(this.dataCopy, ref topLevelLock);
         if (this.dataCopy.TryGetValue(key1, out levelOne))
         {
             if (topLevelLock)
             {
                 Monitor.Exit(this.dataCopy);
             }
             if (((object)(key2)) == null)
             {
                 throw new ArgumentNullException("key2");
             }
             bool levelOneLock = false;
             Monitor.Enter(levelOne, ref levelOneLock);
             if (levelOne.TryGetValue(key2, out levelTwo))
             {
                 if (levelOneLock)
                 {
                     Monitor.Exit(levelOne);
                 }
                 if (((object)(key3)) == null)
                 {
                     throw new ArgumentNullException("key3");
                 }
                 bool levelTwoLock = false;
                 Monitor.Enter(levelTwo, ref levelTwoLock);
                 if (levelTwo.TryGetValue(key3, out levelThree))
                 {
                     TValue value;
                     if (levelTwoLock)
                     {
                         Monitor.Exit(levelTwo);
                     }
                     if (((object)(key4)) == null)
                     {
                         throw new ArgumentNullException("key4");
                     }
                     bool levelThreeLock = false;
                     Monitor.Enter(levelThree, ref levelThreeLock);
                     if (levelThree.TryGetValue(key4, out value))
                     {
                         if (levelThreeLock)
                         {
                             Monitor.Exit(levelThree);
                         }
                         return(value);
                     }
                     else
                     {
                         if (levelThreeLock)
                         {
                             Monitor.Exit(levelThree);
                         }
                         throw new SubKeyNotFoundException("key4");
                     }
                 }
                 else
                 {
                     if (levelTwoLock)
                     {
                         Monitor.Exit(levelTwo);
                     }
                     throw new SubKeyNotFoundException("key3");
                 }
             }
             else
             {
                 if (levelOneLock)
                 {
                     Monitor.Exit(levelOne);
                 }
                 throw new SubKeyNotFoundException("key2");
             }
         }
         else
         {
             if (topLevelLock)
             {
                 Monitor.Exit(this.dataCopy);
             }
             throw new SubKeyNotFoundException("key1");
         }
     }
     set
     {
         LevelOne   levelOne;
         LevelTwo   levelTwo;
         LevelThree levelThree;
         if (((object)(key1)) == null)
         {
             throw new ArgumentNullException("key1");
         }
         bool topLevelLock = false;
         Monitor.Enter(this.dataCopy, ref topLevelLock);
         if (this.dataCopy.TryGetValue(key1, out levelOne))
         {
             if (topLevelLock)
             {
                 Monitor.Exit(this.dataCopy);
             }
             if (((object)(key2)) == null)
             {
                 throw new ArgumentNullException("key2");
             }
             bool levelOneLock = false;
             Monitor.Enter(levelOne, ref levelOneLock);
             if (levelOne.TryGetValue(key2, out levelTwo))
             {
                 if (levelOneLock)
                 {
                     Monitor.Exit(levelOne);
                 }
                 if (((object)(key3)) == null)
                 {
                     throw new ArgumentNullException("key3");
                 }
                 bool levelTwoLock = false;
                 Monitor.Enter(levelTwo, ref levelTwoLock);
                 if (levelTwo.TryGetValue(key3, out levelThree))
                 {
                     if (levelTwoLock)
                     {
                         Monitor.Exit(levelTwo);
                     }
                     if (((object)(key4)) == null)
                     {
                         throw new ArgumentNullException("key4");
                     }
                     bool levelThreeLock = false;
                     Monitor.Enter(levelThree, ref levelThreeLock);
                     if (levelThree.ContainsKey(key4))
                     {
                         if (levelThreeLock)
                         {
                             Monitor.Exit(levelThree);
                         }
                         levelThree[key4] = value;
                     }
                     else
                     {
                         levelThree.Add(key4, value);
                         if (levelThreeLock)
                         {
                             Monitor.Exit(levelThree);
                         }
                     }
                 }
                 else
                 {
                     levelTwo.Add(key3, (levelThree = new LevelThree()));
                     levelThree.Add(key4, value);
                     if (levelTwoLock)
                     {
                         Monitor.Exit(levelTwo);
                     }
                 }
             }
             else
             {
                 levelOne.Add(key2, (levelTwo = new LevelTwo()));
                 levelTwo.Add(key3, (levelThree = new LevelThree()));
                 levelThree.Add(key4, value);
                 if (levelOneLock)
                 {
                     Monitor.Exit(levelOne);
                 }
             }
         }
         else
         {
             this.dataCopy.Add(key1, (levelOne = new LevelOne()));
             levelOne.Add(key2, (levelTwo = new LevelTwo()));
             levelTwo.Add(key3, (levelThree = new LevelThree()));
             levelThree.Add(key4, value);
             if (topLevelLock)
             {
                 Monitor.Exit(this.dataCopy);
             }
         }
     }
 }