blob: d292a62d9f3b6b3e274d71bb6046e89078efafc3 [file] [log] [blame]
using NUnit.Framework;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
using Assert = Lucene.Net.TestFramework.Assert;
#if !FEATURE_RANDOM_NEXTINT64_NEXTSINGLE
using RandomizedTesting.Generators; // for Random.NextInt64 extension method
#endif
namespace Lucene.Net.Util
{
/*
* 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.
*/
[TestFixture]
public class TestMergedIterator : LuceneTestCase
{
private const int REPEATS = 2;
private const int VALS_TO_MERGE = 15000;
[Test]
public virtual void TestMergeEmpty()
{
IEnumerator<int> merged = new MergedEnumerator<int>();
Assert.IsFalse(merged.MoveNext());
merged = new MergedEnumerator<int>(new JCG.List<int>().GetEnumerator());
Assert.IsFalse(merged.MoveNext());
IEnumerator<int>[] itrs = new IEnumerator<int>[Random.Next(100)];
for (int i = 0; i < itrs.Length; i++)
{
itrs[i] = new JCG.List<int>().GetEnumerator();
}
merged = new MergedEnumerator<int>(itrs);
Assert.IsFalse(merged.MoveNext());
}
[Test]
public virtual void TestNoDupsRemoveDups()
{
TestCase(1, 1, true);
}
[Test]
public virtual void TestOffItrDupsRemoveDups()
{
TestCase(3, 1, true);
}
[Test]
public virtual void TestOnItrDupsRemoveDups()
{
TestCase(1, 3, true);
}
[Test]
public virtual void TestOnItrRandomDupsRemoveDups()
{
TestCase(1, -3, true);
}
[Test]
public virtual void TestBothDupsRemoveDups()
{
TestCase(3, 3, true);
}
[Test]
public virtual void TestBothDupsWithRandomDupsRemoveDups()
{
TestCase(3, -3, true);
}
[Test]
public virtual void TestNoDupsKeepDups()
{
TestCase(1, 1, false);
}
[Test]
public virtual void TestOffItrDupsKeepDups()
{
TestCase(3, 1, false);
}
[Test]
public virtual void TestOnItrDupsKeepDups()
{
TestCase(1, 3, false);
}
[Test]
public virtual void TestOnItrRandomDupsKeepDups()
{
TestCase(1, -3, false);
}
[Test]
public virtual void TestBothDupsKeepDups()
{
TestCase(3, 3, false);
}
[Test]
public virtual void TestBothDupsWithRandomDupsKeepDups()
{
TestCase(3, -3, false);
}
private void TestCase(int itrsWithVal, int specifiedValsOnItr, bool removeDups)
{
// Build a random number of lists
IList<int> expected = new JCG.List<int>();
Random random = new J2N.Randomizer(Random.NextInt64());
int numLists = itrsWithVal + random.Next(1000 - itrsWithVal);
IList<int>[] lists = new IList<int>[numLists];
for (int i = 0; i < numLists; i++)
{
lists[i] = new JCG.List<int>();
}
int start = random.Next(1000000);
int end = start + VALS_TO_MERGE / itrsWithVal / Math.Abs(specifiedValsOnItr);
for (int i = start; i < end; i++)
{
int maxList = lists.Length;
int maxValsOnItr = 0;
int sumValsOnItr = 0;
for (int itrWithVal = 0; itrWithVal < itrsWithVal; itrWithVal++)
{
int list = random.Next(maxList);
int valsOnItr = specifiedValsOnItr < 0 ? (1 + random.Next(-specifiedValsOnItr)) : specifiedValsOnItr;
maxValsOnItr = Math.Max(maxValsOnItr, valsOnItr);
sumValsOnItr += valsOnItr;
for (int valOnItr = 0; valOnItr < valsOnItr; valOnItr++)
{
lists[list].Add(i);
}
maxList = maxList - 1;
ArrayUtil.Swap(lists, list, maxList);
}
int maxCount = removeDups ? maxValsOnItr : sumValsOnItr;
for (int count = 0; count < maxCount; count++)
{
expected.Add(i);
}
}
// Now check that they get merged cleanly
IEnumerator<int>[] itrs = new IEnumerator<int>[numLists];
for (int i = 0; i < numLists; i++)
{
itrs[i] = lists[i].GetEnumerator();
}
try
{
MergedEnumerator<int> mergedItr = new MergedEnumerator<int>(removeDups, itrs);
using IEnumerator<int> expectedItr = expected.GetEnumerator();
while (expectedItr.MoveNext())
{
Assert.IsTrue(mergedItr.MoveNext());
Assert.AreEqual(expectedItr.Current, mergedItr.Current);
}
Assert.IsFalse(mergedItr.MoveNext());
}
finally
{
IOUtils.Dispose(itrs);
}
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestMergeEmptyIterator()
{
IEnumerator<int> merged = new MergedIterator<int>();
Assert.IsFalse(merged.MoveNext());
merged = new MergedIterator<int>(new JCG.List<int>().GetEnumerator());
Assert.IsFalse(merged.MoveNext());
IEnumerator<int>[] itrs = new IEnumerator<int>[Random.Next(100)];
for (int i = 0; i < itrs.Length; i++)
{
itrs[i] = new JCG.List<int>().GetEnumerator();
}
merged = new MergedIterator<int>(itrs);
Assert.IsFalse(merged.MoveNext());
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestNoDupsRemoveDupsIterator()
{
TestCaseIterator(1, 1, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOffItrDupsRemoveDupsIterator()
{
TestCaseIterator(3, 1, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOnItrDupsRemoveDupsIterator()
{
TestCaseIterator(1, 3, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOnItrRandomDupsRemoveDupsIterator()
{
TestCaseIterator(1, -3, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestBothDupsRemoveDupsIterator()
{
TestCaseIterator(3, 3, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestBothDupsWithRandomDupsRemoveDupsIterator()
{
TestCaseIterator(3, -3, true);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestNoDupsKeepDupsIterator()
{
TestCaseIterator(1, 1, false);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOffItrDupsKeepDupsIterator()
{
TestCaseIterator(3, 1, false);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOnItrDupsKeepDupsIterator()
{
TestCaseIterator(1, 3, false);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestOnItrRandomDupsKeepDupsIterator()
{
TestCaseIterator(1, -3, false);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestBothDupsKeepDupsIterator()
{
TestCaseIterator(3, 3, false);
}
[Test]
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
public virtual void TestBothDupsWithRandomDupsKeepDupsIterator()
{
TestCaseIterator(3, -3, false);
}
[Obsolete("This method will be removed in 4.8.0 release candidate.")]
private void TestCaseIterator(int itrsWithVal, int specifiedValsOnItr, bool removeDups)
{
// Build a random number of lists
IList<int> expected = new JCG.List<int>();
Random random = new J2N.Randomizer(Random.NextInt64());
int numLists = itrsWithVal + random.Next(1000 - itrsWithVal);
IList<int>[] lists = new IList<int>[numLists];
for (int i = 0; i < numLists; i++)
{
lists[i] = new JCG.List<int>();
}
int start = random.Next(1000000);
int end = start + VALS_TO_MERGE / itrsWithVal / Math.Abs(specifiedValsOnItr);
for (int i = start; i < end; i++)
{
int maxList = lists.Length;
int maxValsOnItr = 0;
int sumValsOnItr = 0;
for (int itrWithVal = 0; itrWithVal < itrsWithVal; itrWithVal++)
{
int list = random.Next(maxList);
int valsOnItr = specifiedValsOnItr < 0 ? (1 + random.Next(-specifiedValsOnItr)) : specifiedValsOnItr;
maxValsOnItr = Math.Max(maxValsOnItr, valsOnItr);
sumValsOnItr += valsOnItr;
for (int valOnItr = 0; valOnItr < valsOnItr; valOnItr++)
{
lists[list].Add(i);
}
maxList = maxList - 1;
ArrayUtil.Swap(lists, list, maxList);
}
int maxCount = removeDups ? maxValsOnItr : sumValsOnItr;
for (int count = 0; count < maxCount; count++)
{
expected.Add(i);
}
}
// Now check that they get merged cleanly
IEnumerator<int>[] itrs = new IEnumerator<int>[numLists];
for (int i = 0; i < numLists; i++)
{
itrs[i] = lists[i].GetEnumerator();
}
MergedIterator<int> mergedItr = new MergedIterator<int>(removeDups, itrs);
using IEnumerator<int> expectedItr = expected.GetEnumerator();
while (expectedItr.MoveNext())
{
Assert.IsTrue(mergedItr.MoveNext());
Assert.AreEqual(expectedItr.Current, mergedItr.Current);
}
Assert.IsFalse(mergedItr.MoveNext());
}
}
}