public virtual void TestSimpleHashMap() { WeakIdentityMap <string, string> map = WeakIdentityMap <string, string> .NewHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: string key1 = "foo"; string key2 = "test1 foo".Split(' ')[1]; string key3 = "test2 foo".Split(' ')[1]; // LUCENENET NOTE: As per http://stackoverflow.com/a/543329/181087, // the above hack is required in order to ensure the AreNotSame // check will work. If you assign the same string to 3 different variables // without doing some kind of manipulation from the original string, the // AreNotSame test will fail because the references will be the same. Assert.AreNotSame(key1, key2); Assert.AreEqual(key1, key2); Assert.AreNotSame(key1, key3); Assert.AreEqual(key1, key3); Assert.AreNotSame(key2, key3); Assert.AreEqual(key2, key3); // try null key & check its iterator also return null: map.Put(null, "null"); { using (IEnumerator <string> iter = map.Keys.GetEnumerator()) { Assert.IsTrue(iter.MoveNext()); Assert.IsNull(iter.Current); Assert.IsFalse(iter.MoveNext()); Assert.IsFalse(iter.MoveNext()); } } // 2 more keys: map.Put(key1, "bar1"); map.Put(key2, "bar2"); Assert.AreEqual(3, map.Count); Assert.AreEqual("bar1", map.Get(key1)); Assert.AreEqual("bar2", map.Get(key2)); Assert.AreEqual(null, map.Get(key3)); Assert.AreEqual("null", map.Get(null)); Assert.IsTrue(map.ContainsKey(key1)); Assert.IsTrue(map.ContainsKey(key2)); Assert.IsFalse(map.ContainsKey(key3)); Assert.IsTrue(map.ContainsKey(null)); // repeat and check that we have no double entries map.Put(key1, "bar1"); map.Put(key2, "bar2"); map.Put(null, "null"); Assert.AreEqual(3, map.Count); Assert.AreEqual("bar1", map.Get(key1)); Assert.AreEqual("bar2", map.Get(key2)); Assert.AreEqual(null, map.Get(key3)); Assert.AreEqual("null", map.Get(null)); Assert.IsTrue(map.ContainsKey(key1)); Assert.IsTrue(map.ContainsKey(key2)); Assert.IsFalse(map.ContainsKey(key3)); Assert.IsTrue(map.ContainsKey(null)); map.Remove(null); Assert.AreEqual(2, map.Count); map.Remove(key1); Assert.AreEqual(1, map.Count); map.Put(key1, "bar1"); map.Put(key2, "bar2"); map.Put(key3, "bar3"); Assert.AreEqual(3, map.Count); int c = 0, keysAssigned = 0; foreach (object k in map.Keys) { //Assert.IsTrue(iter.hasNext()); // try again, should return same result! // LUCENENET NOTE: Need object.ReferenceEquals here because the == operator does more than check reference equality Assert.IsTrue(object.ReferenceEquals(k, key1) || object.ReferenceEquals(k, key2) | object.ReferenceEquals(k, key3)); keysAssigned += object.ReferenceEquals(k, key1) ? 1 : (object.ReferenceEquals(k, key2) ? 2 : 4); c++; } Assert.AreEqual(3, c); Assert.AreEqual(1 + 2 + 4, keysAssigned, "all keys must have been seen"); c = 0; for (IEnumerator <string> iter = map.Values.GetEnumerator(); iter.MoveNext();) { string v = iter.Current; Assert.IsTrue(v.StartsWith("bar", StringComparison.Ordinal)); c++; } Assert.AreEqual(3, c); // clear strong refs key1 = key2 = key3 = null; // check that GC does not cause problems in reap() method, wait 1 second and let GC work: int size = map.Count; for (int i = 0; size > 0 && i < 10; i++) { #if !NETSTANDARD1_6 try { #endif GC.Collect(); int newSize = map.Count; Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(TimeSpan.FromSeconds(1)); c = 0; foreach (object k in map.Keys) { Assert.IsNotNull(k); c++; } newSize = map.Count; Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; #if !NETSTANDARD1_6 } #pragma warning disable 168 catch (ThreadInterruptedException ie) #pragma warning restore 168 { } #endif } map.Clear(); Assert.AreEqual(0, map.Count); Assert.IsTrue(map.IsEmpty); using (IEnumerator <string> it = map.Keys.GetEnumerator()) Assert.IsFalse(it.MoveNext()); /*try * { * it.Next(); * Assert.Fail("Should throw NoSuchElementException"); * } * catch (NoSuchElementException nse) * { * }*/ // LUCENENET NOTE: As per http://stackoverflow.com/a/543329/181087, // the following hack is required in order to ensure the string references // are different. If you assign the same string to 2 different variables // without doing some kind of manipulation from the original string, the // references will be the same. key1 = "test3 foo".Split(' ')[1]; key2 = "test4 foo".Split(' ')[1]; map.Put(key1, "bar1"); map.Put(key2, "bar2"); Assert.AreEqual(2, map.Count); map.Clear(); Assert.AreEqual(0, map.Count); Assert.IsTrue(map.IsEmpty); }
public virtual void TestSimpleHashMap() { WeakIdentityMap <string, string> map = WeakIdentityMap <string, string> .NewHashMap(Random().NextBoolean()); // we keep strong references to the keys, // so WeakIdentityMap will not forget about them: string key1 = "foo"; string key2 = "foo"; string key3 = "foo"; Assert.AreNotSame(key1, key2); Assert.AreEqual(key1, key2); Assert.AreNotSame(key1, key3); Assert.AreEqual(key1, key3); Assert.AreNotSame(key2, key3); Assert.AreEqual(key2, key3); // try null key & check its iterator also return null: map.Put(null, "null"); { IEnumerator <string> iter = map.Keys.GetEnumerator(); Assert.IsTrue(iter.MoveNext()); Assert.IsNull(iter.Current); Assert.IsFalse(iter.MoveNext()); Assert.IsFalse(iter.MoveNext()); } // 2 more keys: map.Put(key1, "bar1"); map.Put(key2, "bar2"); Assert.AreEqual(3, map.Size()); Assert.AreEqual("bar1", map.Get(key1)); Assert.AreEqual("bar2", map.Get(key2)); Assert.AreEqual(null, map.Get(key3)); Assert.AreEqual("null", map.Get(null)); Assert.IsTrue(map.ContainsKey(key1)); Assert.IsTrue(map.ContainsKey(key2)); Assert.IsFalse(map.ContainsKey(key3)); Assert.IsTrue(map.ContainsKey(null)); // repeat and check that we have no double entries map.Put(key1, "bar1"); map.Put(key2, "bar2"); map.Put(null, "null"); Assert.AreEqual(3, map.Size()); Assert.AreEqual("bar1", map.Get(key1)); Assert.AreEqual("bar2", map.Get(key2)); Assert.AreEqual(null, map.Get(key3)); Assert.AreEqual("null", map.Get(null)); Assert.IsTrue(map.ContainsKey(key1)); Assert.IsTrue(map.ContainsKey(key2)); Assert.IsFalse(map.ContainsKey(key3)); Assert.IsTrue(map.ContainsKey(null)); map.Remove(null); Assert.AreEqual(2, map.Size()); map.Remove(key1); Assert.AreEqual(1, map.Size()); map.Put(key1, "bar1"); map.Put(key2, "bar2"); map.Put(key3, "bar3"); Assert.AreEqual(3, map.Size()); int c = 0, keysAssigned = 0; for (IEnumerator <string> iter = map.Keys.GetEnumerator(); iter.MoveNext();) { //Assert.IsTrue(iter.hasNext()); // try again, should return same result! string k = iter.Current; Assert.IsTrue(k == key1 || k == key2 | k == key3); keysAssigned += (k == key1) ? 1 : ((k == key2) ? 2 : 4); c++; } Assert.AreEqual(3, c); Assert.AreEqual(1 + 2 + 4, keysAssigned, "all keys must have been seen"); c = 0; for (IEnumerator <string> iter = map.Values.GetEnumerator(); iter.MoveNext();) { string v = iter.Current; Assert.IsTrue(v.StartsWith("bar")); c++; } Assert.AreEqual(3, c); // clear strong refs key1 = key2 = key3 = null; // check that GC does not cause problems in reap() method, wait 1 second and let GC work: int size = map.Size(); for (int i = 0; size > 0 && i < 10; i++) { try { System.RunFinalization(); System.gc(); int newSize = map.Size(); Assert.IsTrue(size >= newSize, "previousSize(" + size + ")>=newSize(" + newSize + ")"); size = newSize; Thread.Sleep(new TimeSpan(100L)); c = 0; for (IEnumerator <string> iter = map.Keys.GetEnumerator(); iter.MoveNext();) { Assert.IsNotNull(iter.Current); c++; } newSize = map.Size(); Assert.IsTrue(size >= c, "previousSize(" + size + ")>=iteratorSize(" + c + ")"); Assert.IsTrue(c >= newSize, "iteratorSize(" + c + ")>=newSize(" + newSize + ")"); size = newSize; } catch (ThreadInterruptedException ie) { } } map.Clear(); Assert.AreEqual(0, map.Size()); Assert.IsTrue(map.Empty); IEnumerator <string> it = map.Keys.GetEnumerator(); Assert.IsFalse(it.MoveNext()); /*try * { * it.Next(); * Assert.Fail("Should throw NoSuchElementException"); * } * catch (NoSuchElementException nse) * { * }*/ key1 = "foo"; key2 = "foo"; map.Put(key1, "bar1"); map.Put(key2, "bar2"); Assert.AreEqual(2, map.Size()); map.Clear(); Assert.AreEqual(0, map.Size()); Assert.IsTrue(map.Empty); }