⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basehashmap.java

📁 hsqldb是100%java实现的数据库,是一个开放源代码的JAVA数据库 l 具有标准的SQL语法和JAVA接口 l HSQLDB可以自由使用和分发 l 非常简洁和快速的
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) 2001-2005, 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.util.NoSuchElementException;import org.hsqldb.lib.ArrayCounter;public class BaseHashMap {/** * Base class for hash tables or sets. The exact type of the structure is * defined by the constructor. Each instance has at least a keyTable array * and a HashIndex instance for looking up the keys into this table. Instances * that are maps also have a valueTable the same size as the keyTable. * * Special getOrAddXXX() methods are used for object maps in some subclasses. * * @author fredt@users * @version 1.8.0 * @since 1.7.2 *//*    data store:    keys: {array of primitive | array of object}    values: {none | array of primitive | array of object} same size as keys    objects support : hashCode(), equals()    implemented types of keyTable:    {objectKeyTable: variable size Object[] array for keys |    intKeyTable: variable size int[] for keys |    longKeyTable: variable size long[] for keys }    implemented types of valueTable:    {objectValueTable: variable size Object[] array for values |    intValueTable: variable size int[] for values |    longValueTable: variable size long[] for values}    valueTable does not exist for sets or for object pools    hash index:    hashTable: fixed size int[] array for hash lookup into keyTable    linkTable: pointer to the next key ; size equal or larger than hashTable    but equal to the valueTable    access count table:    {none |    variable size int[] array for access count} same size as xxxKeyTable*/    //    boolean isIntKey;    boolean isLongKey;    boolean isObjectKey;    boolean isNoValue;    boolean isIntValue;    boolean isLongValue;    boolean isObjectValue;    //    protected HashIndex hashIndex;    //    protected int[]    intKeyTable;    protected Object[] objectKeyTable;    protected long[]   longKeyTable;    //    protected int[]    intValueTable;    protected Object[] objectValueTable;    protected long[]   longValueTable;    //    int   accessMin;    int   accessCount;    int[] accessTable;    //    final float       loadFactor;    final int         initialCapacity;    int               threshold;    int               maxCapacity;    protected int     purgePolicy = NO_PURGE;    protected boolean minimizeOnEmpty;    //    boolean hasZeroKey;    int     zeroKeyIndex = -1;    // keyOrValueTypes    protected static final int noKeyOrValue     = 0;    protected static final int intKeyOrValue    = 1;    protected static final int longKeyOrValue   = 2;    protected static final int objectKeyOrValue = 3;    // purgePolicy    protected static final int NO_PURGE      = 0;    protected static final int PURGE_ALL     = 1;    protected static final int PURGE_HALF    = 2;    protected static final int PURGE_QUARTER = 3;    protected BaseHashMap(int initialCapacity, float loadFactor, int keyType,                          int valueType,                          boolean hasAccessCount)                          throws IllegalArgumentException {        if (initialCapacity <= 0 || loadFactor <= 0.0) {            throw new IllegalArgumentException();        }        this.loadFactor      = loadFactor;        this.initialCapacity = initialCapacity;        threshold            = initialCapacity;        if (threshold < 3) {            threshold = 3;        }        int hashtablesize = (int) (initialCapacity * loadFactor);        if (hashtablesize < 3) {            hashtablesize = 3;        }        hashIndex = new HashIndex(hashtablesize, initialCapacity, true);        int arraySize = threshold;        if (keyType == BaseHashMap.intKeyOrValue) {            isIntKey    = true;            intKeyTable = new int[arraySize];        } else if (keyType == BaseHashMap.objectKeyOrValue) {            isObjectKey    = true;            objectKeyTable = new Object[arraySize];        } else {            isLongKey    = true;            longKeyTable = new long[arraySize];        }        if (valueType == BaseHashMap.intKeyOrValue) {            isIntValue    = true;            intValueTable = new int[arraySize];        } else if (valueType == BaseHashMap.objectKeyOrValue) {            isObjectValue    = true;            objectValueTable = new Object[arraySize];        } else if (valueType == BaseHashMap.longKeyOrValue) {            isLongValue    = true;            longValueTable = new long[arraySize];        } else {            isNoValue = true;        }        if (hasAccessCount) {            accessTable = new int[arraySize];        }    }    protected int getLookup(Object key, int hash) {        int    lookup = hashIndex.getLookup(hash);        Object tempKey;        for (; lookup >= 0; lookup = hashIndex.getNextLookup(lookup)) {            tempKey = objectKeyTable[lookup];            if (key.equals(tempKey)) {                return lookup;            }        }        return lookup;    }    protected int getLookup(int key) {        int lookup = hashIndex.getLookup(key);        int tempKey;        for (; lookup >= 0; lookup = hashIndex.getNextLookup(lookup)) {            tempKey = intKeyTable[lookup];            if (key == tempKey) {                return lookup;            }        }        return lookup;    }    protected int getLookup(long key) {        int  lookup = hashIndex.getLookup((int) key);        long tempKey;        for (; lookup >= 0; lookup = hashIndex.getNextLookup(lookup)) {            tempKey = longKeyTable[lookup];            if (key == tempKey) {                return lookup;            }        }        return lookup;    }    /**     * generic method for adding or removing keys     */    protected Object addOrRemove(long longKey, long longValue,                                 Object objectKey, Object objectValue,                                 boolean remove) {        int hash = (int) longKey;        if (isObjectKey) {            if (objectKey == null) {                return null;            }            hash = objectKey.hashCode();        }        int    index       = hashIndex.getHashIndex(hash);        int    lookup      = hashIndex.hashTable[index];        int    lastLookup  = -1;        Object returnValue = null;        for (; lookup >= 0;                lastLookup = lookup,                lookup = hashIndex.getNextLookup(lookup)) {            if (isObjectKey) {                if (objectKeyTable[lookup].equals(objectKey)) {                    break;                }            } else if (isIntKey) {                if (longKey == intKeyTable[lookup]) {                    break;                }            } else if (isLongKey) {                if (longKey == longKeyTable[lookup]) {                    break;                }            }        }        if (lookup >= 0) {            if (remove) {                if (isObjectKey) {                    objectKeyTable[lookup] = null;                } else {                    if (longKey == 0) {                        hasZeroKey   = false;                        zeroKeyIndex = -1;                    }                    if (isIntKey) {                        intKeyTable[lookup] = 0;                    } else {                        longKeyTable[lookup] = 0;                    }                }                if (isObjectValue) {                    returnValue              = objectValueTable[lookup];                    objectValueTable[lookup] = null;                } else if (isIntValue) {                    intValueTable[lookup] = 0;                } else if (isLongValue) {                    longValueTable[lookup] = 0;                }                hashIndex.unlinkNode(index, lastLookup, lookup);                if (accessTable != null) {                    accessTable[lookup] = 0;                }                if (minimizeOnEmpty && hashIndex.elementCount == 0) {                    rehash(initialCapacity);                }                return returnValue;            }            if (isObjectValue) {                returnValue              = objectValueTable[lookup];                objectValueTable[lookup] = objectValue;            } else if (isIntValue) {                intValueTable[lookup] = (int) longValue;            } else if (isLongValue) {                longValueTable[lookup] = longValue;            }            if (accessTable != null) {                accessTable[lookup] = accessCount++;            }            return returnValue;        }        // not found        if (remove) {            return null;        }        if (hashIndex.elementCount >= threshold) {            // should throw maybe, if reset returns false?            if (reset()) {                return addOrRemove(longKey, longValue, objectKey,                                   objectValue, remove);            } else {                return null;            }        }        lookup = hashIndex.linkNode(index, lastLookup);        // type dependent block        if (isObjectKey) {            objectKeyTable[lookup] = objectKey;        } else if (isIntKey) {            intKeyTable[lookup] = (int) longKey;            if (longKey == 0) {                hasZeroKey   = true;                zeroKeyIndex = lookup;            }        } else if (isLongKey) {            longKeyTable[lookup] = longKey;            if (longKey == 0) {                hasZeroKey   = true;                zeroKeyIndex = lookup;            }        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -