コード例 #1
0
        private static void ChurnConcurrent()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, string>();
            //var dict = new Concurrent.ConcurrentDictionary<int, string>();

            var         threadCnt = 200;
            List <Task> tasks     = new List <Task>(threadCnt);

            var sw = Stopwatch.StartNew();

            for (int i = 0; i < threadCnt; i++)
            {
                var task = new Task(() =>
                {
                    for (int j = i * 1000000, l = j + 1000000; j < l; j++)
                    {
                        string dummy;
                        dict.TryAdd(j, "dummy");
                        dict.TryRemove(j, out dummy);
                        //Thread.Sleep(10);
                    }
                    System.Console.Write('.');
                }, TaskCreationOptions.LongRunning);

                tasks.Add(task);
                task.Start();
            }

            Task.WaitAll(tasks.ToArray());

            System.Console.WriteLine(sw.ElapsedMilliseconds);
        }
コード例 #2
0
        public static void TestBugFix669376()
        {
            var cd = new NonBlocking.ConcurrentDictionary <string, int>(new OrdinalStringComparer());

            cd["test"] = 10;
            Assert.True(cd.ContainsKey("TEST"), "Customized comparer didn't work");
        }
コード例 #3
0
        public static void TestRemove3()
        {
            NonBlocking.ConcurrentDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>();

            dict[99] = -99;

            ICollection <KeyValuePair <int, int> > col = dict;

            // Make sure we cannot "remove" a key/value pair which is not in the dictionary
            for (int i = 0; i < 200; i++)
            {
                if (i != 99)
                {
                    Assert.False(col.Remove(new KeyValuePair <int, int>(i, -99)), "Should not remove not existing a key/value pair - new KeyValuePair<int, int>(i, -99)");
                    Assert.False(col.Remove(new KeyValuePair <int, int>(99, -i)), "Should not remove not existing a key/value pair - new KeyValuePair<int, int>(99, -i)");
                }
            }

            // Can we remove a key/value pair successfully?
            Assert.True(col.Remove(new KeyValuePair <int, int>(99, -99)), "Failed to remove existing key/value pair");

            // Make sure the key/value pair is gone
            Assert.False(col.Remove(new KeyValuePair <int, int>(99, -99)), "Should not remove the key/value pair which has been removed");

            // And that the dictionary is empty. We will check the count in a few different ways:
            Assert.Equal(0, dict.Count);
            Assert.Equal(0, dict.ToArray().Length);
        }
コード例 #4
0
        public static void TestICollection()
        {
            ICollection dictionary = new NonBlocking.ConcurrentDictionary <int, int>();

            Assert.False(dictionary.IsSynchronized, "TestICollection:  FAILED.  IsSynchronized returned true!");

            int key   = -1;
            int value = +1;

            //add one item to the dictionary
            ((NonBlocking.ConcurrentDictionary <int, int>)dictionary).TryAdd(key, value);

            var objectArray = new Object[1];

            dictionary.CopyTo(objectArray, 0);

            Assert.Equal(key, ((KeyValuePair <int, int>)objectArray[0]).Key);
            Assert.Equal(value, ((KeyValuePair <int, int>)objectArray[0]).Value);

            var keyValueArray = new KeyValuePair <int, int> [1];

            dictionary.CopyTo(keyValueArray, 0);
            Assert.Equal(key, keyValueArray[0].Key);
            Assert.Equal(value, keyValueArray[0].Value);

            var entryArray = new DictionaryEntry[1];

            dictionary.CopyTo(entryArray, 0);
            Assert.Equal(key, (int)entryArray[0].Key);
            Assert.Equal(value, (int)entryArray[0].Value);
        }
コード例 #5
0
        private static void GetOrAddFuncBenchRndNB()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, string>();
            var cnt  = new Counter32();

            var benchmarkName = "======== Random GetOrAdd Func NonBlocking int->string 1M Ops/sec:";

            Action <int, int> act = (i, threadBias) =>
            {
                // get some random index in [0, 1000000]
                int randomIndex = GetRandomIndex(i, threadBias, 1000000);
                dict.GetOrAdd(randomIndex, (_) => "qq");

                // after making about 1000000 adds, start with a new table
                var c = cnt;
                c.Increment();
                if (Every8K(i) && c.Value > 1000000)
                {
                    if (Interlocked.CompareExchange(ref cnt, new Counter32(), c) == c)
                    {
                        dict = new NonBlocking.ConcurrentDictionary <int, string>();
                    }
                }
            };

            RunBench(benchmarkName, act);
        }
コード例 #6
0
        public static void TestConstructor()
        {
            var dictionary = new  NonBlocking.ConcurrentDictionary <int, int>(new[] { new KeyValuePair <int, int>(1, 1) });

            Assert.False(dictionary.IsEmpty);
            Assert.Equal(1, dictionary.Keys.Count);
            Assert.Equal(1, dictionary.Values.Count);
        }
コード例 #7
0
        public static void TestIDictionary()
        {
            IDictionary dictionary = new NonBlocking.ConcurrentDictionary <string, int>();

            Assert.False(dictionary.IsReadOnly);

            // Empty dictionary should not enumerate
            Assert.Empty(dictionary);

            const int SIZE = 10;

            for (int i = 0; i < SIZE; i++)
            {
                dictionary.Add(i.ToString(), i);
            }

            Assert.Equal(SIZE, dictionary.Count);

            //test contains
            Assert.False(dictionary.Contains(1), "TestIDictionary:  FAILED.  Contain retuned true for incorrect key type");
            Assert.False(dictionary.Contains("100"), "TestIDictionary:  FAILED.  Contain retuned true for incorrect key");
            Assert.True(dictionary.Contains("1"), "TestIDictionary:  FAILED.  Contain retuned false for correct key");

            //test GetEnumerator
            int count = 0;

            foreach (var obj in dictionary)
            {
                DictionaryEntry entry         = (DictionaryEntry)obj;
                string          key           = (string)entry.Key;
                int             value         = (int)entry.Value;
                int             expectedValue = int.Parse(key);
                Assert.True(value == expectedValue,
                            String.Format("TestIDictionary:  FAILED.  Unexpected value returned from GetEnumerator, expected {0}, actual {1}", value, expectedValue));
                count++;
            }

            Assert.Equal(SIZE, count);
            Assert.Equal(SIZE, dictionary.Keys.Count);
            Assert.Equal(SIZE, dictionary.Values.Count);

            //Test Remove
            dictionary.Remove("9");
            Assert.Equal(SIZE - 1, dictionary.Count);

            //Test this[]
            for (int i = 0; i < dictionary.Count; i++)
            {
                Assert.Equal(i, (int)dictionary[i.ToString()]);
            }

            dictionary["1"] = 100; // try a valid setter
            Assert.Equal(100, (int)dictionary["1"]);

            //nonsexist key
            Assert.Null(dictionary["NotAKey"]);
        }
コード例 #8
0
        public static void TestExceptions()
        {
            var dictionary = new NonBlocking.ConcurrentDictionary <string, int>();

            Assert.Throws <ArgumentNullException>(
                () => dictionary.TryAdd(null, 0));
            //  "TestExceptions:  FAILED.  TryAdd didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentNullException>(
                () => dictionary.ContainsKey(null));
            // "TestExceptions:  FAILED.  Contains didn't throw ANE when null key is passed");

            int item;

            Assert.Throws <ArgumentNullException>(
                () => dictionary.TryRemove(null, out item));
            //  "TestExceptions:  FAILED.  TryRemove didn't throw ANE when null key is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary.TryGetValue(null, out item));
            // "TestExceptions:  FAILED.  TryGetValue didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentNullException>(
                () => { var x = dictionary[null]; });
            // "TestExceptions:  FAILED.  this[] didn't throw ANE when null key is passed");
            Assert.Throws <KeyNotFoundException>(
                () => { var x = dictionary["1"]; });
            // "TestExceptions:  FAILED.  this[] TryGetValue didn't throw KeyNotFoundException!");

            Assert.Throws <ArgumentNullException>(
                () => dictionary[null] = 1);
            // "TestExceptions:  FAILED.  this[] didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentNullException>(
                () => dictionary.GetOrAdd(null, (k) => 0));
            // "TestExceptions:  FAILED.  GetOrAdd didn't throw ANE when null key is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary.GetOrAdd("1", null));
            // "TestExceptions:  FAILED.  GetOrAdd didn't throw ANE when null valueFactory is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary.GetOrAdd(null, 0));
            // "TestExceptions:  FAILED.  GetOrAdd didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentNullException>(
                () => dictionary.AddOrUpdate(null, (k) => 0, (k, v) => 0));
            // "TestExceptions:  FAILED.  AddOrUpdate didn't throw ANE when null key is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary.AddOrUpdate("1", null, (k, v) => 0));
            // "TestExceptions:  FAILED.  AddOrUpdate didn't throw ANE when null updateFactory is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary.AddOrUpdate(null, (k) => 0, null));
            // "TestExceptions:  FAILED.  AddOrUpdate didn't throw ANE when null addFactory is passed");

            dictionary.TryAdd("1", 1);
            Assert.Throws <ArgumentException>(
                () => ((IDictionary <string, int>)dictionary).Add("1", 2));
            // "TestExceptions:  FAILED.  IDictionary didn't throw AE when duplicate key is passed");
        }
コード例 #9
0
        private static void TestRemove2(int removesPerThread)
        {
            NonBlocking.ConcurrentDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>();

            for (int i = 0; i < removesPerThread; i++)
            {
                dict[i] = -i;
            }

            // The dictionary contains keys [0..N), each key mapped to a value equal to the key.
            // Threads will cooperatively remove all even keys.
            const int SIZE    = 2;
            int       running = SIZE;

            bool[][] seen = new bool[SIZE][];
            for (int i = 0; i < SIZE; i++)
            {
                seen[i] = new bool[removesPerThread];
            }

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int t = 0; t < SIZE; t++)
                {
                    int thread = t;
                    Task.Run(
                        () =>
                    {
                        for (int key = 0; key < removesPerThread; key++)
                        {
                            int value;
                            if (dict.TryRemove(key, out value))
                            {
                                seen[thread][key] = true;

                                Assert.Equal(-key, value);
                            }
                        }
                        if (Interlocked.Decrement(ref running) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }

            Assert.Equal(0, dict.Count);

            for (int i = 0; i < removesPerThread; i++)
            {
                Assert.False(seen[0][i] == seen[1][i],
                             String.Format("> FAILED. Two threads appear to have removed the same element. TestRemove2(removesPerThread={0})", removesPerThread)
                             );
            }
        }
コード例 #10
0
        private static void GetBenchNB_int()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, int>();

            Parallel.For(0, 100000, (i) => dict[i] = i);
            Parallel.For(0, 100000, (i) => { var dummy = dict[i]; });

            var benchmarkName = "======== Get NonBlocking int->int 1M Ops/sec:";

            Action <int, int> act = (i, threadBias) => { var dummy = dict[i % 100000]; };

            RunBench(benchmarkName, act);
        }
コード例 #11
0
        private static void WriteBenchRndNB()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, string>();

            var benchmarkName = "======== Random Write NonBlocking 1M int->string Ops/sec:";

            Action <int, int> act = (i, threadBias) =>
            {
                // get some random index in [0, 1000000]
                int randomIndex = GetRandomIndex(i, threadBias, 1000000);
                dict[randomIndex] = "qq";
                dict[randomIndex] = "aa";
            };

            RunBench(benchmarkName, act);
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: aberkromb/NonBlocking
        private static void GetBenchNBObj()
        {
            var dict = new NonBlocking.ConcurrentDictionary<object, string>();

            var keys = new string[200000];
            for (int i = 0; i < keys.Length; i++) keys[i] = i.ToString();

            Parallel.For(0, 100000, (i) => dict[keys[i]] = i.ToString());
            Parallel.For(0, 100000, (i) => { var dummy = dict[keys[i]]; });

            var benchmarkName = "======== Get NonBlocking 1M Ops/sec:";

            Action<int, int> act = (i, threadBias) => { var dummy = dict[keys[i % 100000]]; };

            RunBench(benchmarkName, act);
        }
コード例 #13
0
        public static void TestICollection_Negative()
        {
            ICollection dictionary = new NonBlocking.ConcurrentDictionary <int, int>();

            Assert.False(dictionary.IsSynchronized, "TestICollection:  FAILED.  IsSynchronized returned true!");

            Assert.Throws <NotSupportedException>(() => { var obj = dictionary.SyncRoot; });
            // "TestICollection:  FAILED.  SyncRoot property didn't throw");
            Assert.Throws <ArgumentNullException>(() => dictionary.CopyTo(null, 0));
            // "TestICollection:  FAILED.  CopyTo didn't throw ANE when null Array is passed");
            Assert.Throws <ArgumentOutOfRangeException>(() => dictionary.CopyTo(new object[] { }, -1));
            // "TestICollection:  FAILED.  CopyTo didn't throw AORE when negative index passed");

            //add one item to the dictionary
            ((NonBlocking.ConcurrentDictionary <int, int>)dictionary).TryAdd(1, 1);
            Assert.Throws <ArgumentException>(() => dictionary.CopyTo(new object[] { }, 0));
            // "TestICollection:  FAILED.  CopyTo didn't throw AE when the Array size is smaller than the dictionary count");
        }
コード例 #14
0
        private static void ChurnSequential()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, string>();

            for (int i = 0; i < 1000000; i++)
            {
                dict.Add(i, "dummy");
                dict.Remove(i);
                //Thread.Sleep(10);
            }

            for (int i = 0; i < 100000; i++)
            {
                dict.Add(i, "dummy");
                dict.Remove(i);
                Thread.Sleep(5);
            }
        }
コード例 #15
0
        private static void GetBenchRndNB()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, string>();

            Parallel.For(0, 100000, (i) => dict[i] = "qq");
            Parallel.For(0, 100000, (i) => { var dummy = dict[i]; });

            var benchmarkName = "======== Random Get NonBlocking int->string 1M Ops/sec:";

            Action <int, int> act = (i, threadBias) =>
            {
                string dummy;
                int    randomIndex = GetRandomIndex(i, threadBias, 100000);
                dict.TryGetValue(randomIndex, out dummy);
            };

            RunBench(benchmarkName, act);
        }
コード例 #16
0
        public static void TestClear()
        {
            var dictionary = new NonBlocking.ConcurrentDictionary <int, int>();

            for (int i = 0; i < 10; i++)
            {
                dictionary.TryAdd(i, i);
            }

            Assert.Equal(10, dictionary.Count);

            dictionary.Clear();
            Assert.Equal(0, dictionary.Count);

            int item;

            Assert.False(dictionary.TryRemove(1, out item), "TestClear: FAILED.  TryRemove succeeded after Clear");
            Assert.True(dictionary.IsEmpty, "TestClear: FAILED.  IsEmpty returned false after Clear");
        }
コード例 #17
0
        public static void TestClear()
        {
            var dictionary = new NonBlocking.ConcurrentDictionary <int, int>();

            for (int i = 0; i < 10; i++)
            {
                dictionary.TryAdd(i, i);
            }

            Assert.Equal(10, dictionary.Count);

            dictionary.Clear();
#pragma warning disable xUnit2013 // Do not use equality check to check for collection size.
            Assert.Equal(0, dictionary.Count);
#pragma warning restore xUnit2013 // Do not use equality check to check for collection size.

            int item;
            Assert.False(dictionary.TryRemove(1, out item), "TestClear: FAILED.  TryRemove succeeded after Clear");
            Assert.True(dictionary.IsEmpty, "TestClear: FAILED.  IsEmpty returned false after Clear");
        }
コード例 #18
0
        private static void TestRead1(int cLevel, int threads, int readsPerThread)
        {
            IDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>(cLevel, 1);

            for (int i = 0; i < readsPerThread; i += 2)
            {
                dict[i] = i;
            }

            int count = threads;

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads; i++)
                {
                    int ii = i;
                    Task.Run(
                        () =>
                    {
                        for (int j = 0; j < readsPerThread; j++)
                        {
                            int val = 0;
                            if (dict.TryGetValue(j, out val))
                            {
                                Assert.Equal(0, j % 2);
                                Assert.Equal(j, val);
                            }
                            else
                            {
                                Assert.Equal(1, j % 2);
                            }
                        }
                        if (Interlocked.Decrement(ref count) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }
        }
コード例 #19
0
        public static void TestBasicScenarios()
        {
            NonBlocking.ConcurrentDictionary <int, int> cd = new NonBlocking.ConcurrentDictionary <int, int>();

            Task[] tks = new Task[2];
            tks[0] = Task.Run(() =>
            {
                var ret = cd.TryAdd(1, 11);
                if (!ret)
                {
                    ret = cd.TryUpdate(1, 11, 111);
                    Assert.True(ret);
                }

                ret = cd.TryAdd(2, 22);
                if (!ret)
                {
                    ret = cd.TryUpdate(2, 22, 222);
                    Assert.True(ret);
                }
            });

            tks[1] = Task.Run(() =>
            {
                var ret = cd.TryAdd(2, 222);
                if (!ret)
                {
                    ret = cd.TryUpdate(2, 222, 22);
                    Assert.True(ret);
                }

                ret = cd.TryAdd(1, 111);
                if (!ret)
                {
                    ret = cd.TryUpdate(1, 111, 11);
                    Assert.True(ret);
                }
            });

            Task.WaitAll(tks);
        }
コード例 #20
0
        public static void TestIDictionary_Negative()
        {
            IDictionary dictionary = new NonBlocking.ConcurrentDictionary <string, int>();

            Assert.Throws <ArgumentNullException>(
                () => dictionary.Add(null, 1));
            // "TestIDictionary:  FAILED.  Add didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentException>(
                () => dictionary.Add(1, 1));
            // "TestIDictionary:  FAILED.  Add didn't throw AE when incorrect key type is passed");

            Assert.Throws <ArgumentException>(
                () => dictionary.Add("1", "1"));
            // "TestIDictionary:  FAILED.  Add didn't throw AE when incorrect value type is passed");

            Assert.Throws <ArgumentNullException>(
                () => dictionary.Contains(null));
            // "TestIDictionary:  FAILED.  Contain didn't throw ANE when null key is passed");

            //Test Remove
            Assert.Throws <ArgumentNullException>(
                () => dictionary.Remove(null));
            // "TestIDictionary:  FAILED.  Remove didn't throw ANE when null key is passed");

            //Test this[]
            Assert.Throws <ArgumentNullException>(
                () => { object val = dictionary[null]; });
            // "TestIDictionary:  FAILED.  this[] getter didn't throw ANE when null key is passed");
            Assert.Throws <ArgumentNullException>(
                () => dictionary[null] = 0);
            // "TestIDictionary:  FAILED.  this[] setter didn't throw ANE when null key is passed");

            Assert.Throws <ArgumentException>(
                () => dictionary[1] = 0);
            // "TestIDictionary:  FAILED.  this[] setter didn't throw AE when invalid key type is passed");

            Assert.Throws <ArgumentException>(
                () => dictionary["1"] = "0");
            // "TestIDictionary:  FAILED.  this[] setter didn't throw AE when invalid value type is passed");
        }
コード例 #21
0
        private static void SingleThreadedSequentialAddWithGapsNB()
        {
            var dict = new NonBlocking.ConcurrentDictionary <int, int>();

            for (var i = 0; i < 8; ++i)
            {
                Stopwatch sw  = Stopwatch.StartNew();
                var       key = (i + 1) * 50_000_000;

                for (var j = 0; j < 10_000_000; ++j)
                {
                    dict.TryAdd(key + j, j);
                }

                sw.Stop();
                System.Console.Write(sw.ElapsedMilliseconds + " ");

                GC.Collect();
            }

            System.Console.WriteLine();
        }
コード例 #22
0
        private static void TestAdd1(int cLevel, int initSize, int threads, int addsPerThread)
        {
            NonBlocking.ConcurrentDictionary <int, int> dictConcurrent = new NonBlocking.ConcurrentDictionary <int, int>(cLevel, 1);
            IDictionary <int, int> dict = dictConcurrent;

            int count = threads;

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads; i++)
                {
                    int ii = i;
                    Task.Run(
                        () =>
                    {
                        for (int j = 0; j < addsPerThread; j++)
                        {
                            dict.Add(j + ii * addsPerThread, -(j + ii * addsPerThread));
                        }
                        if (Interlocked.Decrement(ref count) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }

            foreach (var pair in dict)
            {
                Assert.Equal(pair.Key, -pair.Value);
            }

            List <int> gotKeys = new List <int>();

            foreach (var pair in dict)
            {
                gotKeys.Add(pair.Key);
            }

            gotKeys.Sort();

            List <int> expectKeys = new List <int>();
            int        itemCount  = threads * addsPerThread;

            for (int i = 0; i < itemCount; i++)
            {
                expectKeys.Add(i);
            }

            Assert.Equal(expectKeys.Count, gotKeys.Count);

            for (int i = 0; i < expectKeys.Count; i++)
            {
                Assert.True(expectKeys[i].Equals(gotKeys[i]),
                            String.Format("The set of keys in the dictionary is are not the same as the expected" + Environment.NewLine +
                                          "TestAdd1(cLevel={0}, initSize={1}, threads={2}, addsPerThread={3})", cLevel, initSize, threads, addsPerThread)
                            );
            }

            // Finally, let's verify that the count is reported correctly.
            int expectedCount = threads * addsPerThread;

            Assert.Equal(expectedCount, dict.Count);
            Assert.Equal(expectedCount, dictConcurrent.ToArray().Length);
        }
コード例 #23
0
        private static void TestRemove1(int cLevel, int threads, int removesPerThread)
        {
            NonBlocking.ConcurrentDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>(cLevel, 1);
            string methodparameters = string.Format("* TestRemove1(cLevel={0}, threads={1}, removesPerThread={2})", cLevel, threads, removesPerThread);
            int    N = 2 * threads * removesPerThread;

            for (int i = 0; i < N; i++)
            {
                dict[i] = -i;
            }

            // The dictionary contains keys [0..N), each key mapped to a value equal to the key.
            // Threads will cooperatively remove all even keys

            int running = threads;

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads; i++)
                {
                    int ii = i;
                    Task.Run(
                        () =>
                    {
                        for (int j = 0; j < removesPerThread; j++)
                        {
                            int value;
                            int key = 2 * (ii + j * threads);
                            Assert.True(dict.TryRemove(key, out value), "Failed to remove an element! " + methodparameters);

                            Assert.Equal(-key, value);
                        }

                        if (Interlocked.Decrement(ref running) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }

            foreach (var pair in dict)
            {
                Assert.Equal(pair.Key, -pair.Value);
            }

            List <int> gotKeys = new List <int>();

            foreach (var pair in dict)
            {
                gotKeys.Add(pair.Key);
            }
            gotKeys.Sort();

            List <int> expectKeys = new List <int>();

            for (int i = 0; i < (threads * removesPerThread); i++)
            {
                expectKeys.Add(2 * i + 1);
            }

            Assert.Equal(expectKeys.Count, gotKeys.Count);

            for (int i = 0; i < expectKeys.Count; i++)
            {
                Assert.True(expectKeys[i].Equals(gotKeys[i]), "  > Unexpected key value! " + methodparameters);
            }

            // Finally, let's verify that the count is reported correctly.
            Assert.Equal(expectKeys.Count, dict.Count);
            Assert.Equal(expectKeys.Count, dict.ToArray().Length);
        }
コード例 #24
0
        private static void TestUpdate1(int cLevel, int threads, int updatesPerThread)
        {
            IDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>(cLevel, 1);

            for (int i = 1; i <= updatesPerThread; i++)
            {
                dict[i] = i;
            }

            int running = threads;

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads; i++)
                {
                    int ii = i;
                    Task.Run(
                        () =>
                    {
                        for (int j = 1; j <= updatesPerThread; j++)
                        {
                            dict[j] = (ii + 2) * j;
                        }
                        if (Interlocked.Decrement(ref running) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }

            foreach (var pair in dict)
            {
                var div = pair.Value / pair.Key;
                var rem = pair.Value % pair.Key;

                Assert.Equal(0, rem);
                Assert.True(div > 1 && div <= threads + 1,
                            String.Format("* Invalid value={3}! TestUpdate1(cLevel={0}, threads={1}, updatesPerThread={2})", cLevel, threads, updatesPerThread, div));
            }

            List <int> gotKeys = new List <int>();

            foreach (var pair in dict)
            {
                gotKeys.Add(pair.Key);
            }
            gotKeys.Sort();

            List <int> expectKeys = new List <int>();

            for (int i = 1; i <= updatesPerThread; i++)
            {
                expectKeys.Add(i);
            }

            Assert.Equal(expectKeys.Count, gotKeys.Count);

            for (int i = 0; i < expectKeys.Count; i++)
            {
                Assert.True(expectKeys[i].Equals(gotKeys[i]),
                            String.Format("The set of keys in the dictionary is are not the same as the expected." + Environment.NewLine +
                                          "TestUpdate1(cLevel={0}, threads={1}, updatesPerThread={2})", cLevel, threads, updatesPerThread)
                            );
            }
        }
コード例 #25
0
        private static void TestGetOrAddOrUpdate(int cLevel, int initSize, int threads, int addsPerThread, bool isAdd)
        {
            NonBlocking.ConcurrentDictionary <int, int> dict = new NonBlocking.ConcurrentDictionary <int, int>(cLevel, 1);

            int count = threads;

            using (ManualResetEvent mre = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads; i++)
                {
                    int ii = i;
                    Task.Run(
                        () =>
                    {
                        for (int j = 0; j < addsPerThread; j++)
                        {
                            if (isAdd)
                            {
                                //call either of the two overloads of GetOrAdd
                                if (j + ii % 2 == 0)
                                {
                                    dict.GetOrAdd(j, -j);
                                }
                                else
                                {
                                    dict.GetOrAdd(j, x => - x);
                                }
                            }
                            else
                            {
                                if (j + ii % 2 == 0)
                                {
                                    dict.AddOrUpdate(j, -j, (k, v) => - j);
                                }
                                else
                                {
                                    dict.AddOrUpdate(j, (k) => - k, (k, v) => - k);
                                }
                            }
                        }
                        if (Interlocked.Decrement(ref count) == 0)
                        {
                            mre.Set();
                        }
                    });
                }
                mre.WaitOne();
            }

            foreach (var pair in dict)
            {
                Assert.Equal(pair.Key, -pair.Value);
            }

            List <int> gotKeys = new List <int>();

            foreach (var pair in dict)
            {
                gotKeys.Add(pair.Key);
            }
            gotKeys.Sort();

            List <int> expectKeys = new List <int>();

            for (int i = 0; i < addsPerThread; i++)
            {
                expectKeys.Add(i);
            }

            Assert.Equal(expectKeys.Count, gotKeys.Count);

            for (int i = 0; i < expectKeys.Count; i++)
            {
                Assert.True(expectKeys[i].Equals(gotKeys[i]),
                            String.Format("* Test '{4}': Level={0}, initSize={1}, threads={2}, addsPerThread={3})" + Environment.NewLine +
                                          "> FAILED.  The set of keys in the dictionary is are not the same as the expected.",
                                          cLevel, initSize, threads, addsPerThread, isAdd ? "GetOrAdd" : "GetOrUpdate"));
            }

            // Finally, let's verify that the count is reported correctly.
            Assert.Equal(addsPerThread, dict.Count);
            Assert.Equal(addsPerThread, dict.ToArray().Length);
        }
コード例 #26
0
        public static void TestTryUpdate()
        {
            var dictionary = new NonBlocking.ConcurrentDictionary <string, int>();

            Assert.Throws <ArgumentNullException>(
                () => dictionary.TryUpdate(null, 0, 0));
            // "TestTryUpdate:  FAILED.  TryUpdate didn't throw ANE when null key is passed");

            for (int i = 0; i < 10; i++)
            {
                dictionary.TryAdd(i.ToString(), i);
            }

            for (int i = 0; i < 10; i++)
            {
                Assert.True(dictionary.TryUpdate(i.ToString(), i + 1, i), "TestTryUpdate:  FAILED.  TryUpdate failed!");
                Assert.Equal(i + 1, dictionary[i.ToString()]);
            }

            //test TryUpdate concurrently
            dictionary.Clear();
            for (int i = 0; i < 1000; i++)
            {
                dictionary.TryAdd(i.ToString(), i);
            }

            var mres = new ManualResetEventSlim();

            Task[] tasks = new Task[10];
            ThreadLocal <ThreadData> updatedKeys = new ThreadLocal <ThreadData>(true);

            for (int i = 0; i < tasks.Length; i++)
            {
                // We are creating the Task using TaskCreationOptions.LongRunning because...
                // there is no guarantee that the Task will be created on another thread.
                // There is also no guarantee that using this TaskCreationOption will force
                // it to be run on another thread.
                tasks[i] = Task.Factory.StartNew((obj) =>
                {
                    mres.Wait();
                    int index                     = (((int)obj) + 1) + 1000;
                    updatedKeys.Value             = new ThreadData();
                    updatedKeys.Value.ThreadIndex = index;

                    for (int j = 0; j < dictionary.Count; j++)
                    {
                        if (dictionary.TryUpdate(j.ToString(), index, j))
                        {
                            if (dictionary[j.ToString()] != index)
                            {
                                updatedKeys.Value.Succeeded = false;
                                return;
                            }
                            updatedKeys.Value.Keys.Add(j.ToString());
                        }
                    }
                }, i, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            }

            mres.Set();
            Task.WaitAll(tasks);

            int numberSucceeded  = 0;
            int totalKeysUpdated = 0;

            foreach (var threadData in updatedKeys.Values)
            {
                totalKeysUpdated += threadData.Keys.Count;
                if (threadData.Succeeded)
                {
                    numberSucceeded++;
                }
            }

            Assert.True(numberSucceeded == tasks.Length, "One or more threads failed!");
            Assert.True(totalKeysUpdated == dictionary.Count,
                        String.Format("TestTryUpdate:  FAILED.  The updated keys count doesn't match the dictionary count, expected {0}, actual {1}", dictionary.Count, totalKeysUpdated));
            foreach (var value in updatedKeys.Values)
            {
                for (int i = 0; i < value.Keys.Count; i++)
                {
                    Assert.True(dictionary[value.Keys[i]] == value.ThreadIndex,
                                String.Format("TestTryUpdate:  FAILED.  The updated value doesn't match the thread index, expected {0} actual {1}", value.ThreadIndex, dictionary[value.Keys[i]]));
                }
            }

            //test TryUpdate with non atomic values (intPtr > 8)
            var dict = new NonBlocking.ConcurrentDictionary <int, Struct16>();

            dict.TryAdd(1, new Struct16(1, -1));
            Assert.True(dict.TryUpdate(1, new Struct16(2, -2), new Struct16(1, -1)), "TestTryUpdate:  FAILED.  TryUpdate failed for non atomic values ( > 8 bytes)");
        }