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"); }
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); }
private static void AddBenchRndNB() { var dict = new NonBlocking.ConcurrentDictionary <int, string>(); var cnt = new Counter32(); var benchmarkName = "======== Random Add 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.TryAdd(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); }
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); }
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"); }
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"); }
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(); }
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)"); }