blob: 4344825e2de1278dc3705c15cb228e54b54a420b [file] [log] [blame]
/*
* 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.
*/
package org.apache.uima.internal.util.rb_trees;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import org.apache.uima.internal.util.IntListIterator;
import junit.framework.TestCase;
public class IntArrayRBTtest extends TestCase {
private final static int NIL = 0;
static final Random rand = new Random();
static {
long seed = -585739628489294672L /* rand.nextLong() */ ;
rand.setSeed(seed);
System.out.println("IntArrayRBTtest seed is " + seed);
}
//debug occasional looping in table
private void checkStructure(IntArrayRBT ia) {
if (ia.root == NIL) {
if (ia.greatestNode != NIL) {
assertTrue(ia.greatestNode == NIL);
}
return;
}
if (ia.greatestNode == NIL) {
assertTrue(ia.root == NIL);
return;
}
checkParents(ia, ia.root);
}
private void checkParents(IntArrayRBT ia, int node) {
if (node == NIL) {
return;
}
int v0 = Integer.MIN_VALUE;
int v2 = Integer.MAX_VALUE;
int v1 = ia.getKeyForNode(node);
int left = ia.getLeft(node);
int right = ia.getRight(node);
if (left != NIL) {
assertEquals(ia.getParent(left), node);
assertFalse(left == right);
assertTrue(left != ia.root);
assertTrue(left != ia.greatestNode);
v0 = ia.getKeyForNode(left);
}
if (right != NIL) {
assertEquals(ia.getParent(right), node);
assertFalse(left == right);
assertTrue(right != ia.root);
v2 = ia.getKeyForNode(right);
}
assertTrue(v0 < v1);
assertTrue(v1 < v2);
checkParents(ia, left);
checkParents(ia, right);
}
public void testStructure() {
for (int ol = 0; ol < 100; ol ++) {
IntArrayRBT ia = new IntArrayRBT(4);
int i = 0;
int [] vs = new int[128];
for (; i < 120; i++) {
vs[i] = rand.nextInt(100); // some collisions
ia.add(vs[i]);
if ((i % 2) == 1) { // do removes at 50% rate
ia.deleteKey(rand.nextInt(i)); // remove a random one
checkStructure(ia);
assertTrue(ia.satisfiesRedBlackProperties());
}
}
}
}
public void testFindInsertionPoint() {
IntArrayRBT ia = new IntArrayRBT();
Integer[] vs = new Integer[] {2, 2, 5, 1, 6, 7, 3, 4};
for (Integer i : vs) {
ia.insertKey(i);
}
assertTrue(ia.findInsertionPoint(7) != 0);
assertEquals(0, ia.findInsertionPoint(8));
}
public void testIterator() {
IntArrayRBT ia = new IntArrayRBT();
ia.insertKey(4);
ia.insertKey(8);
ia.insertKey(2);
IntListIterator it = ia.iterator();
assertEquals(2, it.next());
assertEquals(4, it.next());
assertEquals(8, it.next());
assertFalse(it.hasNext());
}
// public void testIterator() throws ResourceInitializationException {
// CAS cas = CasCreationUtils.createCas((TypeSystem)null, null, null, null);
// FSRBTSetIndex<Annotation> setIndex = new FSRBTSetIndex<Annotation>((CASImpl)cas, cas.getAnnotationType(), FSIndex.SET_INDEX);
// IntArrayRBT ia = new IntArrayRBT();
// Integer[] vs = new Integer[] {2, 2, 5, 1, 6, 7, 3, 4};
// for (Integer i : vs) {
// ia.insertKey(i);
// }
// Integer[] rand = new Integer[vs.length];
// int i = 0;
// IntListIterator itl = ia.iterator();
//
// while(itl.hasNext()){
// rand[i++] = itl.next();
// }
// assertEquals(i, vs.length - 1);
// assertTrue(Arrays.equals(rand, new Integer[] {1, 2, 3, 4, 5, 6, 7, null}));
// moved to IteratorTest to take advantage of that test's setup
// i = 0;
//
// IntPointerIterator it = ia.pointerIterator(setIndex, null, null);
// while (it.isValid()) {
// rand[i++] = it.get();
// it.inc();
// }
// assertEquals(i, vs.length - 1);
// assertTrue(Arrays.equals(rand, new Integer[] {1, 2, 3, 4, 5, 6, 7, null}));
//
// it = ia.pointerIterator(setIndex, null, null);
// assertTrue(it.isValid());
// it.dec();
// assertFalse(it.isValid());
// it.inc();
// assertFalse(it.isValid());
// it.moveToLast();
// assertTrue(it.isValid());
// it.inc();
// assertFalse(it.isValid());
// it.dec(); // causes infinite loop
// assertFalse(it.isValid());
// }
public void testLargeInsertsDeletes() {
IntArrayRBT ia = new IntArrayRBT();
System.gc();
long fm1 = Runtime.getRuntime().freeMemory();
int[] ks = new int[10000];
System.out.print("freemem after intArrayRBT keys deleted to 0 (should be about the same): " + fm1 + " ");
for (int j = 0; j < 10; j++) {
// insert values
int shadowSize = 0;
for (int i = 0; i < 1000; i++) {
int k = rand.nextInt(1000);
ks[i] = k;
boolean wasInserted = ia.insertKeyShowNegative(k) >= 0;
if (wasInserted) {
shadowSize++;
}
}
assertEquals(shadowSize, ia.size);
//debug
// int[] iv = new int[1000];
// int iiv = 0;
// IntListIterator it = ia.iterator();
// while (it.hasNext()) {
// iv[iiv++] = it.next();
// }
assertTrue(ia.size <= 1000 && ia.size > 600);
// check all values are present
// Set<Integer> presentValues = new HashSet<>();
for (int i = 0; i < 1000; i++) {
int v = ks[i];
assertTrue(NIL != ia.findKey(v));
// presentValues.add(v);
}
// System.out.println("debug IntArrayRBT before delete, number of present values is " + presentValues.size());
// delete all values
Set<Integer> deletedValues = new HashSet<>();
int localSize = ia.size();
for (int i = 0; i < 1000; i++) {
boolean wasDeleted = ia.deleteKey(ks[i]);
if (wasDeleted) {
assertTrue(deletedValues.add(ks[i]));
localSize --;
assertEquals(ia.size(), localSize);
checkStructure(ia);
} else {
assertTrue(deletedValues.contains(ks[i]));
// if (!deletedValues.contains(ks[i])) { // debugging
// System.out.println("debug");
// boolean found = ia.debugScanFor(ks[i]);
// wasDeleted = ia.deleteKey(ks[i]); // try again, see why not deleted
// }
assertTrue(deletedValues.contains(ks[i]));
}
}
// it = ia.iterator(); // for debugging
// Arrays.fill(iv, -1);
// iiv = 0;
// while (it.hasNext()) {
// iv[iiv++] = it.next();
// }
assertEquals(0, ia.size);
System.gc();
System.out.print(Runtime.getRuntime().freeMemory() + " ");
}
System.out.println("");
}
}