361 lines
10 KiB
C#
Raw Normal View History

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Util;
using Lucene.Net.Util;
using NUnit.Framework;
namespace Lucene.Net.Contrib.Spatial.Test.Compatibility
{
public static class BitArrayExtensions
{
public static int NextSetBit(this BitArray arr, int fromIndex)
{
if (fromIndex >= arr.Length)
throw new ArgumentException("Invalid fromIndex", "fromIndex");
for (var i = fromIndex; i < arr.Length; i++)
{
if (arr[i]) return i;
}
return -1;
}
}
public class TestFixedBitSet : LuceneTestCase
{
private static readonly Random rnd = new Random((int)DateTimeOffset.Now.Ticks);
void doGet(BitArray a, FixedBitSet b)
{
int max = b.Length();
for (int i = 0; i < max; i++)
{
if (a.Get(i) != b.Get(i))
{
Assert.Fail("mismatch: BitSet=[" + i + "]=" + a.Get(i));
}
}
}
void doNextSetBit(BitArray a, FixedBitSet b)
{
int aa = -1, bb = -1;
do
{
aa = a.NextSetBit(aa + 1);
bb = bb < b.Length() - 1 ? b.NextSetBit(bb + 1) : -1;
Assert.AreEqual(aa, bb);
} while (aa >= 0);
}
void doPrevSetBit(BitArray a, FixedBitSet b)
{
int aa = a.Length + rnd.Next(100);
int bb = aa;
do
{
// aa = a.prevSetBit(aa-1);
aa--;
while ((aa >= 0) && (!a.Get(aa)))
{
aa--;
}
if (b.Length() == 0)
{
bb = -1;
}
else if (bb > b.Length() - 1)
{
bb = b.PrevSetBit(b.Length() - 1);
}
else if (bb < 1)
{
bb = -1;
}
else
{
bb = bb >= 1 ? b.PrevSetBit(bb - 1) : -1;
}
Assert.AreEqual(aa, bb);
} while (aa >= 0);
}
// test interleaving different FixedBitSetIterator.next()/skipTo()
//void doIterate(BitArray a, FixedBitSet b, int mode)
//{
// if (mode == 1) doIterate1(a, b);
// if (mode == 2) doIterate2(a, b);
//}
//void doIterate1(BitArray a, FixedBitSet b)
//{
// int aa = -1, bb = -1;
// DocIdSetIterator iterator = b.iterator();
// do
// {
// aa = a.NextSetBit(aa + 1);
// bb = (bb < b.Length() && random().nextBoolean()) ? iterator.NextDoc() : iterator.Advance(bb + 1);
// Assert.AreEqual(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
// } while (aa >= 0);
//}
//void doIterate2(BitArray a, FixedBitSet b)
//{
// int aa = -1, bb = -1;
// DocIdSetIterator iterator = b.iterator();
// do
// {
// aa = a.NextSetBit(aa + 1);
// bb = random().nextBoolean() ? iterator.NextDoc() : iterator.Advance(bb + 1);
// Assert.AreEqual(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
// } while (aa >= 0);
//}
//void doRandomSets(int maxSize, int iter, int mode)
//{
// BitArray a0 = null;
// FixedBitSet b0 = null;
// for (int i = 0; i < iter; i++)
// {
// int sz = _TestUtil.nextInt(random(), 2, maxSize);
// BitSet a = new BitSet(sz);
// FixedBitSet b = new FixedBitSet(sz);
// // test the various ways of setting bits
// if (sz > 0)
// {
// int nOper = random().nextInt(sz);
// for (int j = 0; j < nOper; j++)
// {
// int idx;
// idx = random().nextInt(sz);
// a.set(idx);
// b.set(idx);
// idx = random().nextInt(sz);
// a.clear(idx);
// b.clear(idx);
// idx = random().nextInt(sz);
// a.flip(idx);
// b.flip(idx, idx + 1);
// idx = random().nextInt(sz);
// a.flip(idx);
// b.flip(idx, idx + 1);
// boolean val2 = b.get(idx);
// boolean val = b.getAndSet(idx);
// assertTrue(val2 == val);
// assertTrue(b.get(idx));
// if (!val) b.clear(idx);
// assertTrue(b.get(idx) == val);
// }
// }
// // test that the various ways of accessing the bits are equivalent
// doGet(a, b);
// // test ranges, including possible extension
// int fromIndex, toIndex;
// fromIndex = random().nextInt(sz / 2);
// toIndex = fromIndex + random().nextInt(sz - fromIndex);
// BitSet aa = (BitSet)a.clone(); aa.flip(fromIndex, toIndex);
// FixedBitSet bb = b.clone(); bb.flip(fromIndex, toIndex);
// doIterate(aa, bb, mode); // a problem here is from flip or doIterate
// fromIndex = random().nextInt(sz / 2);
// toIndex = fromIndex + random().nextInt(sz - fromIndex);
// aa = (BitSet)a.clone(); aa.clear(fromIndex, toIndex);
// bb = b.clone(); bb.clear(fromIndex, toIndex);
// doNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit
// doPrevSetBit(aa, bb);
// fromIndex = random().nextInt(sz / 2);
// toIndex = fromIndex + random().nextInt(sz - fromIndex);
// aa = (BitSet)a.clone(); aa.set(fromIndex, toIndex);
// bb = b.clone(); bb.set(fromIndex, toIndex);
// doNextSetBit(aa, bb); // a problem here is from set() or nextSetBit
// doPrevSetBit(aa, bb);
// if (b0 != null && b0.length() <= b.length())
// {
// assertEquals(a.cardinality(), b.cardinality());
// BitSet a_and = (BitSet)a.clone(); a_and.and(a0);
// BitSet a_or = (BitSet)a.clone(); a_or.or(a0);
// BitSet a_andn = (BitSet)a.clone(); a_andn.andNot(a0);
// FixedBitSet b_and = b.clone(); assertEquals(b, b_and); b_and.and(b0);
// FixedBitSet b_or = b.clone(); b_or.or(b0);
// FixedBitSet b_andn = b.clone(); b_andn.andNot(b0);
// assertEquals(a0.cardinality(), b0.cardinality());
// assertEquals(a_or.cardinality(), b_or.cardinality());
// doIterate(a_and, b_and, mode);
// doIterate(a_or, b_or, mode);
// doIterate(a_andn, b_andn, mode);
// assertEquals(a_and.cardinality(), b_and.cardinality());
// assertEquals(a_or.cardinality(), b_or.cardinality());
// assertEquals(a_andn.cardinality(), b_andn.cardinality());
// }
// a0 = a;
// b0 = b;
// }
//}
// large enough to flush obvious bugs, small enough to run in <.5 sec as part of a
// larger testsuite.
//public void testSmall()
//{
// doRandomSets(atLeast(1200), atLeast(1000), 1);
// doRandomSets(atLeast(1200), atLeast(1000), 2);
//}
// uncomment to run a bigger test (~2 minutes).
/*
public void testBig() {
doRandomSets(2000,200000, 1);
doRandomSets(2000,200000, 2);
}
*/
[Test]
public void testEquals()
{
// This test can't handle numBits==0:
int numBits = rnd.Next(2000) + 1;
FixedBitSet b1 = new FixedBitSet(numBits);
FixedBitSet b2 = new FixedBitSet(numBits);
Assert.IsTrue(b1.Equals(b2));
Assert.IsTrue(b2.Equals(b1));
for (int iter = 0; iter < 10 * rnd.Next(500); iter++)
{
int idx = rnd.Next(numBits);
if (!b1.Get(idx))
{
b1.Set(idx);
Assert.IsFalse(b1.Equals(b2));
Assert.IsFalse(b2.Equals(b1));
b2.Set(idx);
Assert.IsTrue(b1.Equals(b2));
Assert.IsTrue(b2.Equals(b1));
}
}
// try different type of object
Assert.IsFalse(b1.Equals(new Object()));
}
[Test]
public void testHashCodeEquals()
{
// This test can't handle numBits==0:
int numBits = rnd.Next(2000) + 1;
FixedBitSet b1 = new FixedBitSet(numBits);
FixedBitSet b2 = new FixedBitSet(numBits);
Assert.IsTrue(b1.Equals(b2));
Assert.IsTrue(b2.Equals(b1));
for (int iter = 0; iter < 10 * rnd.Next(500); iter++)
{
int idx = rnd.Next(numBits);
if (!b1.Get(idx))
{
b1.Set(idx);
Assert.IsFalse(b1.Equals(b2));
Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
b2.Set(idx);
Assert.AreEqual(b1, b2);
Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode());
}
}
}
[Test]
public void testSmallBitSets()
{
// Make sure size 0-10 bit sets are OK:
for (int numBits = 0; numBits < 10; numBits++)
{
FixedBitSet b1 = new FixedBitSet(numBits);
FixedBitSet b2 = new FixedBitSet(numBits);
Assert.IsTrue(b1.Equals(b2));
Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode());
Assert.AreEqual(0, b1.Cardinality());
if (numBits > 0)
{
b1.Set(0, numBits);
Assert.AreEqual(numBits, b1.Cardinality());
//b1.Flip(0, numBits);
//Assert.AreEqual(0, b1.Cardinality());
}
}
}
private FixedBitSet makeFixedBitSet(int[] a, int numBits)
{
FixedBitSet bs = new FixedBitSet(numBits);
foreach (int e in a)
{
bs.Set(e);
}
return bs;
}
private BitArray makeBitSet(int[] a)
{
var bs = new BitArray(a.Length);
foreach (int e in a)
{
bs.Set(e, true);
}
return bs;
}
private void checkPrevSetBitArray(int[] a, int numBits)
{
FixedBitSet obs = makeFixedBitSet(a, numBits);
BitArray bs = makeBitSet(a);
doPrevSetBit(bs, obs);
}
[Test]
public void testPrevSetBit()
{
checkPrevSetBitArray(new int[] { }, 0);
checkPrevSetBitArray(new int[] { 0 }, 1);
checkPrevSetBitArray(new int[] { 0, 2 }, 3);
}
}
}