/* Copyright (c) 2001-2019, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package org.hsqldb.test;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Random;
import java.util.Vector;

import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.HsqlDeque;
import org.hsqldb.lib.HsqlList;
import org.hsqldb.lib.Iterator;
import org.hsqldb.lib.StopWatch;

import junit.framework.TestCase;

Randomly excutes methods on the HsqlList data structures and compares the results with equivalent calls on the java vector class.
Author:dnordahl@users
/** * Randomly excutes methods on the HsqlList data structures and compares the * results with equivalent calls on the java vector class. * * @author dnordahl@users */
public class TestDataStructures extends TestCase { private static final int NUMBER_OF_TEST_RUNS = 100000; private static final int NUMBER_OF_ITERATIONS_PER_RUN = 80; private Random randomGenerator; //Commands private static final int ADD = 1; private static final int ADD_AT = 2; private static final int GET = 3; private static final int REMOVE = 4; private static final int SET = 5; private static final int OPTIMIZE = 6; private static final int REMOVE_ALL = 7; private Vector listCommandsCalled;
Creates a new instance of TestDataStructures
/** Creates a new instance of TestDataStructures */
public TestDataStructures(String s) { super(s); randomGenerator = new Random(System.currentTimeMillis()); listCommandsCalled = new Vector(NUMBER_OF_ITERATIONS_PER_RUN); }
Runs a test on the hsqldb lists
/** Runs a test on the hsqldb lists */
public void testLists() { HsqlArrayList arrayList = new HsqlArrayList(); HsqlDeque deque = new HsqlDeque(); Vector vector = new Vector(); Vector listCommandsCalled = new Vector(NUMBER_OF_ITERATIONS_PER_RUN); Integer tempInt = null; int tempCommandCode; int tempPosition; boolean arrayListException = false; boolean dequeException = false; boolean vectorException = false; Object arrayListObject = null; Object linkedListObject = null; Object vectorObject = null; for (int i = 0; i < getRandomInt(3, 12); i++) { // prime the contents with a couple items tempInt = getRandomInteger(); arrayList.add(tempInt); deque.add(tempInt); vector.addElement(tempInt); listCommandsCalled.addElement("Add"); } compareLists(arrayList, deque, vector); for (int j = 0; j < NUMBER_OF_ITERATIONS_PER_RUN; j++) { tempCommandCode = getRandomInt(0, 15); // 0 and 8 are ignored or used for a special op switch (tempCommandCode) { case ADD : tempInt = getRandomInteger(); listCommandsCalled.addElement("Add"); arrayList.add(tempInt); deque.add(tempInt); vector.addElement(tempInt); break; case ADD_AT : tempInt = getRandomInteger(); tempPosition = getRandomInt(0, vector.size()); listCommandsCalled.addElement("Add at " + tempPosition); try { arrayList.add(tempPosition, tempInt); } catch (Exception ex) { arrayListException = true; } try { deque.add(tempPosition, tempInt); } catch (Exception ex) { dequeException = true; } try { vector.insertElementAt(tempInt, tempPosition); } catch (Exception ex) { vectorException = true; } compareLists(arrayList, deque, vector); break; case GET : tempPosition = getRandomInt(0, vector.size() - 1); listCommandsCalled.addElement("Get " + tempPosition); try { arrayListObject = arrayList.get(tempPosition); } catch (Exception ex) { arrayListException = true; } try { linkedListObject = deque.get(tempPosition); } catch (Exception ex) { dequeException = true; } try { vectorObject = vector.elementAt(tempPosition); } catch (Exception ex) { vectorException = true; } break; case REMOVE : tempPosition = getRandomInt(0, vector.size() - 1); listCommandsCalled.addElement("Remove " + tempPosition); try { arrayListObject = arrayList.remove(tempPosition); } catch (Exception ex) { arrayListException = true; } try { linkedListObject = deque.remove(tempPosition); } catch (Exception ex) { dequeException = true; } try { vectorObject = vector.elementAt(tempPosition); vector.removeElementAt(tempPosition); } catch (Exception ex) { vectorException = true; } break; case SET : tempInt = getRandomInteger(); tempPosition = getRandomInt(0, vector.size() - 1); listCommandsCalled.addElement("Set " + tempPosition); try { arrayList.set(tempPosition, tempInt); } catch (Exception ex) { arrayListException = true; } try { deque.set(tempPosition, tempInt); } catch (Exception ex) { dequeException = true; } try { vector.setElementAt(tempInt, tempPosition); } catch (Exception ex) { vectorException = true; } compareLists(arrayList, deque, vector); break; case OPTIMIZE : listCommandsCalled.addElement("Optimize"); arrayList.trim(); vector.trimToSize(); break; case REMOVE_ALL : if (getRandomInt(0, 5) == 4) { // to limit the frequency of this call listCommandsCalled.addElement("Remove all"); if (vector.size() == 0) { break; } for (int k = arrayList.size() - 1; k >= 0; k--) { arrayList.remove(k); deque.remove(k); } vector.removeAllElements(); } break; default : } if (arrayListException || dequeException || vectorException) { // if an exception is thrown in vector but not one of the lists or vice versa if (!(arrayListException && dequeException && vectorException)) { if (!(arrayListException && vectorException)) { System.out.println( "Exception discrepancy with vector and arraylist"); } else if (!(dequeException && vectorException)) { System.out.println( "Exception discrepancy with vector and linkedlist"); } else { System.out.println("Error in TestDataStructures"); } this.printListCommandsCalled(listCommandsCalled); fail("test failed"); //System.exit(0); } return; } if (!objectEquals(linkedListObject, arrayListObject, vectorObject)) { System.out.println("Objects returned inconsistent"); this.printListCommandsCalled(listCommandsCalled); fail("test failed"); //System.exit(0); } compareLists(arrayList, deque, vector); } }
Compare contents of lists to the vector. Print out stuff if they are inconsistent and exit.
/** * Compare contents of lists to the vector. Print out stuff if they are * inconsistent and exit. */
public void compareLists(HsqlArrayList arrayList, HsqlDeque linkedList, Vector vector) { boolean arrayListError = false; boolean linkedListError = false; if (!equalsVector(arrayList, vector)) { System.out.println("Error in array list implementation"); arrayListError = true; } if (!equalsVector(linkedList, vector)) { System.out.println("Error in linked list implementation"); linkedListError = true; } if (arrayListError || linkedListError) { this.printListCommandsCalled(listCommandsCalled); System.out.flush(); fail("test failed"); } }
Prints the list of commands called so far
/** Prints the list of commands called so far */
public void printListCommandsCalled(Vector commands) { int commandCode = 0; for (int i = 0; i < commands.size(); i++) { System.out.println((String) commands.elementAt(i)); } System.out.flush(); }
Returns whether three objects are equal
/** Returns whether three objects are equal */
private boolean objectEquals(Object lObject, Object aObject, Object vObject) { if (lObject == null && aObject == null && vObject == null) { return true; } try { if (!lObject.equals(vObject)) { System.out.println("LinkList object returned inconsistent"); return false; } else if (!aObject.equals(vObject)) { System.out.println("ArrayList object returned inconsistent"); return false; } else { return true; } } catch (NullPointerException ex) { return false; } }
Returns a random integer in the range of the lowBound and highBound
/** Returns a random integer in the range of the lowBound and highBound */
private int getRandomInt(int lowBound, int highBound) { double random = randomGenerator.nextDouble(); return ((int) (((highBound - lowBound) * random) + .5)) + lowBound; }
Returns an Integer object with a value between Integer.MIN_VALUE and Integer.MAX_VALUE
/** * Returns an Integer object with a value between Integer.MIN_VALUE and * Integer.MAX_VALUE */
private Integer getRandomInteger() { return Integer.valueOf(getRandomInt(0, (int) (Integer.MAX_VALUE / 100.0))); }
Tells whether the given list contains the same data as the vector
/** Tells whether the given list contains the same data as the vector */
private boolean equalsVector(HsqlList list, Vector vector) { if (list.size() != vector.size()) { return false; } Iterator listElements = list.iterator(); Enumeration vectorElements = vector.elements(); Object listObj = null; Object vectorObj = null; while (listElements.hasNext()) { listObj = listElements.next(); vectorObj = vectorElements.nextElement(); if (!listObj.equals(vectorObj)) { return false; } } return true; } public void testGrowth() { HsqlArrayList d = new HsqlArrayList(); for (int i = 0; i < 12; i++) { d.add(Integer.valueOf(i)); } for (int i = 0; i < d.size(); i++) { System.out.println(d.get(i)); } d = new HsqlArrayList(); for (int i = 0; i < 12; i++) { d.add(Integer.valueOf(i)); } d.set(11, Integer.valueOf(11)); for (int i = 0; i < d.size(); i++) { System.out.println(d.get(i)); } Iterator it = d.iterator(); for (int i = 0; it.hasNext(); i++) { Integer value = (Integer) it.next(); System.out.println(value); assertEquals(i, value.intValue()); } //- assertEquals(12, d.size()); } public void testSpeed() { randomGenerator = new Random(System.currentTimeMillis()); int TEST_RUNS = 100000; int LOOP_COUNT = 1000; HsqlArrayList arrayList = new HsqlArrayList(TEST_RUNS); ArrayList utilArrayList = new ArrayList(TEST_RUNS); Vector vector = new Vector(TEST_RUNS); Integer value = Integer.valueOf(randomGenerator.nextInt()); Integer INT_0 = Integer.valueOf(0); StopWatch sw = new StopWatch(); System.out.println(sw.currentElapsedTimeToMessage("time")); for (int i = 0; i < TEST_RUNS; i++) { arrayList.add(INT_0); } for (int i = 0; i < TEST_RUNS; i++) { for (int j = 0; j < LOOP_COUNT; j++) { arrayList.set(i, INT_0); } } System.out.println( sw.currentElapsedTimeToMessage("time HsqlArrayLsit")); sw.zero(); for (int i = 0; i < TEST_RUNS; i++) { utilArrayList.add(INT_0); } for (int i = 0; i < TEST_RUNS; i++) { for (int j = 0; j < LOOP_COUNT; j++) { utilArrayList.set(i, INT_0); } } System.out.println(sw.currentElapsedTimeToMessage("time ArrayList")); sw.zero(); for (int i = 0; i < TEST_RUNS; i++) { vector.addElement(INT_0); } for (int i = 0; i < TEST_RUNS; i++) { for (int j = 0; j < LOOP_COUNT; j++) { vector.setElementAt(INT_0, i); } } System.out.println(sw.currentElapsedTimeToMessage("time Vector")); } public static void main(String[] args) { TestDataStructures test = new TestDataStructures("testLists"); for (int i = 0; i < NUMBER_OF_TEST_RUNS; i++) { test.testLists(); if (i % 1000 == 0) { System.out.println("Finished " + i + " tests"); System.out.flush(); } } System.out.println( "After " + NUMBER_OF_TEST_RUNS + " tests of a maximum of " + NUMBER_OF_ITERATIONS_PER_RUN + " list commands each test, the list tests passed"); test.testGrowth(); } }