Data Type Java

/*
 * $Id: CharStringConverter.java,v 1.3 2004/07/08 08:01:45 yuvalo Exp $
 *
 * (C) Copyright 2002-2004 by Yuval Oren. All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
//package  com.bluecast.util;
import  java.io.*;
import  java.util.*;
/**
 * A fast way to convert character arrays into Strings. This class maintains
 * a hashtable of char[] -> String mappings. Returned Strings are guaranteed
 * to be internalized.
 *
 * @author Yuval Oren, yuval@bluecast.com
 * @version $Revision: 1.3 $
 */
final public class CharStringConverter {
    private static final float DEFAULT_LOAD = 0.70F;
    private float loadFactor;
    private int numEntries = 0;
    private int maxEntries;
    private int hashmask;
    private char[][] keys;
    private String[] values;
    public CharStringConverter (int initialCapacity, float loadFactor) {
        if (initialCapacity < 0) {
            throw  new IllegalArgumentException("Illegal initial capacity: "
                    + initialCapacity);
        }
        if (loadFactor < 0 || loadFactor > 1) {
            throw  new IllegalArgumentException("Illegal load factor: " + loadFactor);
        }
        int desiredSize = (int)((float)initialCapacity/loadFactor);
        int size = 16;
        while (size < desiredSize) {
            size <<= 1;
        }
        hashmask = size - 1;
        maxEntries = (int)(size*loadFactor);
        keys = new char[size][];
        values = new String[size];
        this.loadFactor = loadFactor;
    }
    public CharStringConverter () {
        this(0, DEFAULT_LOAD);
    }
    public CharStringConverter (int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD);
    }
    /**
     * Returns the number of cached conversion mappings.
     */
    public int getCacheSize () {
        return  numEntries;
    }
    /**
     * Converts a character array into an internalized String.
     */
    public String convert (char[] ch) {
        return  convert(ch, 0, ch.length);
    }
    /**
     * Converts a character array into an internalized String.
     *
     * @param ch character array to convert
     * @param start starting offset of ch[]
     * @param length number of characters to read
     */
    public String convert (char[] ch, int start, int length) {
        if (numEntries >= maxEntries) {
            rehash();
        }
        // Look for the cached String for this char array
        int offset = hashKey(ch, start, length) & hashmask;
        char[] k = null;
        while ((k = keys[offset]) != null && !keysAreEqual(k, 0, k.length,
                ch, start, length)) {
            offset = (offset - 1) & hashmask;
        }
        if (k != null) {
            return  values[offset];
        }
        else {
            // Add the conversion to the cache
            k = new char[length];
            System.arraycopy(ch, start, k, 0, length);
            String v = new String(k).intern();
            keys[offset] = k;
            values[offset] = v;
            numEntries++;
            return  v;
        }
    }
    private void rehash () {
        int newlength = keys.length << 1;
        char[][] newkeys = new char[newlength][];
        String[] newvalues = new String[newlength];
        int newhashmask = newlength - 1;
        for (int i = 0; i < keys.length; i++) {
            char[] k = keys[i];
            String v = values[i];
            if (k != null) {
                int newoffset = hashKey(k, 0, k.length) & newhashmask;
                char[] newk = null;
                while ((newk = newkeys[newoffset]) != null && !keysAreEqual(newk,
                        0, newk.length, k, 0, k.length)) {
                    newoffset = (newoffset - 1) & newhashmask;
                }
                newkeys[newoffset] = k;
                newvalues[newoffset] = v;
            }
        }
        keys = newkeys;
        values = newvalues;
        maxEntries = (int)(newlength*loadFactor);
        hashmask = newhashmask;
    }
    public void clearCache () {
        for (int i = 0; i < keys.length; i++) {
            keys[i] = null;
            values[i] = null;
        }
        numEntries = 0;
    }
    private static final boolean keysAreEqual (char[] a, int astart, int alength,
            char[] b, int bstart, int blength) {
        if (alength != blength) {
            return  false;
        }
        else {
            for (int i = 0; i < alength; i++) {
                if (a[astart + i] != b[bstart + i]) {
                    return  false;
                }
            }
            return  true;
        }
    }
    private static final int hashKey (char ch[], int start, int length) {
        int hash = 0;
        for (int i = 0; i < length; i++) {
            hash = (hash << 5) + ch[start + i];
        }
        return  hash;
    }
}