FileDocCategorySizeDatePackage
SimpleHashtable.javaAPI DocApache Tomcat 6.0.149182Fri Jul 20 04:20:34 BST 2007org.apache.tomcat.util.collections

SimpleHashtable

public final class SimpleHashtable extends Object implements Enumeration
This class implements a special purpose hashtable. It works like a normal java.util.Hashtable except that:
  1. Keys to "get" are strings which are known to be interned, so that "==" is used instead of "String.equals". (Interning could be document-relative instead of global.)
  2. It's not synchronized, since it's to be used only by one thread at a time.
  3. The keys () enumerator allocates no memory, with live updates to the data disallowed.
  4. It's got fewer bells and whistles: fixed threshold and load factor, no JDK 1.2 collection support, only keys can be enumerated, things can't be removed, simpler inheritance; more.

The overall result is that it's less expensive to use these in performance-critical locations, in terms both of CPU and memory, than java.util.Hashtable instances. In this package it makes a significant difference when normalizing attributes, which is done for each start-element construct.

Fields Summary
private static org.apache.juli.logging.Log
log
private Entry[]
table
private Entry
current
private int
currentBucket
private int
count
private int
threshold
private static final float
loadFactor
private static final int
dL
Constructors Summary
public SimpleHashtable(int initialCapacity)
Constructs a new, empty hashtable with the specified initial capacity.

param
initialCapacity the initial capacity of the hashtable.



                                   
       
	if (initialCapacity < 0)
	    throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (initialCapacity==0)
            initialCapacity = 1;
	table = new Entry[initialCapacity];
	threshold = (int)(initialCapacity * loadFactor);
    
public SimpleHashtable()
Constructs a new, empty hashtable with a default capacity.

	this(11);
    
Methods Summary
public voidclear()

	count = 0;
	currentBucket = 0;
	current = null;
	for (int i = 0; i < table.length; i++)
	    table [i] = null;
    
private voidd(java.lang.String s)

         
	if (log.isDebugEnabled())
            log.debug( "SimpleHashtable: " + s );
    
public java.lang.Objectget(java.lang.String key)
Returns the value to which the specified key is mapped in this hashtable ... the key isn't necessarily interned, though.

	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && e.key.equals(key))
		return e.value;
	}
	return null;
    
public java.lang.ObjectgetInterned(java.lang.String key)
Returns the value to which the specified key is mapped in this hashtable.

	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && (e.key == key))
		return e.value;
	}
	return null;
    
public booleanhasMoreElements()
Used to view this as an enumeration; returns true if there are more keys to be enumerated.

	if (current != null)
	    return true;
	while (currentBucket < table.length) {
	    current = table [currentBucket++];
	    if (current != null)
		return true;
	}
	return false;
    
public java.util.Enumerationkeys()
Returns an enumeration of the keys in this hashtable.

return
an enumeration of the keys in this hashtable.
see
Enumeration

	currentBucket = 0;
	current = null;
	hasMoreElements();
	return this;
    
public java.lang.ObjectnextElement()
Used to view this as an enumeration; returns the next key in the enumeration.

	Object retval;

	if (current == null)
	    throw new IllegalStateException ();
	retval = current.key;
	current = current.next;
	// Advance to the next position ( we may call next after next,
	// without hasMore )
	hasMoreElements();
	return retval;
    
public java.lang.Objectput(java.lang.Object key, java.lang.Object value)
Maps the specified key to the specified value in this hashtable. Neither the key nor the value can be null.

The value can be retrieved by calling the get method with a key that is equal to the original key.

	// Make sure the value is not null
	if (value == null) {
	    throw new NullPointerException();
	}

	// Makes sure the key is not already in the hashtable.
	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry e = tab[index] ; e != null ; e = e.next) {
	    // if ((e.hash == hash) && e.key.equals(key)) {
	    if ((e.hash == hash) && (e.key == key)) {
		Object old = e.value;
		e.value = value;
		return old;
	    }
	}

	if (count >= threshold) {
	    // Rehash the table if the threshold is exceeded
	    rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
	} 

	// Creates the new entry.
	Entry e = new Entry(hash, key, value, tab[index]);
	tab[index] = e;
	count++;
	return null;
    
private voidrehash()
Increases the capacity of and internally reorganizes this hashtable, in order to accommodate and access its entries more efficiently. This method is called automatically when the number of keys in the hashtable exceeds this hashtable's capacity and load factor.

	int oldCapacity = table.length;
	Entry oldMap[] = table;

	int newCapacity = oldCapacity * 2 + 1;
	Entry newMap[] = new Entry[newCapacity];

	threshold = (int)(newCapacity * loadFactor);
	table = newMap;

	/*
	System.out.pr intln("rehash old=" + oldCapacity
		+ ", new=" + newCapacity
		+ ", thresh=" + threshold
		+ ", count=" + count);
	*/

	for (int i = oldCapacity ; i-- > 0 ;) {
	    for (Entry old = oldMap[i] ; old != null ; ) {
		Entry e = old;
		old = old.next;

		int index = (e.hash & 0x7FFFFFFF) % newCapacity;
		e.next = newMap[index];
		newMap[index] = e;
	    }
	}
    
public java.lang.Objectremove(java.lang.Object key)

	Entry tab[] = table;
	Entry prev=null;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	if( dL > 0 ) d("Idx " + index +  " " + tab[index] );
	for (Entry e = tab[index] ; e != null ; prev=e, e = e.next) {
	    if( dL > 0 ) d("> " + prev + " " + e.next + " " + e + " " + e.key);
	    if ((e.hash == hash) && e.key.equals(key)) {
		if( prev!=null ) {
		    prev.next=e.next;
		} else {
		    tab[index]=e.next;
		}
		if( dL > 0 ) d("Removing from list " + tab[index] + " " + prev +
			       " " + e.value);
		count--;
		Object res=e.value;
		e.value=null;
		return res;
	    }
	}
	return null;
    
public intsize()
Returns the number of keys in this hashtable.

return
the number of keys in this hashtable.

	return count;