/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections;
using NUnit.Framework;
namespace Lucene.Net._SupportClass
{
///
///
[TestFixture]
public class TestSupportClass
{
///
///
[Test]
public virtual void TestCRC32()
{
byte[] b = new byte[256];
for (int i = 0; i < b.Length; i++)
b[i] = (byte)i;
SupportClass.Checksum digest = new SupportClass.CRC32();
digest.update(b, 0, b.Length);
Int64 expected = 688229491;
Assert.AreEqual(expected, digest.getValue());
}
}
[TestFixture]
public class TestWeakHashTable
{
[Test]
public void A_TestBasicOps()
{
IDictionary weakHashTable = TestWeakHashTableBehavior.CreateDictionary();// new SupportClass.TjWeakHashTable();
Hashtable realHashTable = new Hashtable();
SmallObject[] so = new SmallObject[100];
for (int i = 0; i < 20000; i++)
{
SmallObject key = new SmallObject(i);
SmallObject value = key;
so[i / 200] = key;
realHashTable.Add(key, value);
weakHashTable.Add(key, value);
}
Assert.AreEqual(weakHashTable.Count, realHashTable.Count);
ICollection keys = (ICollection)realHashTable.Keys;
foreach (SmallObject key in keys)
{
Assert.AreEqual(((SmallObject)realHashTable[key]).i,
((SmallObject)weakHashTable[key]).i);
Assert.IsTrue(realHashTable[key].Equals(weakHashTable[key]));
}
ICollection values1 = (ICollection)weakHashTable.Values;
ICollection values2 = (ICollection)realHashTable.Values;
Assert.AreEqual(values1.Count, values2.Count);
realHashTable.Remove(new SmallObject(10000));
weakHashTable.Remove(new SmallObject(10000));
Assert.AreEqual(weakHashTable.Count, 20000);
Assert.AreEqual(realHashTable.Count, 20000);
for (int i = 0; i < so.Length; i++)
{
realHashTable.Remove(so[i]);
weakHashTable.Remove(so[i]);
Assert.AreEqual(weakHashTable.Count, 20000 - i - 1);
Assert.AreEqual(realHashTable.Count, 20000 - i - 1);
}
//After removals, compare the collections again.
ICollection keys2 = (ICollection)realHashTable.Keys;
foreach (SmallObject o in keys2)
{
Assert.AreEqual(((SmallObject)realHashTable[o]).i,
((SmallObject)weakHashTable[o]).i);
Assert.IsTrue(realHashTable[o].Equals(weakHashTable[o]));
}
}
[Test]
public void B_TestOutOfMemory()
{
IDictionary wht = TestWeakHashTableBehavior.CreateDictionary(); //new SupportClass.TjWeakHashTable();
for (int i = 0; i < 1024 * 8 + 32; i++) // requested Mem. > 8GB
{
wht.Add(new BigObject(i), i);
}
GC.Collect();
Console.WriteLine("Passed out of memory exception.");
}
private int GetMemUsageInKB()
{
return System.Diagnostics.Process.GetCurrentProcess().WorkingSet / 1024;
}
[Test]
public void C_TestMemLeakage()
{
IDictionary wht = TestWeakHashTableBehavior.CreateDictionary(); //new SupportClass.TjWeakHashTable();
GC.Collect();
int initialMemUsage = GetMemUsageInKB();
Console.WriteLine("Initial MemUsage=" + initialMemUsage);
for (int i = 0; i < 10000; i++)
{
wht.Add(new BigObject(i), i);
if (i % 100 == 0)
{
int mu = GetMemUsageInKB();
Console.WriteLine(i.ToString() + ") MemUsage=" + mu);
}
}
GC.Collect();
int memUsage = GetMemUsageInKB();
if (memUsage > initialMemUsage * 2) Assert.Fail("Memory Leakage.MemUsage = " + memUsage);
}
}
[TestFixture]
public class TestWeakHashTableBehavior
{
IDictionary dictionary;
public static IDictionary CreateDictionary()
{
return new SupportClass.WeakHashTable();
}
private void CallGC()
{
for (int i = 0; i < 10; i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
[SetUp]
public void Setup()
{
dictionary = CreateDictionary();
}
[Test]
public void Test_Dictionary_Add()
{
string key = "A";
dictionary.Add(key, "value");
Assert.IsTrue(dictionary.Contains(key));
Assert.AreEqual("value", dictionary[key]);
Assert.AreEqual(1, dictionary.Count);
CollectionAssert.AreEquivalent(dictionary.Values, new object[] { "value" });
}
[Test]
public void Test_Dictionary_Add_2()
{
string key = "A";
string key2 = "B";
dictionary.Add(key, "value");
dictionary.Add(key2, "value2");
Assert.IsTrue(dictionary.Contains(key));
Assert.IsTrue(dictionary.Contains(key2));
Assert.AreEqual("value", dictionary[key]);
Assert.AreEqual("value2", dictionary[key2]);
Assert.AreEqual(2, dictionary.Count);
CollectionAssert.AreEquivalent(dictionary.Values, new object[] { "value", "value2" });
}
[Test]
public void Test_Keys()
{
string key = "A";
string key2 = "B";
dictionary.Add(key, "value");
CollectionAssert.AreEquivalent(dictionary.Keys, new object[] { key });
dictionary.Add(key2, "value2");
CollectionAssert.AreEquivalent(dictionary.Keys, new object[] { key, key2 });
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_Dictionary_Add_Null()
{
dictionary.Add(null, "value");
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_Dictionary_Set_Null()
{
dictionary[null] = "value";
}
[Test]
[ExpectedException(typeof(ArgumentException))]
public void Test_Dictionary_AddTwice()
{
string key = "A";
dictionary.Add(key, "value");
dictionary.Add(key, "value2");
}
[Test]
public void Test_Dictionary_AddReplace()
{
string key = "A";
string key2 = "a".ToUpper();
dictionary.Add(key, "value");
dictionary[key2] = "value2";
Assert.AreEqual(1, dictionary.Count);
Assert.IsTrue(dictionary.Contains(key));
Assert.AreEqual("value2", dictionary[key]);
}
[Test]
public void Test_Dictionary_AddRemove()
{
string key = "A";
dictionary.Add(key, "value");
dictionary.Remove(key);
Assert.AreEqual(0, dictionary.Count);
Assert.IsFalse(dictionary.Contains(key));
Assert.IsNull(dictionary[key]);
}
[Test]
public void Test_Dictionary_Clear()
{
string key = "A";
dictionary.Add(key, "value");
dictionary.Clear();
Assert.AreEqual(0, dictionary.Count);
Assert.IsFalse(dictionary.Contains(key));
Assert.IsNull(dictionary[key]);
}
[Test]
public void Test_Dictionary_AddRemove_2()
{
string key = "A";
dictionary.Add(key, "value");
dictionary.Remove(key);
dictionary.Remove(key);
Assert.AreEqual(0, dictionary.Count);
Assert.IsFalse(dictionary.Contains(key));
Assert.IsNull(dictionary[key]);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_Dictionary_Get_Null()
{
object value = dictionary[null];
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Test_Dictionary_Remove_Null()
{
dictionary.Remove(null);
}
[Test]
public void Test_Dictionary_CopyTo()
{
string key = "A";
dictionary.Add(key, "value");
DictionaryEntry[] a = new DictionaryEntry[1];
dictionary.CopyTo(a, 0);
DictionaryEntry de = (DictionaryEntry)a[0];
Assert.AreEqual(key, de.Key);
Assert.AreEqual("value", de.Value);
}
[Test]
public void Test_Dictionary_GetEnumerator()
{
string key = "A";
dictionary.Add(key, "value");
IDictionaryEnumerator de = dictionary.GetEnumerator();
Assert.IsTrue(de.MoveNext());
Assert.AreEqual(key, de.Key);
Assert.AreEqual("value", de.Value);
}
[Test]
public void Test_Dictionary_ForEach()
{
string key = "A";
dictionary.Add(key, "value");
IEnumerable enumerable = dictionary;
foreach (DictionaryEntry de in enumerable)
{
Assert.AreEqual(key, de.Key);
Assert.AreEqual("value", de.Value);
}
}
[Test]
public void Test_Collisions()
{
//Create 2 keys with same hashcode but that are not equal
CollisionTester key1 = new CollisionTester(1, 100);
CollisionTester key2 = new CollisionTester(2, 100);
dictionary.Add(key1, "value1");
dictionary.Add(key2, "value2");
Assert.AreEqual("value1", dictionary[key1]);
Assert.AreEqual("value2", dictionary[key2]);
dictionary.Remove(key1);
Assert.AreEqual(null, dictionary[key1]);
}
[Test]
public void Test_Weak_1()
{
BigObject key = new BigObject(1);
BigObject key2 = new BigObject(2);
dictionary.Add(key, "value");
Assert.AreEqual("value", dictionary[key]);
key = null;
CallGC();
dictionary.Add(key2, "value2");
Assert.AreEqual(1, dictionary.Count);
}
[Test]
public void Test_Weak_2()
{
BigObject key = new BigObject(1);
BigObject key2 = new BigObject(2);
BigObject key3 = new BigObject(3);
dictionary.Add(key, "value");
dictionary.Add(key2, "value2");
Assert.AreEqual("value", dictionary[key]);
key = null;
CallGC();
dictionary.Add(key3, "value3");
Assert.AreEqual(2, dictionary.Count);
Assert.IsNotNull(key2);
}
[Test]
public void Test_Weak_ForEach()
{
BigObject[] keys1 = new BigObject[20];
BigObject[] keys2 = new BigObject[20];
for (int i = 0; i < keys1.Length; i++)
{
keys1[i] = new BigObject(i);
dictionary.Add(keys1[i], "value");
}
for (int i = 0; i < keys2.Length; i++)
{
keys2[i] = new BigObject(i);
dictionary.Add(keys2[i], "value");
}
Assert.AreEqual(40, dictionary.Count);
keys2 = null;
int count = 0;
foreach (DictionaryEntry de in dictionary)
{
CallGC();
count++;
}
Assert.LessOrEqual(20, count);
Assert.Greater(40, count);
Assert.IsNotNull(keys1);
}
}
class CollisionTester
{
int id;
int hashCode;
public CollisionTester(int id, int hashCode)
{
this.id = id;
this.hashCode = hashCode;
}
public override int GetHashCode()
{
return hashCode;
}
public override bool Equals(object obj)
{
if (obj is CollisionTester)
{
return this.id == ((CollisionTester)obj).id;
}
else
return base.Equals(obj);
}
}
[TestFixture]
public class TestWeakHashTablePerformance
{
IDictionary dictionary;
SmallObject[] keys;
[SetUp]
public void Setup()
{
dictionary = TestWeakHashTableBehavior.CreateDictionary();
}
private void Fill(IDictionary dictionary)
{
foreach (SmallObject key in keys)
dictionary.Add(key, "value");
}
[TestFixtureSetUp]
public void TestSetup()
{
keys = new SmallObject[100000];
for (int i = 0; i < keys.Length; i++)
keys[i] = new SmallObject(i);
}
[Test]
public void Test_Performance_Add()
{
for (int i = 0; i < 10; i++)
{
dictionary.Clear();
Fill(dictionary);
}
}
[Test]
public void Test_Performance_Remove()
{
for (int i = 0; i < 10; i++)
{
Fill(dictionary);
foreach (SmallObject key in keys)
dictionary.Remove(key);
}
}
[Test]
public void Test_Performance_Replace()
{
for (int i = 0; i < 10; i++)
{
foreach (SmallObject key in keys)
dictionary[key] = "value2";
}
}
[Test]
public void Test_Performance_Access()
{
Fill(dictionary);
for (int i = 0; i < 10; i++)
{
foreach (SmallObject key in keys)
{
object value = dictionary[key];
}
}
}
[Test]
public void Test_Performance_Contains()
{
Fill(dictionary);
for (int i = 0; i < 10; i++)
{
foreach (SmallObject key in keys)
{
dictionary.Contains(key);
}
}
}
[Test]
public void Test_Performance_Keys()
{
Fill(dictionary);
for (int i = 0; i < 100; i++)
{
ICollection keys = dictionary.Keys;
}
}
[Test]
public void Test_Performance_ForEach()
{
Fill(dictionary);
for (int i = 0; i < 10; i++)
{
foreach (DictionaryEntry de in dictionary)
{
}
}
}
[Test]
public void Test_Performance_CopyTo()
{
Fill(dictionary);
DictionaryEntry[] array = new DictionaryEntry[dictionary.Count];
for (int i = 0; i < 10; i++)
{
dictionary.CopyTo(array, 0);
}
}
}
internal class BigObject
{
public int i = 0;
public byte[] buf = null;
public BigObject(int i)
{
this.i = i;
buf = new byte[1024 * 1024]; //1MB
}
}
internal class SmallObject
{
public int i = 0;
public SmallObject(int i)
{
this.i = i;
}
}
}