lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mhern...@apache.org
Subject [01/50] [abbrv] git commit: Port: a bunch of Util test classes
Date Tue, 24 Sep 2013 18:32:37 GMT
Updated Branches:
  refs/heads/branch_4x ea1dc3c67 -> a8ad47860


Port: a bunch of Util test classes


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/d3c00f5a
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/d3c00f5a
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/d3c00f5a

Branch: refs/heads/branch_4x
Commit: d3c00f5a0b79338cb9fdaac7abfdfb622b948eb3
Parents: d4b0864
Author: James Blair <jmblair7@gmail.com>
Authored: Wed Jul 10 00:16:37 2013 -0400
Committer: James Blair <jmblair7@gmail.com>
Committed: Wed Jul 10 00:16:37 2013 -0400

----------------------------------------------------------------------
 test/core/Lucene.Net.Test.csproj           |  19 +-
 test/core/Support/RandomExtensions.cs      |  47 +++
 test/core/Util/ArrayUtilTest.cs            |  95 ------
 test/core/Util/StressRamUsageEstimator.cs  | 153 ++++++++++
 test/core/Util/Test2BPagedBytes.cs         |  62 ++++
 test/core/Util/TestArrayUtil.cs            | 390 ++++++++++++++++++++++++
 test/core/Util/TestAttributeSource.cs      | 120 +++-----
 test/core/Util/TestBitVector.cs            | 311 -------------------
 test/core/Util/TestByteBlockPool.cs        |  59 ++++
 test/core/Util/TestBytesRef.cs             |  68 +++++
 test/core/Util/TestBytesRefHash.cs         | 187 ++++++++++++
 test/core/Util/TestCharsRef.cs             | 147 +++++++++
 test/core/Util/TestCloseableThreadLocal.cs |  37 +--
 test/core/Util/TestCollectionUtil.cs       | 186 +++++++++++
 test/core/Util/TestDoubleBarrelLRUCache.cs | 212 +++++++++++++
 15 files changed, 1583 insertions(+), 510 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Lucene.Net.Test.csproj
----------------------------------------------------------------------
diff --git a/test/core/Lucene.Net.Test.csproj b/test/core/Lucene.Net.Test.csproj
index 212dbe8..1426b60 100644
--- a/test/core/Lucene.Net.Test.csproj
+++ b/test/core/Lucene.Net.Test.csproj
@@ -501,6 +501,7 @@
     <Compile Include="SupportClassException.cs" />
     <Compile Include="Support\BigObject.cs" />
     <Compile Include="Support\CollisionTester.cs" />
+    <Compile Include="Support\RandomExtensions.cs" />
     <Compile Include="Support\TestWeakDictionaryBehavior.cs" />
     <Compile Include="Support\TestWeakDictionary.cs" />
     <Compile Include="Support\SmallObject.cs" />
@@ -526,18 +527,23 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Support\TestSupportClass.cs" />
-    <Compile Include="Util\ArrayUtilTest.cs" />
     <Compile Include="Util\Cache\TestSimpleLRUCache.cs" />
     <Compile Include="Util\English.cs">
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Util\LocalizedTestCase.cs" />
     <Compile Include="Util\Paths.cs" />
+    <Compile Include="Util\StressRamUsageEstimator.cs" />
+    <Compile Include="Util\Test2BPagedBytes.cs" />
+    <Compile Include="Util\TestArrayUtil.cs" />
     <Compile Include="Util\TestAttributeSource.cs" />
-    <Compile Include="Util\TestBitVector.cs">
-      <SubType>Code</SubType>
-    </Compile>
+    <Compile Include="Util\TestByteBlockPool.cs" />
+    <Compile Include="Util\TestBytesRef.cs" />
+    <Compile Include="Util\TestBytesRefHash.cs" />
+    <Compile Include="Util\TestCharsRef.cs" />
     <Compile Include="Util\TestCloseableThreadLocal.cs" />
+    <Compile Include="Util\TestCollectionUtil.cs" />
+    <Compile Include="Util\TestDoubleBarrelLRUCache.cs" />
     <Compile Include="Util\TestFieldCacheSanityChecker.cs" />
     <Compile Include="Util\TestIndexableBinaryStringTools.cs" />
     <Compile Include="Util\TestNumericUtils.cs" />
@@ -622,6 +628,11 @@
   <ItemGroup>
     <Content Include="UpdatedTests.txt" />
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Util\Automaton\" />
+    <Folder Include="Util\Fst\" />
+    <Folder Include="Util\Packed\" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PreBuildEvent>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Support/RandomExtensions.cs
----------------------------------------------------------------------
diff --git a/test/core/Support/RandomExtensions.cs b/test/core/Support/RandomExtensions.cs
new file mode 100644
index 0000000..49625e5
--- /dev/null
+++ b/test/core/Support/RandomExtensions.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace Lucene.Net.Test.Support
+{
+    public static class RandomExtensions
+    {
+        private static bool BoolTieBreak = false;
+
+        public static long NextLong(this Random random)
+        {
+            return random.NextLong(long.MaxValue);
+        }
+
+        public static long NextLong(this Random random, long max)
+        {
+            return random.NextLong(0, max);
+        }
+
+        public static long NextLong(this Random random, long min, long max)
+        {
+            return (long)((random.NextDouble() * max + min) % max);
+        }
+
+        public static bool NextBool(this Random random)
+        {
+            var randInt = random.Next();
+            var adjusted = randInt - (int.MaxValue/2);
+            if (adjusted == 0)
+            {
+                BoolTieBreak = !BoolTieBreak;
+                return BoolTieBreak;
+            }
+            return adjusted > 0 ? true : false;
+        }
+
+        public static void NextBytes(this Random random, sbyte[] bytes)
+        {
+            var length = bytes.Length;
+            var randBytes = new byte[length];
+            random.NextBytes(randBytes);
+            for (var i = 0; i < bytes.Length; i++)
+            {
+                bytes[i] = (sbyte) randBytes[i];
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/ArrayUtilTest.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/ArrayUtilTest.cs b/test/core/Util/ArrayUtilTest.cs
deleted file mode 100644
index 8d312aa..0000000
--- a/test/core/Util/ArrayUtilTest.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-/* 
- * 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 NUnit.Framework;
-
-namespace Lucene.Net.Util
-{
-	
-	
-	/// <summary> 
-	/// 
-	/// 
-	/// </summary>
-    [TestFixture]
-	public class ArrayUtilTest:LuceneTestCase
-	{
-		
-        [Test]
-		public virtual void  TestParseInt()
-		{
-			int test;
-			try
-			{
-				test = ArrayUtil.ParseInt("".ToCharArray());
-				Assert.IsTrue(false);
-			}
-			catch (System.FormatException)
-			{
-				//expected
-			}
-			try
-			{
-				test = ArrayUtil.ParseInt("foo".ToCharArray());
-				Assert.IsTrue(false);
-			}
-			catch (System.FormatException)
-			{
-				//expected
-			}
-			try
-			{
-				test = ArrayUtil.ParseInt(System.Convert.ToString(System.Int64.MaxValue).ToCharArray());
-				Assert.IsTrue(false);
-			}
-			catch (System.FormatException)
-			{
-				//expected
-			}
-			try
-			{
-				test = ArrayUtil.ParseInt("0.34".ToCharArray());
-				Assert.IsTrue(false);
-			}
-			catch (System.FormatException)
-			{
-				//expected
-			}
-			
-			try
-			{
-				test = ArrayUtil.ParseInt("1".ToCharArray());
-				Assert.IsTrue(test == 1, test + " does not equal: " + 1);
-				test = ArrayUtil.ParseInt("-10000".ToCharArray());
-				Assert.IsTrue(test == - 10000, test + " does not equal: " + (- 10000));
-				test = ArrayUtil.ParseInt("1923".ToCharArray());
-				Assert.IsTrue(test == 1923, test + " does not equal: " + 1923);
-				test = ArrayUtil.ParseInt("-1".ToCharArray());
-				Assert.IsTrue(test == - 1, test + " does not equal: " + (- 1));
-				test = ArrayUtil.ParseInt("foo 1923 bar".ToCharArray(), 4, 4);
-				Assert.IsTrue(test == 1923, test + " does not equal: " + 1923);
-			}
-			catch (System.FormatException e)
-			{
-				System.Console.Error.WriteLine(e.StackTrace);
-				Assert.IsTrue(false);
-			}
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/StressRamUsageEstimator.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/StressRamUsageEstimator.cs b/test/core/Util/StressRamUsageEstimator.cs
new file mode 100644
index 0000000..8472fca
--- /dev/null
+++ b/test/core/Util/StressRamUsageEstimator.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    public class StressRamUsageEstimator : LuceneTestCase
+    {
+        internal class Entry
+        {
+            internal object o;
+            internal Entry next;
+
+            public Entry CreateNext(object o)
+            {
+                var e = new Entry {o = o, next = next};
+                this.next = e;
+                return e;
+            }
+        }
+
+        [Ignore]
+        public void TestChainedEstimation()
+        {
+            MemoryMXBean memoryMXBean = ManagementFactory.GetMemoryMXBean();
+
+            var rnd = new Random();
+            var first = new Entry();
+
+            try
+            {
+                while (true)
+                {
+                    // Check the current memory consumption and provide the estimate
+                    var jvmUsed = memoryMXBean.GetHeapMemoryUsage().GetUsed();
+                    var estimated = RamUsageEstimator.SizeOf(first);
+                    Console.WriteLine("{0}, {1}", jvmUsed, estimated);
+
+                    // Make a batch of objects
+                    for (var i = 0; i < 5000; i++)
+                    {
+                        first.CreateNext(new sbyte[rnd.Next(1024)]);
+                    }
+                }
+            }
+            catch (OutOfMemoryException ex)
+            {
+                // Release and quit
+            }
+        }
+
+        internal volatile object guard;
+
+        // This shows an easy stack overflow because we're counting recursively.
+        public void TestLargeSetOfByteArrays()
+        {
+            MemoryMXBean memoryMXBean = ManagementFactory.GetMemoryMXBean();
+
+            CauseGC();
+            var before = memoryMXBean.GetHeapMemoryUsage().GetUsed();
+            var all = new object[1000000];
+            for (var i = 0; i < all.Length; i++)
+            {
+                all[i] = new byte[new Random().Next(3)];
+            }
+            CauseGC();
+            var after = memoryMXBean.GetHeapMemoryUsage().GetUsed();
+            Console.WriteLine("mx:  " + RamUsageEstimator.HumanReadableUnits(after - before));
+            Console.WriteLine("rue: " + RamUsageEstimator.HumanReadableUnits(ShallowSizeOf(all)));
+
+            guard = all;
+        }
+
+        private long ShallowSizeOf(object[] all)
+        {
+            return RamUsageEstimator.ShallowSizeOf(all)
+                + all.Sum(o => RamUsageEstimator.ShallowSizeOf(o));
+        }
+
+        private long ShallowSizeOf(object[][] all)
+        {
+            var s = RamUsageEstimator.ShallowSizeOf(all);
+            foreach (var o in all)
+            {
+                s += RamUsageEstimator.ShallowSizeOf(o);
+                s += o.Sum(o2 => RamUsageEstimator.ShallowSizeOf(o2));
+            }
+            return s;
+        }
+
+        public void TestSimpleByteArrays()
+        {
+            MemoryMXBean memoryMXBean = ManagementFactory.GetMemoryMXBean();
+
+            var all = new object[0][];
+            try
+            {
+                while (true)
+                {
+                    // Check the current memory consumption and provide the estimate.
+                    CauseGc();
+                    var mu = memoryMXBean.GetHeapMemoryUsage();
+                    var estimated = ShallowSizeOf(all);
+                    if (estimated > 50 * RamUsageEstimator.ONE_MB)
+                    {
+                        break;
+                    }
+
+                    Console.WriteLine("{0}\t{1}]t{2}",
+                        RamUsageEstimator.HumanReadableUnits(mu.GetUsed()),
+                        RamUsageEstimator.HumanReadableUnits(mu.GetMax()),
+                        RamUsageEstimator.HumanReadableUnits(estimated));
+
+                    // Make another batch of objects.
+                    var seg = new object[10000];
+                    all = Arrays.CopyOf(all, all.Length + 1);
+                    all[all.Length - 1] = seg;
+                    for (var i = 0; i < seg.Length; i++)
+                    {
+                        seg[i] = new byte[new Random().Next(7)];
+                    }
+                }
+            }
+            catch (OutOfMemoryException ex)
+            {
+                // Release and quit.
+            }
+        }
+
+        private void CauseGc()
+        {
+            var garbageCollectorMXBeans = ManagementFactory.GetGarbageCollectorMXBeans();
+            var ccounts = new List<long>();
+            foreach (var g in garbageCollectorMXBeans)
+            {
+                ccounts.Add(g.GetCollectionCount());
+            }
+            var ccounts2 = new List<long>();
+            do
+            {
+                GC.Collect();
+                ccounts.Clear();
+                foreach (var g in garbageCollectorMXBeans)
+                {
+                    ccounts2.Add(g.GetCollectionCount());
+                }
+            } while (ccounts2.Equals(ccounts));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/Test2BPagedBytes.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/Test2BPagedBytes.cs b/test/core/Util/Test2BPagedBytes.cs
new file mode 100644
index 0000000..31fca25
--- /dev/null
+++ b/test/core/Util/Test2BPagedBytes.cs
@@ -0,0 +1,62 @@
+using System;
+using Lucene.Net.Store;
+using Lucene.Net.Test.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [Ignore("You must increase heap to > 2 G to run this")]
+    [TestFixture]
+    public class Test2BPagedBytes : LuceneTestCase
+    {
+        [Test]
+        public void Test()
+        {
+            BaseDirectoryWrapper dir = NewFSDirectory(_TestUtil.GetTempDir("test2BPagedBytes"));
+            if (dir is MockDirectoryWrapper)
+            {
+                ((MockDirectoryWrapper) dir).SetThrottling(MockDirectoryWrapper.Throttling.NEVER);
+            }
+            var pb = new PagedBytes(15);
+            IndexOutput dataOutput = dir.CreateOutput("foo", IOContext.DEFAULT);
+            long netBytes = 0;
+            var seed = new Random().Next();
+            long lastFP = 0;
+            var r2 = new Random(seed);
+            while (netBytes < 1.1*int.MaxValue)
+            {
+                var numBytes = _TestUtil.NextInt(r2, 1, 32768);
+                var bytes = new sbyte[numBytes];
+                r2.NextBytes(bytes);
+                dataOutput.WriteBytes(bytes, bytes.Length);
+                var fp = dataOutput.FilePointer;
+                // assert fp == lastFP + numBytes;
+                lastFP = fp;
+                netBytes += numBytes;
+            }
+            dataOutput.Dispose();
+            IndexInput input = dir.OpenInput("foo", IOContext.DEFAULT);
+            pb.Copy(input, input.Length);
+            input.Dispose();
+            var reader = pb.Freeze(true);
+
+            r2 = new Random(seed);
+            netBytes = 0;
+            while (netBytes < 1.1 * int.MaxValue)
+            {
+                int numBytes = _TestUtil.NextInt(r2, 1, 32768);
+                var bytes = new sbyte[numBytes];
+                r2.NextBytes(bytes);
+                var expected = new BytesRef(bytes);
+
+                var actual = new BytesRef();
+                reader.FillSlice(actual, netBytes, numBytes);
+                assertEquals(expected, actual);
+
+                netBytes += numBytes;
+            }
+            dir.Close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestArrayUtil.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestArrayUtil.cs b/test/core/Util/TestArrayUtil.cs
new file mode 100644
index 0000000..2e1b644
--- /dev/null
+++ b/test/core/Util/TestArrayUtil.cs
@@ -0,0 +1,390 @@
+using System;
+using Lucene.Net.Support;
+using Lucene.Net.Test.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestArrayUtil : LuceneTestCase
+    {
+        // Ensure ArrayUtil.getNextSize gives linear amortized cost of realloc/copy
+        [Test]
+        public void TestGrowth()
+        {
+            int currentSize = 0;
+            long copyCost = 0;
+
+            // Make sure ArrayUtil hits int.MaxValue, if we insist:
+            while (currentSize != int.MaxValue)
+            {
+                int nextSize = ArrayUtil.Oversize(1 + currentSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF);
+                Assert.IsTrue(nextSize > currentSize);
+                if (currentSize > 0)
+                {
+                    copyCost += currentSize;
+                    var copyCostPerElement = ((double)copyCost) / currentSize;
+                    Assert.IsTrue("cost " + copyCostPerElement, copyCostPerElement < 10.0);
+                }
+                currentSize = nextSize;
+            }
+        }
+
+        [Test]
+        public void TextMaxSize()
+        {
+            // Intentionally pass invalid elemSizes:
+            for (var elemSize = 0; elemSize < 10; elemSize++)
+            {
+                assertEquals(int.MaxValue, ArrayUtil.Oversize(int.MaxValue, elemSize));
+                assertEquals(int.MaxValue, ArrayUtil.Oversize(int.MaxValue - 1, elemSize));
+            }
+        }
+
+        [Test]
+        public void TestInvalidElementSizes()
+        {
+            var rnd = new Random();
+            int num = AtLeast(10000);
+            for (var iter = 0; iter < num; iter++)
+            {
+                var minTargetSize = rnd.Next(int.MaxValue);
+                var elemSize = rnd.Next(11);
+                var v = ArrayUtil.Oversize(minTargetSize, elemSize);
+                Assert.IsTrue(v >= minTargetSize);
+            }
+        }
+
+        [Test]
+        public void TestParseInt()
+        {
+            int test;
+            try
+            {
+                test = ArrayUtil.ParseInt("".ToCharArray());
+                Assert.IsTrue(false);
+            }
+            catch (FormatException e)
+            {
+                //expected
+            }
+            try
+            {
+                test = ArrayUtil.ParseInt("foo".ToCharArray());
+                Assert.IsTrue(false);
+            }
+            catch (FormatException e)
+            {
+                //expected
+            }
+            try
+            {
+                test = ArrayUtil.ParseInt(long.MaxValue.ToString().ToCharArray());
+                Assert.IsTrue(false);
+            }
+            catch (FormatException e)
+            {
+                //expected
+            }
+            try
+            {
+                test = ArrayUtil.ParseInt("0.34".ToCharArray());
+                Assert.IsTrue(false);
+            }
+            catch (FormatException e)
+            {
+                //expected
+            }
+
+            try
+            {
+                test = ArrayUtil.ParseInt("1".ToCharArray());
+                Assert.IsTrue(test == 1, test + " does not equal: " + 1);
+                test = ArrayUtil.ParseInt("-10000".ToCharArray());
+                Assert.IsTrue(test == -10000, test + " does not equal: " + -10000);
+                test = ArrayUtil.ParseInt("1923".ToCharArray());
+                Assert.IsTrue(test == 1923, test + " does not equal: " + 1923);
+                test = ArrayUtil.ParseInt("-1".ToCharArray());
+                Assert.IsTrue(test == -1, test + " does not equal: " + -1);
+                test = ArrayUtil.ParseInt("foo 1923 bar".ToCharArray(), 4, 4);
+                Assert.IsTrue(test == 1923, test + " does not equal: " + 1923);
+            }
+            catch (FormatException e)
+            {
+                Console.WriteLine(e.StackTrace);
+                Assert.IsTrue(false);
+            }
+        }
+
+        [Test]
+        public void TestSliceEquals()
+        {
+            var left = "this is equal";
+            var right = left;
+            var leftChars = left.ToCharArray();
+            var rightChars = right.ToCharArray();
+            Assert.IsTrue(ArrayUtil.Equals(leftChars, 0, rightChars, 0, left.Length), left + " does not equal: " + right);
+
+            Assert.IsFalse(ArrayUtil.Equals(leftChars, 1, rightChars, 0, left.Length), left + " does not equal: " + right);
+            Assert.IsFalse(ArrayUtil.Equals(leftChars, 1, rightChars, 2, left.Length), left + " does not equal: " + right);
+
+            Assert.IsFalse(ArrayUtil.Equals(leftChars, 25, rightChars, 0, left.Length), left + " does not equal: " + right);
+            Assert.IsFalse(ArrayUtil.Equals(leftChars, 12, rightChars, 0, left.Length), left + " does not equal: " + right);
+        }
+
+        private int[] CreateRandomArray(int maxSize)
+        {
+            var rnd = new Random();
+            var a = new int[rnd.Next(maxSize) + 1];
+            for (var i = 0; i < a.Length; i++)
+            {
+                a[i] = rnd.Next(a.Length);
+            }
+            return a;
+        }
+
+        [Test]
+        public virtual void TestQuickSort()
+        {
+            int num = AtLeast(50);
+            for (var i = 0; i < num; i++)
+            {
+                int[] a1 = CreateRandomArray(2000), a2 = (int[])a1.Clone();
+                ArrayUtil.QuickSort(a1);
+                Array.Sort(a2);
+                Assert.IsTrue(a2.Equals(a1));
+
+                a1 = CreateRandomArray(2000);
+                a2 = (int[])a1.Clone();
+                ArrayUtil.QuickSort(a1, Collections.ReverseOrder());
+                Array.Sort(a2, Collections.ReverseOrder());
+                Assert.Equals(a1, a2);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                ArrayUtil.QuickSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        private int[] CreateSparseRandomArray(int maxSize)
+        {
+            var rnd = new Random();
+            var a = new int[rnd.Next(maxSize) + 1];
+            for (var i = 0; i < a.Length; i++)
+            {
+                a[i] = rnd.Next(2);
+            }
+            return a;
+        }
+
+        [Test]
+        public virtual void TestQuickToMergeSortFallback()
+        {
+            int num = AtLeast(50);
+            for (var i = 0; i < num; i++)
+            {
+                int[] a1 = CreateSparseRandomArray(40000), a2 = (int[])a1.Clone();
+                ArrayUtil.QuickSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        [Test]
+        public virtual void TestMergeSort()
+        {
+            int num = AtLeast(50);
+            for (var i = 0; i < num; i++)
+            {
+                int[] a1 = CreateRandomArray(2000), a2 = (int[])a1.Clone();
+                ArrayUtil.MergeSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+
+                a1 = CreateRandomArray(2000);
+                a2 = (int[])a1.Clone();
+                ArrayUtil.MergeSort(a1, Collections.ReverseOrder());
+                Array.Sort(a2, Collections.ReverseOrder());
+                Assert.Equals(a2, a1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                ArrayUtil.MergeSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        [Test]
+        public virtual void TestTimSort()
+        {
+            int num = AtLeast(65);
+            for (var i = 0; i < num; i++)
+            {
+                int[] a1 = CreateRandomArray(2000), a2 = (int[])a1.Clone();
+                ArrayUtil.TimSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+
+                a1 = CreateRandomArray(2000);
+                a2 = (int[])a1.Clone();
+                ArrayUtil.TimSort(a1, Collections.ReverseOrder());
+                Array.Sort(a2, Collections.ReverseOrder());
+                Assert.Equals(a2, a1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                ArrayUtil.TimSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        [Test]
+        public virtual void TestInsertionSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                int[] a1 = CreateRandomArray(30), a2 = (int[])a1.Clone();
+                ArrayUtil.InsertionSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+
+                a1 = CreateRandomArray(30);
+                a2 = (int[])a1.Clone();
+                ArrayUtil.InsertionSort(a1, Collections.ReverseOrder());
+                Array.Sort(a2, Collections.ReverseOrder());
+                Assert.Equals(a2, a1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                ArrayUtil.InsertionSort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        [Test]
+        public virtual void TestBinarySort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                int[] a1 = CreateRandomArray(30), a2 = (int[])a1.Clone();
+                ArrayUtil.BinarySort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+
+                a1 = CreateRandomArray(30);
+                a2 = (int[])a1.Clone();
+                ArrayUtil.BinarySort(a1, Collections.ReverseOrder());
+                Array.Sort(a2, Collections.ReverseOrder());
+                Assert.Equals(a2, a1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                ArrayUtil.BinarySort(a1);
+                Array.Sort(a2);
+                Assert.Equals(a2, a1);
+            }
+        }
+
+        internal class Item : IComparable<Item>
+        {
+            int val, order;
+
+            internal Item(int val, int order)
+            {
+                this.val = val;
+                this.order = order;
+            }
+
+            public int CompareTo(Item other)
+            {
+                return this.order - other.order;
+            }
+
+            public override string ToString()
+            {
+                return val.ToString();
+            }
+        }
+
+        [Test]
+        public virtual void TestMergeSortStability()
+        {
+            var rnd = new Random();
+            var items = new Item[100];
+            for (var i = 0; i < items.Length; i++)
+            {
+                // half of the items have value but same order. The value of this items is sorted,
+                // so they should always be in order after sorting.
+                // The other half has defined order, but no (-1) value (they should appear after
+                // all above, when sorted).
+                var equal = rnd.NextBool();
+                items[i] = new Item(equal ? (i + 1) : -1, equal ? 0 : (rnd.Next(1000) + 1));
+            }
+
+            if (VERBOSE) Console.WriteLine("Before: " + Arrays.ToString(items));
+            // if you replace this with ArrayUtil.quickSort(), test should fail:
+            ArrayUtil.MergeSort(items);
+            if (VERBOSE) Console.WriteLine("Sorted: " + Arrays.ToString(items));
+
+            var last = items[0];
+            for (var i = 1; i < items.Length; i++)
+            {
+                var act = items[i];
+                if (act.Order == 0)
+                {
+                    // order of "equal" items should be not mixed up
+                    Assert.IsTrue(act.Val > last.Val);
+                }
+                Assert.IsTrue(act.Order >= last.Order);
+                last = act;
+            }
+        }
+
+        [Test]
+        public virtual void TestTimSortStability()
+        {
+            var rnd = new Random();
+            var items = new Item[100];
+            for (var i = 0; i < items.Length; i++)
+            {
+                // half of the items have value but same order. The value of this items is sorted,
+                // so they should always be in order after sorting.
+                // The other half has defined order, but no (-1) value (they should appear after
+                // all above, when sorted).
+                var equal = rnd.NextBool();
+                items[i] = new Item(equal ? (i + 1) : -1, equal ? 0 : (rnd.Next(1000) + 1));
+            }
+
+            if (VERBOSE) Console.WriteLine("Before: " + Arrays.ToString(items));
+            // if you replace this with ArrayUtil.quickSort(), test should fail:
+            ArrayUtil.TimSort(items);
+            if (VERBOSE) Console.WriteLine("Sorted: " + Arrays.ToString(items));
+
+            var last = items[0];
+            for (var i = 1; i < items.Length; i++)
+            {
+                var act = items[i];
+                if (act.Order == 0)
+                {
+                    // order of "equal" items should be not mixed up
+                    Assert.IsTrue(act.Val > last.Val);
+                }
+                Assert.IsTrue(act.Order >= last.Order);
+                last = act;
+            }
+        }
+
+        // Should produce no excepetions
+        [Test]
+        public virtual void TestEmptyArraySort()
+        {
+            var a = new int[0];
+            ArrayUtil.QuickSort(a);
+            ArrayUtil.MergeSort(a);
+            ArrayUtil.InsertionSort(a);
+            ArrayUtil.BinarySort(a);
+            ArrayUtil.TimSort(a);
+            ArrayUtil.QuickSort(a, Collections.ReverseOrder());
+            ArrayUtil.MergeSort(a, Collections.ReverseOrder());
+            ArrayUtil.TimSort(a, Collections.ReverseOrder());
+            ArrayUtil.InsertionSort(a, Collections.ReverseOrder());
+            ArrayUtil.BinarySort(a, Collections.ReverseOrder());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestAttributeSource.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestAttributeSource.cs b/test/core/Util/TestAttributeSource.cs
index 395ac16..b9d8595 100644
--- a/test/core/Util/TestAttributeSource.cs
+++ b/test/core/Util/TestAttributeSource.cs
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using System.Collections;
 using NUnit.Framework;
 
 using Token = Lucene.Net.Analysis.Token;
@@ -34,48 +34,48 @@ namespace Lucene.Net.Util
         public virtual void TestCaptureState()
         {
             // init a first instance
-            AttributeSource src = new AttributeSource();
-            ITermAttribute termAtt = src.AddAttribute<ITermAttribute>();
-            ITypeAttribute typeAtt = src.AddAttribute<ITypeAttribute>();
-            termAtt.SetTermBuffer("TestTerm");
+            var src = new AttributeSource();
+            var termAtt = src.AddAttribute<ICharTermAttribute>();
+            var typeAtt = src.AddAttribute<ITypeAttribute>();
+            termAtt.Append("TestTerm");
             typeAtt.Type = "TestType";
-            int hashCode = src.GetHashCode();
+            var hashCode = src.GetHashCode();
 
-            AttributeSource.State state = src.CaptureState();
+            var state = src.CaptureState();
 
             // modify the attributes
-            termAtt.SetTermBuffer("AnotherTestTerm");
+            termAtt.SetEmpty().Append("AnotherTestTerm");
             typeAtt.Type = "AnotherTestType";
             Assert.IsTrue(hashCode != src.GetHashCode(), "Hash code should be different");
 
             src.RestoreState(state);
-            Assert.AreEqual("TestTerm", termAtt.Term);
+            Assert.AreEqual("TestTerm", termAtt.ToString());
             Assert.AreEqual("TestType", typeAtt.Type);
             Assert.AreEqual(hashCode, src.GetHashCode(), "Hash code should be equal after restore");
 
             // restore into an exact configured copy
-            AttributeSource copy = new AttributeSource();
-            copy.AddAttribute<ITermAttribute>();
+            var copy = new AttributeSource();
+            copy.AddAttribute<ICharTermAttribute>();
             copy.AddAttribute<ITypeAttribute>();
             copy.RestoreState(state);
             Assert.AreEqual(src.GetHashCode(), copy.GetHashCode(), "Both AttributeSources should have same hashCode after restore");
             Assert.AreEqual(src, copy, "Both AttributeSources should be equal after restore");
 
             // init a second instance (with attributes in different order and one additional attribute)
-            AttributeSource src2 = new AttributeSource();
+            var src2 = new AttributeSource();
             typeAtt = src2.AddAttribute<ITypeAttribute>();
-            IFlagsAttribute flagsAtt = src2.AddAttribute<IFlagsAttribute>();
-            termAtt = src2.AddAttribute<ITermAttribute>();
+            var flagsAtt = src2.AddAttribute<IFlagsAttribute>();
+            termAtt = src2.AddAttribute<ICharTermAttribute>();
             flagsAtt.Flags = 12345;
 
             src2.RestoreState(state);
-            Assert.AreEqual("TestTerm", termAtt.Term);
+            Assert.AreEqual("TestTerm", termAtt.ToString());
             Assert.AreEqual("TestType", typeAtt.Type);
             Assert.AreEqual(12345, flagsAtt.Flags, "FlagsAttribute should not be touched");
 
             // init a third instance missing one Attribute
-            AttributeSource src3 = new AttributeSource();
-            termAtt = src3.AddAttribute<ITermAttribute>();
+            var src3 = new AttributeSource();
+            termAtt = src3.AddAttribute<ICharTermAttribute>();
 
             Assert.Throws<ArgumentException>(() => src3.RestoreState(state),
                                              "The third instance is missing the TypeAttribute, so restoreState() should throw IllegalArgumentException");
@@ -84,66 +84,35 @@ namespace Lucene.Net.Util
         [Test]
         public virtual void TestCloneAttributes()
         {
-            AttributeSource src = new AttributeSource();
-            ITermAttribute termAtt = src.AddAttribute<ITermAttribute>();
-            ITypeAttribute typeAtt = src.AddAttribute<ITypeAttribute>();
-            termAtt.SetTermBuffer("TestTerm");
+            var src = new AttributeSource();
+            var flagsAtt = src.AddAttribute<IFlagsAttribute>();
+            var typeAtt = src.AddAttribute<ITypeAttribute>();
+            flagsAtt.Flags = 1234;
             typeAtt.Type = "TestType";
 
-            AttributeSource clone = src.CloneAttributes();
-            System.Collections.Generic.IEnumerator<Type> it = clone.GetAttributeTypesIterator().GetEnumerator();
+            var clone = src.CloneAttributes();
+            var it = clone.GetAttributeTypesIterator().GetEnumerator();
             Assert.IsTrue(it.MoveNext());
-            Assert.AreEqual(typeof(ITermAttribute), it.Current, "TermAttribute must be the first attribute");
+            Assert.AreEqual(typeof(IFlagsAttribute), it.Current, "FlagsAttribute must be the first attribute");
             Assert.IsTrue(it.MoveNext());
             Assert.AreEqual(typeof(ITypeAttribute), it.Current, "TypeAttribute must be the second attribute");
             Assert.IsFalse(it.MoveNext(), "No more attributes");
 
-            ITermAttribute termAtt2 = clone.GetAttribute<ITermAttribute>();
-            ITypeAttribute typeAtt2 = clone.GetAttribute<ITypeAttribute>();
-            Assert.IsFalse(ReferenceEquals(termAtt2, termAtt), "TermAttribute of original and clone must be different instances");
-            Assert.IsFalse(ReferenceEquals(typeAtt2, typeAtt), "TypeAttribute of original and clone must be different instances");
-            Assert.AreEqual(termAtt2, termAtt, "TermAttribute of original and clone must be equal");
+            var flagsAtt2 = clone.GetAttribute<IFlagsAttribute>();
+            var typeAtt2 = clone.GetAttribute<ITypeAttribute>();
+            Assert.That(flagsAtt2 != flagsAtt, "TermAttribute of original and clone must be different instances");
+            Assert.That(typeAtt2 != typeAtt, "TypeAttribute of original and clone must be different instances");
+            Assert.AreEqual(flagsAtt2, flagsAtt, "TermAttribute of original and clone must be equal");
             Assert.AreEqual(typeAtt2, typeAtt, "TypeAttribute of original and clone must be equal");
         }
 
         [Test]
-        public virtual void TestToStringAndMultiAttributeImplementations()
-        {
-            AttributeSource src = new AttributeSource();
-            ITermAttribute termAtt = src.AddAttribute<ITermAttribute>();
-            ITypeAttribute typeAtt = src.AddAttribute<ITypeAttribute>();
-            termAtt.SetTermBuffer("TestTerm");
-            typeAtt.Type = "TestType";
-            Assert.AreEqual("(" + termAtt.ToString() + "," + typeAtt.ToString() + ")", src.ToString(), "Attributes should appear in original order");
-            System.Collections.Generic.IEnumerator<Attribute> it = src.GetAttributeImplsIterator().GetEnumerator();
-            Assert.IsTrue(it.MoveNext(), "Iterator should have 2 attributes left");
-            Assert.AreSame(termAtt, it.Current, "First AttributeImpl from iterator should be termAtt");
-            Assert.IsTrue(it.MoveNext(), "Iterator should have 1 attributes left");
-            Assert.AreSame(typeAtt, it.Current, "Second AttributeImpl from iterator should be typeAtt");
-            Assert.IsFalse(it.MoveNext(), "Iterator should have 0 attributes left");
-
-            src = new AttributeSource();
-            src.AddAttributeImpl(new Token());
-            // this should not add a new attribute as Token implements TermAttribute, too
-            termAtt = src.AddAttribute<ITermAttribute>();
-            Assert.IsTrue(termAtt is Token, "TermAttribute should be implemented by Token");
-            // get the Token attribute and check, that it is the only one
-            it = src.GetAttributeImplsIterator().GetEnumerator();
-            Assert.IsTrue(it.MoveNext());
-            Token tok = (Token)it.Current;
-            Assert.IsFalse(it.MoveNext(), "There should be only one attribute implementation instance");
-
-            termAtt.SetTermBuffer("TestTerm");
-            Assert.AreEqual("(" + tok.ToString() + ")", src.ToString(), "Token should only printed once");
-        }
-
-        [Test]
         public void TestDefaultAttributeFactory()
         {
-            AttributeSource src = new AttributeSource();
+            var src = new AttributeSource();
 
-            Assert.IsTrue(src.AddAttribute<ITermAttribute>() is TermAttribute,
-                          "TermAttribute is not implemented by TermAttributeImpl");
+            Assert.IsTrue(src.AddAttribute<ICharTermAttribute>() is CharTermAttribute,
+                          "CharTermAttribute is not implemented by CharTermAttributeImpl");
             Assert.IsTrue(src.AddAttribute<IOffsetAttribute>() is OffsetAttribute,
                           "OffsetAttribute is not implemented by OffsetAttributeImpl");
             Assert.IsTrue(src.AddAttribute<IFlagsAttribute>() is FlagsAttribute,
@@ -162,16 +131,25 @@ namespace Lucene.Net.Util
             var src = new AttributeSource();
             Assert.Throws<ArgumentException>(() => src.AddAttribute<Token>(), "Should throw ArgumentException");
 
-            src = new AttributeSource();
+            src = new AttributeSource(Token.TOKEN_ATTRIBUTE_FACTORY);
             Assert.Throws<ArgumentException>(() => src.AddAttribute<Token>(), "Should throw ArgumentException");
+        
+            src = new AttributeSource();
+            // TODO: how to fix this??
+            // orginal Java is: src.addAttribute((Class) Iterator.class);  // break this by unsafe cast
+            Assert.Throws<ArgumentException>(() => src.AddAttribute<IEnumerator>(), "Should throw ArgumentException");
+        }
 
-            //try
-            //{
-            //    AttributeSource src = new AttributeSource();
-            //    src.AddAttribute<System.Collections.IEnumerator>(); //Doesn't compile.
-            //    Assert.Fail("Should throw IllegalArgumentException");
-            //}
-            //catch (ArgumentException iae) { }
+        [Test]
+        public void TestLUCENE_3042()
+        {
+            var src1 = new AttributeSource();
+            src1.AddAttribute<ICharTermAttribute>().Append("foo");
+            var hash1 = src1.GetHashCode(); // this triggers a cached state
+            var src2 = new AttributeSource(src1);
+            src2.AddAttribute<ITypeAttribute>().Type = "bar";
+            Assert.True(hash1 != src1.GetHashCode(), "The hashCode is identical, so the captured state was preserved.");
+            Assert.Equals(src2.GetHashCode(), src1.GetHashCode());
         }
     }
     

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestBitVector.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestBitVector.cs b/test/core/Util/TestBitVector.cs
deleted file mode 100644
index 69798f3..0000000
--- a/test/core/Util/TestBitVector.cs
+++ /dev/null
@@ -1,311 +0,0 @@
-/* 
- * 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 NUnit.Framework;
-
-using Directory = Lucene.Net.Store.Directory;
-using RAMDirectory = Lucene.Net.Store.RAMDirectory;
-
-namespace Lucene.Net.Util
-{
-	
-	/// <summary> <c>TestBitVector</c> tests the <c>BitVector</c>, obviously.
-	/// 
-	/// 
-	/// </summary>
-	/// <version>  $Id: TestBitVector.java 765649 2009-04-16 14:29:26Z mikemccand $
-	/// </version>
-	[TestFixture]
-	public class TestBitVector:LuceneTestCase
-	{
-		
-		/// <summary> Test the default constructor on BitVectors of various sizes.</summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestConstructSize()
-		{
-			DoTestConstructOfSize(8);
-			DoTestConstructOfSize(20);
-			DoTestConstructOfSize(100);
-			DoTestConstructOfSize(1000);
-		}
-		
-		private void  DoTestConstructOfSize(int n)
-		{
-			BitVector bv = new BitVector(n);
-			Assert.AreEqual(n, bv.Size());
-		}
-		
-		/// <summary> Test the get() and set() methods on BitVectors of various sizes.</summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestGetSet()
-		{
-			DoTestGetSetVectorOfSize(8);
-			DoTestGetSetVectorOfSize(20);
-			DoTestGetSetVectorOfSize(100);
-			DoTestGetSetVectorOfSize(1000);
-		}
-		
-		private void  DoTestGetSetVectorOfSize(int n)
-		{
-			BitVector bv = new BitVector(n);
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				// ensure a set bit can be git'
-				Assert.IsFalse(bv.Get(i));
-				bv.Set(i);
-				Assert.IsTrue(bv.Get(i));
-			}
-		}
-		
-		/// <summary> Test the clear() method on BitVectors of various sizes.</summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestClear()
-		{
-			DoTestClearVectorOfSize(8);
-			DoTestClearVectorOfSize(20);
-			DoTestClearVectorOfSize(100);
-			DoTestClearVectorOfSize(1000);
-		}
-		
-		private void  DoTestClearVectorOfSize(int n)
-		{
-			BitVector bv = new BitVector(n);
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				// ensure a set bit is cleared
-				Assert.IsFalse(bv.Get(i));
-				bv.Set(i);
-				Assert.IsTrue(bv.Get(i));
-				bv.Clear(i);
-				Assert.IsFalse(bv.Get(i));
-			}
-		}
-		
-		/// <summary> Test the count() method on BitVectors of various sizes.</summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestCount()
-		{
-			DoTestCountVectorOfSize(8);
-			DoTestCountVectorOfSize(20);
-			DoTestCountVectorOfSize(100);
-			DoTestCountVectorOfSize(1000);
-		}
-		
-		private void  DoTestCountVectorOfSize(int n)
-		{
-			BitVector bv = new BitVector(n);
-			// test count when incrementally setting bits
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				Assert.IsFalse(bv.Get(i));
-				Assert.AreEqual(i, bv.Count());
-				bv.Set(i);
-				Assert.IsTrue(bv.Get(i));
-				Assert.AreEqual(i + 1, bv.Count());
-			}
-			
-			bv = new BitVector(n);
-			// test count when setting then clearing bits
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				Assert.IsFalse(bv.Get(i));
-				Assert.AreEqual(0, bv.Count());
-				bv.Set(i);
-				Assert.IsTrue(bv.Get(i));
-				Assert.AreEqual(1, bv.Count());
-				bv.Clear(i);
-				Assert.IsFalse(bv.Get(i));
-				Assert.AreEqual(0, bv.Count());
-			}
-		}
-		
-		/// <summary> Test writing and construction to/from Directory.</summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestWriteRead()
-		{
-			DoTestWriteRead(8);
-			DoTestWriteRead(20);
-			DoTestWriteRead(100);
-			DoTestWriteRead(1000);
-		}
-		
-		private void  DoTestWriteRead(int n)
-		{
-			Directory d = new RAMDirectory();
-			
-			BitVector bv = new BitVector(n);
-			// test count when incrementally setting bits
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				Assert.IsFalse(bv.Get(i));
-				Assert.AreEqual(i, bv.Count());
-				bv.Set(i);
-				Assert.IsTrue(bv.Get(i));
-				Assert.AreEqual(i + 1, bv.Count());
-				bv.Write(d, "TESTBV");
-				BitVector compare = new BitVector(d, "TESTBV");
-				// compare bit vectors with bits set incrementally
-				Assert.IsTrue(DoCompare(bv, compare));
-			}
-		}
-		
-		/// <summary> Test r/w when size/count cause switching between bit-set and d-gaps file formats.  </summary>
-		/// <throws>  Exception </throws>
-		[Test]
-		public virtual void  TestDgaps()
-		{
-			DoTestDgaps(1, 0, 1);
-			DoTestDgaps(10, 0, 1);
-			DoTestDgaps(100, 0, 1);
-			DoTestDgaps(1000, 4, 7);
-			DoTestDgaps(10000, 40, 43);
-			DoTestDgaps(100000, 415, 418);
-			DoTestDgaps(1000000, 3123, 3126);
-		}
-		
-		private void  DoTestDgaps(int size, int count1, int count2)
-		{
-			Directory d = new RAMDirectory();
-			BitVector bv = new BitVector(size);
-			for (int i = 0; i < count1; i++)
-			{
-				bv.Set(i);
-				Assert.AreEqual(i + 1, bv.Count());
-			}
-			bv.Write(d, "TESTBV");
-			// gradually increase number of set bits
-			for (int i = count1; i < count2; i++)
-			{
-				BitVector bv2 = new BitVector(d, "TESTBV");
-				Assert.IsTrue(DoCompare(bv, bv2));
-				bv = bv2;
-				bv.Set(i);
-				Assert.AreEqual(i + 1, bv.Count());
-				bv.Write(d, "TESTBV");
-			}
-			// now start decreasing number of set bits
-			for (int i = count2 - 1; i >= count1; i--)
-			{
-				BitVector bv2 = new BitVector(d, "TESTBV");
-				Assert.IsTrue(DoCompare(bv, bv2));
-				bv = bv2;
-				bv.Clear(i);
-				Assert.AreEqual(i, bv.Count());
-				bv.Write(d, "TESTBV");
-			}
-		}
-		/// <summary> Compare two BitVectors.
-		/// This should really be an equals method on the BitVector itself.
-		/// </summary>
-		/// <param name="bv">One bit vector
-		/// </param>
-		/// <param name="compare">The second to compare
-		/// </param>
-		private bool DoCompare(BitVector bv, BitVector compare)
-		{
-			bool equal = true;
-			for (int i = 0; i < bv.Size(); i++)
-			{
-				// bits must be equal
-				if (bv.Get(i) != compare.Get(i))
-				{
-					equal = false;
-					break;
-				}
-			}
-			return equal;
-		}
-		
-		private static int[] subsetPattern = new int[]{1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1};
-		
-		/// <summary> Tests BitVector.subset() against the above pattern</summary>
-		[Test]
-		public virtual void  TestSubset()
-		{
-			DoTestSubset(0, 0);
-			DoTestSubset(0, 20);
-			DoTestSubset(0, 7);
-			DoTestSubset(0, 8);
-			DoTestSubset(0, 9);
-			DoTestSubset(0, 15);
-			DoTestSubset(0, 16);
-			DoTestSubset(0, 17);
-			DoTestSubset(1, 7);
-			DoTestSubset(1, 8);
-			DoTestSubset(1, 9);
-			DoTestSubset(1, 15);
-			DoTestSubset(1, 16);
-			DoTestSubset(1, 17);
-			DoTestSubset(2, 20);
-			DoTestSubset(3, 20);
-			DoTestSubset(4, 20);
-			DoTestSubset(5, 20);
-			DoTestSubset(6, 20);
-			DoTestSubset(7, 14);
-			DoTestSubset(7, 15);
-			DoTestSubset(7, 16);
-			DoTestSubset(8, 15);
-			DoTestSubset(9, 20);
-			DoTestSubset(10, 20);
-			DoTestSubset(11, 20);
-			DoTestSubset(12, 20);
-			DoTestSubset(13, 20);
-		}
-		
-		/// <summary> Compare a subset against the corresponding portion of the test pattern</summary>
-		private void  DoTestSubset(int start, int end)
-		{
-			BitVector full = CreateSubsetTestVector();
-			BitVector subset = full.Subset(start, end);
-			Assert.AreEqual(end - start, subset.Size());
-			int count = 0;
-			for (int i = start, j = 0; i < end; i++, j++)
-			{
-				if (subsetPattern[i] == 1)
-				{
-					count++;
-					Assert.IsTrue(subset.Get(j));
-				}
-				else
-				{
-					Assert.IsFalse(subset.Get(j));
-				}
-			}
-			Assert.AreEqual(count, subset.Count());
-		}
-		
-		private BitVector CreateSubsetTestVector()
-		{
-			BitVector bv = new BitVector(subsetPattern.Length);
-			for (int i = 0; i < subsetPattern.Length; i++)
-			{
-				if (subsetPattern[i] == 1)
-				{
-					bv.Set(i);
-				}
-			}
-			return bv;
-		}
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestByteBlockPool.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestByteBlockPool.cs b/test/core/Util/TestByteBlockPool.cs
new file mode 100644
index 0000000..cef6110
--- /dev/null
+++ b/test/core/Util/TestByteBlockPool.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using Lucene.Net.Test.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestByteBlockPool : LuceneTestCase
+    {
+        [Test]
+        public void TestReadAndWrite()
+        {
+            var random = new Random();
+
+            Counter bytesUsed = Counter.NewCounter();
+            var pool = new ByteBlockPool(new ByteBlockPool.DirectTrackingAllocator(bytesUsed));
+            pool.NextBuffer();
+            var reuseFirst = random.NextBool();
+            for (var j = 0; j < 2; j++)
+            {
+
+                var list = new List<BytesRef>();
+                int maxLength = AtLeast(500);
+                int numValues = AtLeast(100);
+                var bytesRef = new BytesRef();
+                for (var i = 0; i < numValues; i++)
+                {
+                    string value = _TestUtil.RandomRealisticUnicodeString(random,
+                       maxLength);
+                    list.Add(new BytesRef(value));
+                    bytesRef.CopyChars(value);
+                    pool.Append(bytesRef);
+                }
+                // verify
+                long position = 0;
+                foreach (var expected in list)
+                {
+                    bytesRef.Grow(expected.length);
+                    bytesRef.length = expected.length;
+                    pool.ReadBytes(position, bytesRef.bytes, bytesRef.offset, bytesRef.length);
+                    assertEquals(expected, bytesRef);
+                    position += bytesRef.length;
+                }
+                pool.Reset(random.NextBool(), reuseFirst);
+                if (reuseFirst)
+                {
+                    assertEquals(ByteBlockPool.BYTE_BLOCK_SIZE, bytesUsed.Get());
+                }
+                else
+                {
+                    assertEquals(0, bytesUsed.Get());
+                    pool.NextBuffer(); // prepare for next iter
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestBytesRef.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestBytesRef.cs b/test/core/Util/TestBytesRef.cs
new file mode 100644
index 0000000..4e8b0b9
--- /dev/null
+++ b/test/core/Util/TestBytesRef.cs
@@ -0,0 +1,68 @@
+using System;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestBytesRef : LuceneTestCase
+    {
+        [Test]
+        public void TestEmpty()
+        {
+            var b = new BytesRef();
+            Assert.Equals(BytesRef.EMPTY_BYTES, b.bytes);
+            Assert.Equals(0, b.offset);
+            Assert.Equals(0, b.length);
+        }
+
+        [Test]
+        public void TestFromBytes()
+        {
+            var bytes = new sbyte[] { (sbyte)'a', (sbyte)'b', (sbyte)'c', (sbyte)'d' };
+            var b = new BytesRef(bytes);
+            Assert.Equals(bytes, b.bytes);
+            Assert.Equals(0, b.offset);
+            Assert.Equals(4, b.length);
+
+            var b2 = new BytesRef(bytes, 1, 3);
+            Assert.Equals("bcd", b2.Utf8ToString());
+
+            Assert.IsFalse(b.Equals(b2));
+        }
+
+        [Test]
+        public void TestFromChars()
+        {
+            for (var i = 0; i < 100; i++)
+            {
+                string s = _TestUtil.RandomUnicodeString(new Random());
+                string s2 = new BytesRef(s).Utf8ToString();
+                Assert.Equals(s, s2);
+            }
+
+            // only for 4.x
+            Assert.Equals("\uFFFF", new BytesRef("\uFFFF").Utf8ToString());
+        }
+
+        // LUCENE-3590, AIOOBE if you append to a bytesref with offset != 0
+        [Test]
+        public void TestAppend()
+        {
+            var bytes = new sbyte[] { (sbyte)'a', (sbyte)'b', (sbyte)'c', (sbyte)'d' };
+            var b = new BytesRef(bytes, 1, 3); // bcd
+            b.Append(new BytesRef("e"));
+            Assert.Equals("bcde", b.Utf8ToString());
+        }
+
+        // LUCENE-3590, AIOOBE if you copy to a bytesref with offset != 0
+        [Test]
+        public void TestCopyBytes()
+        {
+            var bytes = new sbyte[] { (sbyte)'a', (sbyte)'b', (sbyte)'c', (sbyte)'d' };
+            var b = new BytesRef(bytes, 1, 3); // bcd
+            b.CopyBytes(new BytesRef("bcde"));
+            Assert.Equals("bcde", b.Utf8ToString());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestBytesRefHash.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestBytesRefHash.cs b/test/core/Util/TestBytesRefHash.cs
new file mode 100644
index 0000000..a950da6
--- /dev/null
+++ b/test/core/Util/TestBytesRefHash.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Collections.Generic;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+using System.Linq;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestBytesRefHash : LuceneTestCase
+    {
+        private IList<int> CreateRandomList(int maxSize)
+        {
+            var rnd = new Random();
+            var a = new int[rnd.Next(maxSize) + 1];
+            for (var i = 0; i < a.Length; i++)
+            {
+                a[i] = rnd.Next(a.Length);
+            }
+            return a.ToList();
+        }
+
+        [Test]
+        public void TestQuickSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000);
+                var list2 = new List<int>(list1);
+                CollectionUtil.QuickSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.QuickSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.QuickSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestMergeSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000);
+                var list2 = new List<int>(list1);
+                CollectionUtil.MergeSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.MergeSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.MergeSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestTimSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000);
+                var list2 = new List<int>(list1);
+                CollectionUtil.TimSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.TimSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.TimSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestInsertionSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(30);
+                var list2 = new List<int>(list1);
+                CollectionUtil.InsertionSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(30);
+                list2 = new List<int>(list1);
+                CollectionUtil.InsertionSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.InsertionSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestBinarySort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(30);
+                var list2 = new List<int>(list1);
+                CollectionUtil.BinarySort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(30);
+                list2 = new List<int>(list1);
+                CollectionUtil.BinarySort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.BinarySort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestEmptyListSort()
+        {
+            // should produce no exceptions
+            IList<int> list = new int[0].ToList(); // LUCENE-2989
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+
+            // check that empty non-random access lists pass sorting without ex (as sorting is not needed)
+            list = new LinkedList<int>();
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+        }
+
+        [Test]
+        public void TestOneElementListSort()
+        {
+            // check that one-element non-random access lists pass sorting without ex (as sorting is not needed)
+            IList<int> list = new LinkedList<int>();
+            list.Add(1);
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestCharsRef.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestCharsRef.cs b/test/core/Util/TestCharsRef.cs
new file mode 100644
index 0000000..e6da517
--- /dev/null
+++ b/test/core/Util/TestCharsRef.cs
@@ -0,0 +1,147 @@
+using System;
+using System.Text;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestCharsRef : LuceneTestCase
+    {
+        [Test]
+        public void TestUTF16InUTF8Order()
+        {
+            int numStrings = AtLeast(1000);
+            var utf8 = new BytesRef[numStrings];
+            var utf16 = new CharsRef[numStrings];
+
+            for (var i = 0; i < numStrings; i++)
+            {
+                string s = _TestUtil.RandomUnicodeString(new Random());
+                utf8[i] = new BytesRef(s);
+                utf16[i] = new CharsRef(s);
+            }
+
+            Array.Sort(utf8);
+            Array.Sort(utf16, CharsRef.GetUTF16SortedAsUTF8Comparator());
+
+            for (var i = 0; i < numStrings; i++)
+            {
+                Assert.Equals(utf8[i].Utf8ToString(), utf16[i].ToString());
+            }
+        }
+
+        [Test]
+        public void TestAppend()
+        {
+            var charsRef = new CharsRef();
+            var builder = new StringBuilder();
+            int numStrings = atLeast(10);
+            for (var i = 0; i < numStrings; i++)
+            {
+                char[] charArray = _TestUtil.RandomRealisticUnicodeString(new Random(), 1, 100).ToCharArray();
+                var offset = new Random().Next(charArray.Length);
+                var length = charArray.Length - offset;
+                builder.Append(charArray, offset, length);
+                charsRef.Append(charArray, offset, length);
+            }
+
+            Assert.Equals(builder.ToString(), charsRef.ToString());
+        }
+
+        [Test]
+        public void TestCopy()
+        {
+            int numIters = AtLeast(10);
+            for (var i = 0; i < numIters; i++)
+            {
+                var charsRef = new CharsRef();
+                char[] charArray = _TestUtil.RandomRealisticUnicodeString(new Random(), 1, 100).ToCharArray();
+                var offset = new Random().Next(charArray.Length);
+                var Length = charArray.Length - offset;
+                var str = new string(charArray, offset, Length);
+                charsRef.CopyChars(charArray, offset, Length);
+                Assert.Equals(str, charsRef.ToString());
+            }
+        }
+
+        // LUCENE-3590, AIOOBE if you Append to a charsref with offset != 0
+        [Test]
+        public void TestAppendChars()
+        {
+            var chars = new char[] { 'a', 'b', 'c', 'd' };
+            var c = new CharsRef(chars, 1, 3); // bcd
+            c.Append(new char[] { 'e' }, 0, 1);
+            Assert.Equals("bcde", c.ToString());
+        }
+
+        // LUCENE-3590, AIOOBE if you copy to a charsref with offset != 0
+        [Test]
+        public void TestCopyChars()
+        {
+            var chars = new char[] { 'a', 'b', 'c', 'd' };
+            var c = new CharsRef(chars, 1, 3); // bcd
+            var otherchars = new char[] { 'b', 'c', 'd', 'e' };
+            c.CopyChars(otherchars, 0, 4);
+            Assert.Equals("bcde", c.ToString());
+        }
+
+        // LUCENE-3590, AIOOBE if you copy to a charsref with offset != 0
+        [Test]
+        public void TestCopyCharsRef()
+        {
+            var chars = new char[] { 'a', 'b', 'c', 'd' };
+            var c = new CharsRef(chars, 1, 3); // bcd
+            char otherchars = new char[] { 'b', 'c', 'd', 'e' };
+            c.CopyChars(new CharsRef(otherchars, 0, 4));
+            Assert.Equals("bcde", c.ToString());
+        }
+
+        // LUCENE-3590: fix charsequence to fully obey interface
+        [Test]
+        public void TestCharSequenceCharAt()
+        {
+            var c = new CharsRef("abc");
+
+            Assert.Equals('b', c.CharAt(1));
+
+            Assert.Throws<IndexOutOfRangeException>(() => c.CharAt(-1));
+            Assert.Throws<IndexOutOfRangeException>(() => c.CharAt(3));
+        }
+
+        // LUCENE-3590: fix off-by-one in subsequence, and fully obey interface
+        // LUCENE-4671: fix SubSequence
+        [Test]
+        public void TestCharSequenceSubSequence()
+        {
+            var sequences = new[] {
+                new CharsRef("abc"),
+                new CharsRef("0abc".ToCharArray(), 1, 3),
+                new CharsRef("abc0".ToCharArray(), 0, 3),
+                new CharsRef("0abc0".ToCharArray(), 1, 3)
+            };
+
+            foreach (var c in sequences)
+            {
+                DoTestSequence(c);
+            }
+        }
+
+        private void DoTestSequence(CharSequence c)
+        {
+            // slice
+            Assert.Equals("a", c.SubSequence(0, 1).toString());
+            // mid subsequence
+            Assert.Equals("b", c.SubSequence(1, 2).toString());
+            // end subsequence
+            Assert.Equals("bc", c.SubSequence(1, 3).toString());
+            // empty subsequence
+            Assert.Equals("", c.SubSequence(0, 0).toString());
+
+            Assert.Throws<IndexOutOfRangeException>(() => c.SubSequence(-1, 1));
+            Assert.Throws<IndexOutOfRangeException>(() => c.SubSequence(0, -1));
+            Assert.Throws<IndexOutOfRangeException>(() => c.SubSequence(0, 4));
+            Assert.Throws<IndexOutOfRangeException>(() => c.SubSequence(2, 1));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestCloseableThreadLocal.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestCloseableThreadLocal.cs b/test/core/Util/TestCloseableThreadLocal.cs
index 0cc4fbd..f7b55a9 100644
--- a/test/core/Util/TestCloseableThreadLocal.cs
+++ b/test/core/Util/TestCloseableThreadLocal.cs
@@ -15,23 +15,20 @@
  * limitations under the License.
  */
 
-using System;
-
 using NUnit.Framework;
 
 namespace Lucene.Net.Util
 {
-	
     [TestFixture]
-	public class TestCloseableThreadLocal:LuceneTestCase
+	public class TestCloseableThreadLocal : LuceneTestCase
 	{
-		public const System.String TEST_VALUE = "initvaluetest";
+		public const string TEST_VALUE = "initvaluetest";
 		
         [Test]
 		public virtual void  TestInitValue()
 		{
-			InitValueThreadLocal tl = new InitValueThreadLocal(this);
-			System.String str = (System.String) tl.Get();
+			var tl = new InitValueThreadLocal();
+			var str = (string) tl.Get();
 			Assert.AreEqual(TEST_VALUE, str);
 		}
 		
@@ -40,7 +37,7 @@ namespace Lucene.Net.Util
 		{
 			// Tests that null can be set as a valid value (LUCENE-1805). This
 			// previously failed in get().
-            CloseableThreadLocal<object> ctl = new CloseableThreadLocal<object>();
+            var ctl = new CloseableThreadLocal<object>();
 			ctl.Set(null);
 			Assert.IsNull(ctl.Get());
 		}
@@ -50,33 +47,15 @@ namespace Lucene.Net.Util
 		{
 			// LUCENE-1805: make sure default get returns null,
 			// twice in a row
-            CloseableThreadLocal<object> ctl = new CloseableThreadLocal<object>();
-			Assert.IsNull(ctl.Get());
+            var ctl = new CloseableThreadLocal<object>();
 			Assert.IsNull(ctl.Get());
 		}
 
         public class InitValueThreadLocal : CloseableThreadLocal<object>
 		{
-			public InitValueThreadLocal(TestCloseableThreadLocal enclosingInstance)
-			{
-				InitBlock(enclosingInstance);
-			}
-			private void  InitBlock(TestCloseableThreadLocal enclosingInstance)
-			{
-				this.enclosingInstance = enclosingInstance;
-			}
-			private TestCloseableThreadLocal enclosingInstance;
-			public TestCloseableThreadLocal Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			public /*protected internal*/ override System.Object InitialValue()
+			public /*protected internal*/ override object InitialValue()
 			{
-				return Lucene.Net.Util.TestCloseableThreadLocal.TEST_VALUE;
+				return TEST_VALUE;
 			}
 		}
 	}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestCollectionUtil.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestCollectionUtil.cs b/test/core/Util/TestCollectionUtil.cs
new file mode 100644
index 0000000..baa7bca
--- /dev/null
+++ b/test/core/Util/TestCollectionUtil.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestCollectionUtil : LuceneTestCase
+    {
+        private List<int> CreateRandomList(int maxSize)
+        {
+            Random rnd = new Random();
+            int[] a = new int[rnd.Next(maxSize) + 1];
+            for (int i = 0; i < a.Length; i++)
+            {
+                a[i] = rnd.Next(a.Length);
+            }
+            return a.ToList();
+        }
+
+        [Test]
+        public void TestQuickSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000);
+                var list2 = new List<int>(list1);
+                CollectionUtil.QuickSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.QuickSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.QuickSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestMergeSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000); 
+                var list2 = new List<int>(list1);
+                CollectionUtil.MergeSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.MergeSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.MergeSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestTimSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(2000);
+                var list2 = new List<int>(list1);
+                CollectionUtil.TimSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(2000);
+                list2 = new List<int>(list1);
+                CollectionUtil.TimSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.TimSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestInsertionSort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                var list1 = CreateRandomList(30);
+                var list2 = new List<int>(list1);
+                CollectionUtil.InsertionSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(30);
+                list2 = new List<int>(list1);
+                CollectionUtil.InsertionSort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.InsertionSort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestBinarySort()
+        {
+            for (int i = 0, c = AtLeast(500); i < c; i++)
+            {
+                List<int> list1 = CreateRandomList(30), list2 = new List<int>(list1);
+                CollectionUtil.BinarySort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+
+                list1 = CreateRandomList(30);
+                list2 = new List<int>(list1);
+                CollectionUtil.BinarySort(list1, Collections.ReverseOrder());
+                Collections.Sort(list2, Collections.ReverseOrder());
+                assertEquals(list2, list1);
+                // reverse back, so we can test that completely backwards sorted array (worst case) is working:
+                CollectionUtil.BinarySort(list1);
+                Collections.Sort(list2);
+                assertEquals(list2, list1);
+            }
+        }
+
+        [Test]
+        public void TestEmptyListSort()
+        {
+            // should produce no exceptions
+            List<int> list = new List<int>(); // LUCENE-2989
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+
+            // check that empty non-new Random access lists pass sorting without ex (as sorting is not needed)
+            list = new LinkedList<int>();
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+        }
+
+        [Test]
+        public void TestOneElementListSort()
+        {
+            // check that one-element non-new Random access lists pass sorting without ex (as sorting is not needed)
+            List<int> list = new LinkedList<int>();
+            list.Add(1);
+            CollectionUtil.QuickSort(list);
+            CollectionUtil.MergeSort(list);
+            CollectionUtil.TimSort(list);
+            CollectionUtil.InsertionSort(list);
+            CollectionUtil.BinarySort(list);
+            CollectionUtil.QuickSort(list, Collections.ReverseOrder());
+            CollectionUtil.MergeSort(list, Collections.ReverseOrder());
+            CollectionUtil.TimSort(list, Collections.ReverseOrder());
+            CollectionUtil.InsertionSort(list, Collections.ReverseOrder());
+            CollectionUtil.BinarySort(list, Collections.ReverseOrder());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/d3c00f5a/test/core/Util/TestDoubleBarrelLRUCache.cs
----------------------------------------------------------------------
diff --git a/test/core/Util/TestDoubleBarrelLRUCache.cs b/test/core/Util/TestDoubleBarrelLRUCache.cs
new file mode 100644
index 0000000..fabe4ab
--- /dev/null
+++ b/test/core/Util/TestDoubleBarrelLRUCache.cs
@@ -0,0 +1,212 @@
+using System;
+using Lucene.Net.Support;
+using Lucene.Net.Util;
+using NUnit.Framework;
+
+namespace Lucene.Net.Test.Util
+{
+    [TestFixture]
+    public class TestDoubleBarrelLRUCache : LuceneTestCase
+    {
+        [Test]
+        private void TestCache(DoubleBarrelLRUCache<CloneableInteger, object> cache, int n)
+        {
+            var dummy = new object();
+
+            for (var i = 0; i < n; i++)
+            {
+                cache[new CloneableInteger(i)] = dummy;
+            }
+
+            // access every 2nd item in cache
+            for (var i = 0; i < n; i += 2)
+            {
+                assertNotNull(cache[new CloneableInteger(i)]);
+            }
+
+            // add n/2 elements to cache, the ones that weren't
+            // touched in the previous loop should now be thrown away
+            for (var i = n; i < n + (n / 2); i++)
+            {
+                cache[new CloneableInteger(i)] = dummy;
+            }
+
+            // access every 4th item in cache
+            for (var i = 0; i < n; i += 4)
+            {
+                assertNotNull(cache[new CloneableInteger(i)]);
+            }
+
+            // add 3/4n elements to cache, the ones that weren't
+            // touched in the previous loops should now be thrown away
+            for (var i = n; i < n + (n * 3 / 4); i++)
+            {
+                cache[new CloneableInteger(i)] = dummy;
+            }
+
+            // access every 4th item in cache
+            for (var i = 0; i < n; i += 4)
+            {
+                assertNotNull(cache[new CloneableInteger(i)]);
+            }
+        }
+
+        [Test]
+        public void TestLRUCache()
+        {
+            var n = 100;
+            TestCache(new DoubleBarrelLRUCache<CloneableInteger, object>(n), n);
+        }
+
+        private class CacheThread : ThreadClass
+        {
+            private TestDoubleBarrelLRUCache parent;
+
+            private CloneableObject[] objs;
+            private DoubleBarrelLRUCache<CloneableObject, object> c;
+            private DateTime endTime;
+            volatile bool failed;
+
+            public CacheThread(TestDoubleBarrelLRUCache parent, DoubleBarrelLRUCache<CloneableObject, object> c,
+                               CloneableObject[] objs, long endTime)
+            {
+                this.parent = parent;
+
+                this.c = c;
+                this.objs = objs;
+                this.endTime = new DateTime(1970, 1, 1).AddMilliseconds(endTime);
+            }
+
+            public override void Run()
+            {
+                try
+                {
+                    long count = 0;
+                    long miss = 0;
+                    long hit = 0;
+                    var limit = objs.Length;
+
+                    while (true)
+                    {
+                        var obj = objs[(int)((count / 2) % limit)];
+                        var v = c[obj];
+                        if (v == null)
+                        {
+                            c[new CloneableObject(obj)] = obj;
+                            //c.Put(new CloneableObject(obj), obj);
+                            miss++;
+                        }
+                        else
+                        {
+                            //assert obj == v;
+                            hit++;
+                        }
+                        if ((++count % 10000) == 0)
+                        {
+                            if (DateTime.Now >= endTime)
+                            {
+                                break;
+                            }
+                        }
+                    }
+
+                    parent.AddResults(miss, hit);
+                }
+                catch (Exception e)
+                {
+                    failed = true;
+                    throw;
+                }
+            }
+        }
+
+        long totMiss, totHit;
+        void AddResults(long miss, long hit)
+        {
+            totMiss += miss;
+            totHit += hit;
+        }
+
+        [Test]
+        public void TestThreadCorrectness()
+        {
+            var NUM_THREADS = 4;
+            var CACHE_SIZE = 512;
+            var OBJ_COUNT = 3 * CACHE_SIZE;
+
+            var c = new DoubleBarrelLRUCache<CloneableObject, object>(1024);
+
+            var objs = new CloneableObject[OBJ_COUNT];
+            for (var i = 0; i < OBJ_COUNT; i++)
+            {
+                objs[i] = new CloneableObject(new object());
+            }
+
+            var threads = new CacheThread[NUM_THREADS];
+            var endTime = (long)((DateTime.Now.Subtract(new DateTime(1970, 1, 1))
+                .Add(TimeSpan.FromMilliseconds(1000))).TotalMilliseconds);
+            //long endTime = System.currentTimeMillis() + 1000L;
+            for (var i = 0; i < NUM_THREADS; i++)
+            {
+                threads[i] = new CacheThread(this, c, objs, endTime);
+                threads[i].Start();
+            }
+            for (var i = 0; i < NUM_THREADS; i++)
+            {
+                threads[i].Join();
+                //assert !threads[i].failed;
+            }
+            //System.out.println("hits=" + totHit + " misses=" + totMiss);
+        }
+
+        public class CloneableObject : DoubleBarrelLRUCache.CloneableKey
+        {
+            private object value;
+
+            public CloneableObject(object value)
+            {
+                this.value = value;
+            }
+
+            public override bool Equals(object other)
+            {
+                return this.value.Equals(((CloneableObject)other).value);
+            }
+
+            public override int GetHashCode()
+            {
+                return value.GetHashCode();
+            }
+
+            public override DoubleBarrelLRUCache.CloneableKey Clone()
+            {
+                return new CloneableObject(value);
+            }
+        }
+
+        public class CloneableInteger : DoubleBarrelLRUCache.CloneableKey
+        {
+            private int value;
+
+            public CloneableInteger(int value)
+            {
+                this.value = value;
+            }
+
+            public override bool Equals(object other)
+            {
+                return this.value.Equals(((CloneableInteger)other).value);
+            }
+
+            public override int GetHashCode()
+            {
+                return value.GetHashCode();
+            }
+
+            public override DoubleBarrelLRUCache.CloneableKey Clone()
+            {
+                return new CloneableInteger(value);
+            }
+        }
+    }
+}


Mime
View raw message