|
HSQLDB example source code file (ValuePoolHashMap.java)
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 |
Copyright 1998-2024 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.