361 lines
10 KiB
C#
361 lines
10 KiB
C#
|
/**
|
|||
|
* 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);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|