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); }
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); }
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); }
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); }