| /* Copyright (c) 2001-2010, 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.Random; |
| |
| import org.hsqldb.lib.DoubleIntIndex; |
| import org.hsqldb.lib.StopWatch; |
| |
| import junit.framework.TestCase; |
| |
| /** |
| * @author Fred Toussi (fredt@users dot sourceforge.net) |
| */ |
| public class TestHashStructures extends TestCase { |
| |
| public TestHashStructures(String s) { |
| super(s); |
| } |
| |
| Random randomgen = new java.util.Random(); |
| |
| public void testHashMap() throws Exception { |
| |
| boolean failed = false; |
| int testSize = 33; |
| org.hsqldb.lib.HashMap hMap = new org.hsqldb.lib.HashMap(); |
| org.hsqldb.lib.IntKeyHashMap hIntMap = |
| new org.hsqldb.lib.IntKeyHashMap(); |
| java.util.HashMap uMap = new java.util.HashMap(); |
| |
| try { |
| populateBySerialIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| |
| // - |
| populateByRandomIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| |
| // |
| depopulateRandomly(uMap, hMap, 20); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| |
| // - |
| populateBySerialIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| |
| // |
| depopulateByIterator(uMap, hMap, 20); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| } catch (Exception e) { |
| failed = true; |
| } |
| |
| assertTrue(!failed); |
| } |
| |
| public void testIntKeyHashMap() throws Exception { |
| |
| boolean failed = false; |
| int testSize = 33; |
| org.hsqldb.lib.IntKeyHashMap hIntMap = |
| new org.hsqldb.lib.IntKeyHashMap(); |
| java.util.HashMap uMap = new java.util.HashMap(); |
| |
| try { |
| populateBySerialIntKeysInt(uMap, hIntMap, testSize); |
| compareByUIteratorInt(uMap, hIntMap); |
| populateByRandomIntKeysInt(uMap, hIntMap, testSize); |
| compareByUIteratorInt(uMap, hIntMap); |
| compareByHIteratorInt(uMap, hIntMap); |
| |
| // |
| depopulateByIntIterator(uMap, hIntMap, 20); |
| compareByUIteratorInt(uMap, hIntMap); |
| compareByHIteratorInt(uMap, hIntMap); |
| |
| // |
| clearByIntIterator(uMap, hIntMap); |
| compareByUIteratorInt(uMap, hIntMap); |
| compareByHIteratorInt(uMap, hIntMap); |
| |
| // - |
| populateBySerialIntKeysInt(uMap, hIntMap, testSize); |
| compareByUIteratorInt(uMap, hIntMap); |
| compareByHIteratorInt(uMap, hIntMap); |
| |
| // |
| clearByIntIterator(uMap, hIntMap); |
| compareByUIteratorInt(uMap, hIntMap); |
| compareByHIteratorInt(uMap, hIntMap); |
| } catch (Exception e) { |
| failed = true; |
| } |
| |
| assertTrue(!failed); |
| } |
| |
| public void testHashMappedList() throws Exception { |
| |
| boolean failed = false; |
| int testSize = 33; |
| org.hsqldb.lib.HashMappedList hMap = |
| new org.hsqldb.lib.HashMappedList(); |
| java.util.HashMap uMap = new java.util.HashMap(); |
| |
| try { |
| populateBySerialIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| populateByRandomIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| depopulateRandomly(uMap, hMap, 20); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| populateByRandomIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| depopulateRandomly(uMap, hMap, 20); |
| populateBySerialIntKeys(uMap, hMap, testSize); |
| compareByUIterator(uMap, hMap); |
| compareByHIterator(uMap, hMap); |
| } catch (Exception e) { |
| failed = true; |
| } |
| |
| assertTrue(!failed); |
| } |
| |
| public void testDoubleIntLookup() throws Exception { |
| |
| boolean failed = false; |
| int testSize = 512; |
| org.hsqldb.lib.IntKeyHashMap hIntMap = |
| new org.hsqldb.lib.IntKeyHashMap(); |
| DoubleIntIndex intLookup = new DoubleIntIndex(12, false); |
| |
| try { |
| intLookup.setKeysSearchTarget(); |
| populateBySerialIntKeysInt(intLookup, hIntMap, testSize); |
| compareByHIteratorInt(intLookup, hIntMap); |
| populateByRandomIntKeysInt(intLookup, hIntMap, testSize); |
| compareByHIteratorInt(intLookup, hIntMap); |
| } catch (Exception e) { |
| failed = true; |
| } |
| |
| assertTrue(!failed); |
| } |
| |
| public void testDoubleIntSpeed() throws Exception { |
| |
| boolean failed = false; |
| int testSize = 500; |
| org.hsqldb.lib.IntKeyHashMap hIntMap = |
| new org.hsqldb.lib.IntKeyHashMap(); |
| DoubleIntIndex intLookup = new DoubleIntIndex(testSize, false); |
| |
| intLookup.setKeysSearchTarget(); |
| populateByRandomIntKeysInt(intLookup, hIntMap, testSize); |
| compareByHIteratorInt(intLookup, hIntMap); |
| |
| int[] sample = getSampleIntArray(intLookup, 100); |
| int[] sampleVals = new int[sample.length]; |
| int i = 0; |
| int j = 0; |
| StopWatch sw = new StopWatch(); |
| |
| try { |
| for (j = 0; j < 10000; j++) { |
| for (i = 0; i < sample.length; i++) { |
| int pos = intLookup.findFirstEqualKeyIndex(sample[i]); |
| |
| sampleVals[i] = intLookup.getValue(pos); |
| |
| intLookup.remove(pos); |
| } |
| |
| for (i = 0; i < sample.length; i++) { |
| intLookup.addUnique(sample[i], sampleVals[i]); |
| } |
| } |
| |
| System.out.println( |
| sw.elapsedTimeToMessage("Double int table times")); |
| intLookup.findFirstEqualKeyIndex(0); // sort |
| compareByHIteratorInt(intLookup, hIntMap); |
| } catch (Exception e) { |
| System.out.println( |
| sw.elapsedTimeToMessage("Double int table error: i =" + i)); |
| |
| failed = true; |
| } |
| |
| assertTrue(!failed); |
| } |
| |
| int[] getSampleIntArray(org.hsqldb.lib.DoubleIntIndex index, int size) { |
| |
| int[] array = new int[size]; |
| org.hsqldb.lib.IntKeyHashMap map = new org.hsqldb.lib.IntKeyHashMap(); |
| |
| for (; map.size() < size; ) { |
| int pos = nextIntRandom(randomgen, index.size()); |
| |
| map.put(pos, null); |
| } |
| |
| org.hsqldb.lib.Iterator it = map.keySet().iterator(); |
| |
| for (int i = 0; i < size; i++) { |
| int pos = it.nextInt(); |
| |
| array[i] = index.getKey(pos); |
| } |
| |
| return array; |
| } |
| |
| void populateBySerialIntKeys(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| uMap.put(new Integer(i), new Integer(intValue)); |
| hMap.put(new Integer(i), new Integer(intValue)); |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| |
| void populateBySerialIntKeysInt(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| uMap.put(new Integer(i), new Integer(intValue)); |
| hMap.put(i, new Integer(intValue)); |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| |
| void populateBySerialIntKeysInt(DoubleIntIndex intLookup, |
| org.hsqldb.lib.IntKeyHashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| intLookup.addUnique(i, intValue); |
| hMap.put(i, new Integer(intValue)); |
| |
| if (intLookup.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| |
| void populateByRandomIntKeysInt(DoubleIntIndex intLookup, |
| org.hsqldb.lib.IntKeyHashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| intLookup.addUnique(intValue, i); |
| hMap.put(intValue, new Integer(i)); |
| |
| // actually this can happen as duplicates are allowed in DoubleIntTable |
| if (intLookup.size() != hMap.size()) { |
| throw new Exception("Duplicate random in int lookup"); |
| } |
| } |
| } |
| |
| void populateByRandomIntKeys(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| uMap.put(new Integer(intValue), new Integer(i)); |
| hMap.put(new Integer(intValue), new Integer(i)); |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| |
| void populateByRandomIntKeysInt(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hMap, |
| int testSize) throws Exception { |
| |
| for (int i = 0; i < testSize; i++) { |
| int intValue = randomgen.nextInt(); |
| |
| uMap.put(new Integer(intValue), new Integer(i)); |
| hMap.put(intValue, new Integer(i)); |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| |
| void depopulateRandomly(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap, |
| int testCount) throws Exception { |
| |
| int removeCount = 0; |
| int size = uMap.size(); |
| |
| if (testCount > size / 2) { |
| testCount = size / 2; |
| } |
| |
| while (removeCount < testCount) { |
| java.util.Iterator uIt = uMap.keySet().iterator(); |
| |
| for (int i = 0; uIt.hasNext(); i++) { |
| Object uKey = uIt.next(); |
| int intValue = randomgen.nextInt(size); |
| |
| if (intValue == i) { |
| uIt.remove(); |
| hMap.remove(uKey); |
| |
| removeCount++; |
| } |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| } |
| } |
| |
| void depopulateByIterator(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap, |
| int testCount) throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator(); |
| |
| System.out.println(uMap.size()); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| Object key = hIt.next(); |
| int check = randomgen.nextInt(2); |
| |
| if (check == i % 2) { |
| hIt.remove(); |
| uMap.remove(key); |
| } |
| |
| if (uMap.size() != hMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| |
| System.out.println(uMap.size()); |
| } |
| |
| void depopulateByIntIterator(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hIntMap, |
| int testCount) throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hIntMap.keySet().iterator(); |
| |
| System.out.println(uMap.size()); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| Object key = new Integer(hIt.nextInt()); |
| int check = randomgen.nextInt(2); |
| |
| if (check == i % 2) { |
| hIt.remove(); |
| uMap.remove(key); |
| } |
| |
| if (uMap.size() != hIntMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| |
| System.out.println(uMap.size()); |
| } |
| |
| void clearByIntIterator(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hIntMap) |
| throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hIntMap.keySet().iterator(); |
| |
| System.out.println(uMap.size()); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| Object key = new Integer(hIt.nextInt()); |
| |
| hIt.remove(); |
| uMap.remove(key); |
| |
| if (uMap.size() != hIntMap.size()) { |
| throw new Exception("HashMap size mismatch"); |
| } |
| } |
| |
| System.out.println(uMap.size()); |
| } |
| |
| void compareByUIterator(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap) throws Exception { |
| |
| java.util.Iterator uIt = uMap.keySet().iterator(); |
| |
| for (int i = 0; uIt.hasNext(); i++) { |
| Object uKey = uIt.next(); |
| Object oU = uMap.get(uKey); |
| Object hU = hMap.get(uKey); |
| |
| if (!oU.equals(hU)) { |
| throw new Exception("HashMap value mismatch"); |
| } |
| } |
| } |
| |
| void compareByHIterator(java.util.HashMap uMap, |
| org.hsqldb.lib.HashMap hMap) throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator(); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| Object hKey = hIt.next(); |
| Object oU = uMap.get(hKey); |
| Object hU = hMap.get(hKey); |
| |
| if (!oU.equals(hU)) { |
| throw new Exception("HashMap value mismatch"); |
| } |
| } |
| } |
| |
| void compareByUIteratorInt(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hMap) |
| throws Exception { |
| |
| java.util.Iterator uIt = uMap.keySet().iterator(); |
| |
| for (int i = 0; uIt.hasNext(); i++) { |
| Object uKey = uIt.next(); |
| Object oU = uMap.get(uKey); |
| Object hU = hMap.get(((Integer) uKey).intValue()); |
| |
| if (!oU.equals(hU)) { |
| throw new Exception("HashMap value mismatch"); |
| } |
| } |
| } |
| |
| void compareByHIteratorInt(java.util.HashMap uMap, |
| org.hsqldb.lib.IntKeyHashMap hMap) |
| throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator(); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| Object hKey = new Integer(hIt.nextInt()); |
| Object oU = uMap.get(hKey); |
| Object hU = hMap.get(((Integer) hKey).intValue()); |
| |
| if (!oU.equals(hU)) { |
| throw new Exception("HashMap value mismatch"); |
| } |
| } |
| } |
| |
| void compareByHIteratorInt(DoubleIntIndex intLookup, |
| org.hsqldb.lib.IntKeyHashMap hMap) |
| throws Exception { |
| |
| org.hsqldb.lib.Iterator hIt = hMap.keySet().iterator(); |
| |
| for (int i = 0; hIt.hasNext(); i++) { |
| int hK = hIt.nextInt(); |
| int lookup = intLookup.findFirstEqualKeyIndex(hK); |
| int lV = intLookup.getValue(lookup); |
| Integer hV = (Integer) hMap.get(hK); |
| |
| if (hV.intValue() != lV) { |
| throw new Exception("HashMap value mismatch"); |
| } |
| } |
| } |
| |
| int nextIntRandom(Random r, int range) { |
| |
| int b = r.nextInt(); |
| |
| if (b == Integer.MIN_VALUE) { |
| b = Integer.MAX_VALUE; |
| } |
| |
| b = Math.abs(b); |
| |
| return b % range; |
| } |
| |
| public static void main(String[] argv) { |
| |
| try { |
| TestHashStructures test = new TestHashStructures("testHashMap"); |
| |
| test.testHashMap(); |
| test.testIntKeyHashMap(); |
| test.testHashMappedList(); |
| test.testDoubleIntLookup(); |
| test.testDoubleIntSpeed(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| } |