alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

HSQLDB example source code file (ValuePoolHashMap.java)

This example HSQLDB source code file (ValuePoolHashMap.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - HSQLDB tags/keywords

basehashmap, date, date, double, illegalargumentexception, integer, integer, jdbc, long, long, object, sql, string, string, valuepoolhashmap

The HSQLDB ValuePoolHashMap.java source code

/* Copyright (c) 2001-2008, 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.store;

import java.sql.Date;

/*
 * implementation notes:
 *
 * NB: As of this version this class cannot be used for mixed object types
 * It is relativly easy to support this by adding an 'instanceof' test inside
 * each getOrAddXxxx method before casting the Set values to the target type
 * for comparison purposes.
 *
 * superclass is used as an Object Set
 * getOrAddXxxx methods are implemented directly for speed
 * the superclass infrastructure is otherwise used
 */

/**
 * Subclass of BaseHashMap for maintaining a pool of objects. Supports a
 * range of java.lang.* objects.
 *
 * @author fredt@users
 * @version 1.8.0
 * @since 1.7.2
 *
 */
public class ValuePoolHashMap extends BaseHashMap {

    public ValuePoolHashMap(int initialCapacity, int maxCapacity,
                            int purgePolicy) throws IllegalArgumentException {

        super(initialCapacity, 1, BaseHashMap.objectKeyOrValue,
              BaseHashMap.noKeyOrValue, true);

        this.maxCapacity = maxCapacity;
        this.purgePolicy = purgePolicy;
    }

    /**
     * In rare circumstances resetCapacity may not succeed, in which case
     * capacity remains unchanged but purge policy is set to newPolicy
     */
    public void resetCapacity(int newCapacity,
                              int newPolicy) throws IllegalArgumentException {

        if (newCapacity != 0 && hashIndex.elementCount > newCapacity) {
            int surplus = hashIndex.elementCount - newCapacity;

            surplus += (surplus >> 5);

            if (surplus > hashIndex.elementCount) {
                surplus = hashIndex.elementCount;
            }

            clear(surplus, (surplus >> 6));
        }

        if (newCapacity != 0 && newCapacity < threshold) {
            rehash(newCapacity);

            if (newCapacity < hashIndex.elementCount) {
                newCapacity = maxCapacity;
            }
        }

        this.maxCapacity = newCapacity;
        this.purgePolicy = newPolicy;
    }

    protected Integer getOrAddInteger(int intKey) {

        Integer testValue;
        int     index      = hashIndex.getHashIndex(intKey);
        int     lookup     = hashIndex.hashTable[index];
        int     lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = (Integer) objectKeyTable[lookup];

            if (testValue.intValue() == intKey) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddInteger(intKey);
        }

        lookup                 = hashIndex.linkNode(index, lastLookup);
        testValue              = new Integer(intKey);
        objectKeyTable[lookup] = testValue;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return testValue;
    }

    protected Long getOrAddLong(long longKey) {

        Long testValue;
        int index = hashIndex.getHashIndex((int) (longKey
            ^ (longKey >>> 32)));
        int lookup     = hashIndex.hashTable[index];
        int lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = (Long) objectKeyTable[lookup];

            if (testValue.longValue() == longKey) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddLong(longKey);
        }

        lookup                 = hashIndex.linkNode(index, lastLookup);
        testValue              = new Long(longKey);
        objectKeyTable[lookup] = testValue;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return testValue;
    }

    /**
     * This is dissimilar to normal hash map get() methods. The key Object
     * should have an equals(String) method which should return true if the
     * key.toString.equals(String) is true. Also the key.hashCode() method
     * must return the same value as key.toString.hashCode().<p>
     *
     * The above is always true when the key is a String. But it means it is
     * possible to submit special keys that fulfill the contract. For example
     * a wrapper around a byte[] can be submitted as key to retrieve either
     * a new String, which is the toString() method of the wrapper, or return
     * an existing String which would be equal to the product of toString().
     *
     * @param key String or other Object with compatible equals(String)
     * and hashCode().
     * @return String from map or a new String
     */
    protected String getOrAddString(Object key) {

        String testValue;
        int    index      = hashIndex.getHashIndex(key.hashCode());
        int    lookup     = hashIndex.hashTable[index];
        int    lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = (String) objectKeyTable[lookup];

            if (key.equals(testValue)) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddString(key);
        }

        testValue              = key.toString();
        lookup                 = hashIndex.linkNode(index, lastLookup);
        objectKeyTable[lookup] = testValue;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return testValue;
    }

    protected Date getOrAddDate(long longKey) {

        Date testValue;
        int  hash       = (int) longKey ^ (int) (longKey >>> 32);
        int  index      = hashIndex.getHashIndex(hash);
        int  lookup     = hashIndex.hashTable[index];
        int  lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = (Date) objectKeyTable[lookup];

            if (testValue.getTime() == longKey) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddDate(longKey);
        }

        lookup                 = hashIndex.linkNode(index, lastLookup);
        testValue              = new Date(longKey);
        objectKeyTable[lookup] = testValue;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return testValue;
    }

    protected Double getOrAddDouble(long longKey) {

        Double testValue;
        int index = hashIndex.getHashIndex((int) (longKey
            ^ (longKey >>> 32)));
        int lookup     = hashIndex.hashTable[index];
        int lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = (Double) objectKeyTable[lookup];

            if (Double.doubleToLongBits(testValue.doubleValue()) == longKey) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddDouble(longKey);
        }

        lookup                 = hashIndex.linkNode(index, lastLookup);
        testValue              = new Double(Double.longBitsToDouble(longKey));
        objectKeyTable[lookup] = testValue;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return testValue;
    }

    protected Object getOrAddObject(Object key) {

        Object testValue;
        int    index      = hashIndex.getHashIndex(key.hashCode());
        int    lookup     = hashIndex.hashTable[index];
        int    lastLookup = -1;

        for (; lookup >= 0;
                lastLookup = lookup,
                lookup = hashIndex.getNextLookup(lookup)) {
            testValue = objectKeyTable[lookup];

            if (testValue.equals(key)) {
                if (accessCount == Integer.MAX_VALUE) {
                    resetAccessCount();
                }

                accessTable[lookup] = accessCount++;

                return testValue;
            }
        }

        if (hashIndex.elementCount >= threshold) {
            reset();

            return getOrAddObject(key);
        }

        lookup                 = hashIndex.linkNode(index, lastLookup);
        objectKeyTable[lookup] = key;

        if (accessCount == Integer.MAX_VALUE) {
            resetAccessCount();
        }

        accessTable[lookup] = accessCount++;

        return key;
    }
/*
    public static void main(String[] argv) {

        int                      BIGRANGE   = 100000;
        int                      SMALLRANGE = 50000;
        int                      POOLSIZE   = 100000;
        java.util.Random         randomgen  = new java.util.Random();
        org.hsqldb.lib.StopWatch sw         = new org.hsqldb.lib.StopWatch();
        ValuePoolHashMap map = new ValuePoolHashMap(POOLSIZE, POOLSIZE,
            BaseHashMap.PURGE_HALF);
        int maxCount = 5000000;

        try {
            for (int rounds = 0; rounds < 3; rounds++) {
                sw.zero();

                // timing for ValuePool retreival
                for (int i = 0; i < maxCount; i++) {
                    boolean bigrange  = (i % 2) == 0;
                    int     intValue  = randomgen.nextInt(bigrange ? BIGRANGE
                                                                   : SMALLRANGE);
                    Integer intObject = map.getOrAddInteger(intValue);

                    if (intObject.intValue() != intValue) {
                        throw new Exception("Value mismatch");
                    }

                    //                    System.out.print(intValue);
                    //                    System.out.print(' ');
                }

                System.out.println("Count " + maxCount + " "
                                   + sw.elapsedTime());
                sw.zero();

                // timing for Integer creation
                for (int i = 0; i < maxCount; i++) {
                    boolean bigrange  = (i % 2) == 0;
                    int     intValue  = randomgen.nextInt(bigrange ? BIGRANGE
                                                                   : SMALLRANGE);
                    Integer intObject = new Integer(intValue);

                    if (intObject.intValue() != intValue) {
                        throw new Exception("Value mismatch");
                    }
                }

                System.out.println("Count new Integer() " + maxCount + " "
                                   + sw.elapsedTime());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
*/
}

Other HSQLDB examples (source code examples)

Here is a short list of links related to this HSQLDB ValuePoolHashMap.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.