ExpandedNameTablepublic class ExpandedNameTable extends Object This is a default implementation of a table that manages mappings from
expanded names to expandedNameIDs.
%OPT% The performance of the getExpandedTypeID() method is very important
to DTM building. To get the best performance out of this class, we implement
a simple hash algorithm directly into this class, instead of using the
inefficient java.util.Hashtable. The code for the get and put operations
are combined in getExpandedTypeID() method to share the same hash calculation
code. We only need to implement the rehash() interface which is used to
expand the hash table. |
Fields Summary |
---|
private ExtendedType[] | m_extendedTypesArray of extended types for this document | private static int | m_initialSizeThe initial size of the m_extendedTypes array | private int | m_nextTypeNext available extended type | public static final int | ELEMENT | public static final int | ATTRIBUTE | public static final int | TEXT | public static final int | CDATA_SECTION | public static final int | ENTITY_REFERENCE | public static final int | ENTITY | public static final int | PROCESSING_INSTRUCTION | public static final int | COMMENT | public static final int | DOCUMENT | public static final int | DOCUMENT_TYPE | public static final int | DOCUMENT_FRAGMENT | public static final int | NOTATION | public static final int | NAMESPACE | ExtendedType | hashETWorkspace for lookup. NOT THREAD SAFE! | private static ExtendedType[] | m_defaultExtendedTypesThe array to store the default extended types. | private static float | m_loadFactorThe default load factor of the Hashtable.
This is used to calcualte the threshold. | private static int | m_initialCapacityThe initial capacity of the hash table. Use a bigger number
to avoid the cost of expanding the table. | private int | m_capacityThe capacity of the hash table, i.e. the size of the
internal HashEntry array. | private int | m_thresholdThe threshold of the hash table, which is equal to capacity * loadFactor.
If the number of entries in the hash table is bigger than the threshold,
the hash table needs to be expanded. | private HashEntry[] | m_tableThe internal array to store the hash entries.
Each array member is a slot for a hash bucket. |
Constructors Summary |
---|
public ExpandedNameTable()Create an expanded name table.
m_defaultExtendedTypes = new ExtendedType[DTM.NTYPES];
for (int i = 0; i < DTM.NTYPES; i++)
{
m_defaultExtendedTypes[i] = new ExtendedType(i, "", "");
}
m_capacity = m_initialCapacity;
m_threshold = (int)(m_capacity * m_loadFactor);
m_table = new HashEntry[m_capacity];
initExtendedTypes();
|
Methods Summary |
---|
public int | getExpandedTypeID(java.lang.String namespace, java.lang.String localName, int type)Given an expanded name represented by namespace, local name and node type,
return an ID. If the expanded-name does not exist in the internal tables,
the entry will be created, and the ID will be returned. Any additional
nodes that are created that have this expanded name will use this ID.
return getExpandedTypeID(namespace, localName, type, false);
| public int | getExpandedTypeID(java.lang.String namespace, java.lang.String localName, int type, boolean searchOnly)Given an expanded name represented by namespace, local name and node type,
return an ID. If the expanded-name does not exist in the internal tables,
the entry will be created, and the ID will be returned. Any additional
nodes that are created that have this expanded name will use this ID.
If searchOnly is true, we will return -1 if the name is not found in the
table, otherwise the name is added to the table and the expanded name id
of the new entry is returned.
if (null == namespace)
namespace = "";
if (null == localName)
localName = "";
// Calculate the hash code
int hash = type + namespace.hashCode() + localName.hashCode();
// Redefine the hashET object to represent the new expanded name.
hashET.redefine(type, namespace, localName, hash);
// Calculate the index into the HashEntry table.
int index = hash % m_capacity;
if (index < 0)
index = -index;
// Look up the expanded name in the hash table. Return the id if
// the expanded name is already in the hash table.
for (HashEntry e = m_table[index]; e != null; e = e.next)
{
if (e.hash == hash && e.key.equals(hashET))
return e.value;
}
if (searchOnly)
{
return DTM.NULL;
}
// Expand the internal HashEntry array if necessary.
if (m_nextType > m_threshold) {
rehash();
index = hash % m_capacity;
if (index < 0)
index = -index;
}
// Create a new ExtendedType object
ExtendedType newET = new ExtendedType(type, namespace, localName, hash);
// Expand the m_extendedTypes array if necessary.
if (m_extendedTypes.length == m_nextType) {
ExtendedType[] newArray = new ExtendedType[m_extendedTypes.length * 2];
System.arraycopy(m_extendedTypes, 0, newArray, 0,
m_extendedTypes.length);
m_extendedTypes = newArray;
}
m_extendedTypes[m_nextType] = newET;
// Create a new hash entry for the new ExtendedType and put it into
// the table.
HashEntry entry = new HashEntry(newET, m_nextType, hash, m_table[index]);
m_table[index] = entry;
return m_nextType++;
| public int | getExpandedTypeID(int type)Given a type, return an expanded name ID.Any additional nodes that are
created that have this expanded name will use this ID.
return type;
| public com.sun.org.apache.xml.internal.dtm.ref.ExtendedType[] | getExtendedTypes()Return the array of extended types
return m_extendedTypes;
| public java.lang.String | getLocalName(int ExpandedNameID)Given an expanded-name ID, return the local name part.
return m_extendedTypes[ExpandedNameID].getLocalName();
| public final int | getLocalNameID(int ExpandedNameID)Given an expanded-name ID, return the local name ID.
// ExtendedType etype = m_extendedTypes[ExpandedNameID];
if (m_extendedTypes[ExpandedNameID].getLocalName().equals(""))
return 0;
else
return ExpandedNameID;
| public java.lang.String | getNamespace(int ExpandedNameID)Given an expanded-name ID, return the namespace URI part.
String namespace = m_extendedTypes[ExpandedNameID].getNamespace();
return (namespace.equals("") ? null : namespace);
| public final int | getNamespaceID(int ExpandedNameID)Given an expanded-name ID, return the namespace URI ID.
//ExtendedType etype = m_extendedTypes[ExpandedNameID];
if (m_extendedTypes[ExpandedNameID].getNamespace().equals(""))
return 0;
else
return ExpandedNameID;
| public int | getSize()Return the size of the ExpandedNameTable
return m_nextType;
| public final short | getType(int ExpandedNameID)Given an expanded-name ID, return the local name ID.
//ExtendedType etype = m_extendedTypes[ExpandedNameID];
return (short)m_extendedTypes[ExpandedNameID].getNodeType();
| private void | initExtendedTypes()Initialize the vector of extended types with the
basic DOM node types.
m_extendedTypes = new ExtendedType[m_initialSize];
for (int i = 0; i < DTM.NTYPES; i++) {
m_extendedTypes[i] = m_defaultExtendedTypes[i];
m_table[i] = new HashEntry(m_defaultExtendedTypes[i], i, i, null);
}
m_nextType = DTM.NTYPES;
| private void | rehash()Increases the capacity of and internally reorganizes the hashtable,
in order to accommodate and access its entries more efficiently.
This method is called when the number of keys in the hashtable exceeds
this hashtable's capacity and load factor.
int oldCapacity = m_capacity;
HashEntry[] oldTable = m_table;
int newCapacity = 2 * oldCapacity + 1;
m_capacity = newCapacity;
m_threshold = (int)(newCapacity * m_loadFactor);
m_table = new HashEntry[newCapacity];
for (int i = oldCapacity-1; i >=0 ; i--)
{
for (HashEntry old = oldTable[i]; old != null; )
{
HashEntry e = old;
old = old.next;
int newIndex = e.hash % newCapacity;
if (newIndex < 0)
newIndex = -newIndex;
e.next = m_table[newIndex];
m_table[newIndex] = e;
}
}
|
|