jkesselm 01/11/26 14:08:28
Modified: java/src/org/apache/xalan/lib/sql DTMDocument.java
java/src/org/apache/xalan/templates ElemApplyTemplates.java
java/src/org/apache/xalan/xslt Process.java
java/src/org/apache/xml/dtm DTMManager.java
java/src/org/apache/xml/dtm/ref DTMDefaultBase.java
DTMDefaultBaseIterators.java
DTMDefaultBaseTraversers.java
DTMManagerDefault.java
java/src/org/apache/xml/dtm/ref/dom2dtm DOM2DTM.java
java/src/org/apache/xml/dtm/ref/sax2dtm SAX2DTM.java
Log:
Another fairly large change in the DTM architexture (sic)....
We've changed DTM's internal behavior so it can now assign
more than one "DTM ID" to a single document, cascading from
one ID to the next. This means that the size of a single DTM is
no longer limited by the bits available in the low part of the DTM
Node Handle. This means we can support larger documents.
That has allowed us to reduce the number of bits reserved
for that portion of the node addresing scheme... which in turn has
increased the number of bits available for use in the DTM ID. This
means we can now have many more documents active at once.
The trade-off is that huge documents will require more than one
DTM ID and thus cut into the number of documents, But since we
now have 16 bits of DTM ID space, I don't think we're really likely
to run into both limits at once. And the changes are essentially
limited to the DTM layer; the rest of Xalan should be unaffected.
In the process of making this change, I've also encapsulated the
conversions between DTM API node handles and DTMDefaultBase's
internal node indices. That should be safer all 'round.
NOTE: One side effect of this change is that the strings
generated by the key() function have changed again.
I've updated the IDKEY testcases to reflect this.
Smoketest is currently passing everything except
axes109 and the API's TraceListenerTest . But I believe
those failures are due to a glitch in my test directory
since they also happen when I run the D13 code there,
whereas D13 runs fine in the directory where I built it.
I'm going to assume that "same result is no new bug"
for now.
Revision Changes Path
1.4 +2 -2
xml-xalan/java/src/org/apache/xalan/lib/sql/DTMDocument.java
Index: DTMDocument.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/DTMDocument.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DTMDocument.java 2001/08/10 22:10:46 1.3
+++ DTMDocument.java 2001/11/26 22:08:27 1.4
@@ -364,7 +364,7 @@
{
if (DEBUG) System.out.println("getFirstAttribute("+
(parm1&NODEIDENTITYBITS)+")");
int nodeIdx = parm1 & NODEIDENTITYBITS;
- if (nodeIdx != DTM.NULL) return m_attribute.elementAt(nodeIdx) |
m_dtmIdent;
+ if (nodeIdx != DTM.NULL) return
makeNodeHandle(m_attribute.elementAt(nodeIdx));
else return DTM.NULL;
}
@@ -430,7 +430,7 @@
{
if (DEBUG) System.out.println("getNextAttribute(" + parm1 + ")");
int nodeIdx = parm1 & NODEIDENTITYBITS;
- if (nodeIdx != DTM.NULL) return m_nextsib.elementAt(nodeIdx) |
m_dtmIdent;
+ if (nodeIdx != DTM.NULL) return
makeNodeHandle(m_nextsib.elementAt(nodeIdx));
else return DTM.NULL;
}
1.18 +1 -3
xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java
Index: ElemApplyTemplates.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- ElemApplyTemplates.java 2001/10/18 20:30:44 1.17
+++ ElemApplyTemplates.java 2001/11/26 22:08:28 1.18
@@ -292,7 +292,6 @@
// Should be able to get this from the iterator but there must be a
bug.
DTM dtm = xctxt.getDTM(sourceNode);
- int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
int argsFrame = -1;
if(nParams > 0)
@@ -319,10 +318,9 @@
currentNodes[currentNodePos] = child;
currentExpressionNodes[currentExpressionNodePos] = child;
- if((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
+ if(xctxt.getDTM(child) != dtm)
{
dtm = xctxt.getDTM(child);
- docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
}
final int exNodeType = dtm.getExpandedTypeID(child);
1.43 +1 -1 xml-xalan/java/src/org/apache/xalan/xslt/Process.java
Index: Process.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xslt/Process.java,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- Process.java 2001/10/31 19:57:38 1.42
+++ Process.java 2001/11/26 22:08:28 1.43
@@ -554,7 +554,7 @@
tfactory.setAttribute
("http://xml.apache.org/xalan/features/optimize",
java.lang.Boolean.FALSE);
- }
+ }
else
System.err.println(
XSLMessages.createMessage(
1.8 +7 -4 xml-xalan/java/src/org/apache/xml/dtm/DTMManager.java
Index: DTMManager.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xml/dtm/DTMManager.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DTMManager.java 2001/09/13 18:32:41 1.7
+++ DTMManager.java 2001/11/26 22:08:28 1.8
@@ -524,15 +524,18 @@
* files which use it... including the IDKey testcases.
*
* (FuncGenerateKey currently uses the node identifier directly and
- * thus is sensitive to its format. The IDKEY results will still be
+ * thus is affected when this changes. The IDKEY results will still be
* _correct_ (presuming no other breakage), but simple equality
* comparison against the previous "golden" files will probably
- * complain.) */
- public static final int IDENT_DTM_NODE_BITS = 22;
+ * complain.)
+ * */
+ public static final int IDENT_DTM_NODE_BITS = 16;
/** When this bitmask is ANDed with a DTM node handle number, the result
- * is the node's index number within that DTM.
+ * is the low bits of the node's index number within that DTM. To obtain
+ * the high bits, add the DTM ID portion's offset as assigned in the DTM
+ * Manager.
*/
public static final int IDENT_NODE_DEFAULT = (1<<IDENT_DTM_NODE_BITS)-1;
1.21 +126 -52
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java
Index: DTMDefaultBase.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBase.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- DTMDefaultBase.java 2001/10/01 15:36:17 1.20
+++ DTMDefaultBase.java 2001/11/26 22:08:28 1.21
@@ -90,6 +90,9 @@
*/
public abstract class DTMDefaultBase implements DTM
{
+ static boolean JJK_DEBUG=false;
+
+
/**
* The number of nodes, which is also used to determine the next
* node index.
@@ -142,13 +145,14 @@
*/
protected DTMManager m_mgr;
- /** The document identity, which is OR'd with node indexes to make
handles. */
- protected int m_dtmIdent;
+ /** The document identity number(s). If we have overflowed the addressing
+ * range of the first that was assigned to us, we may add others. */
+ protected SuballocatedIntVector m_dtmIdent=new SuballocatedIntVector();
/** The mask for the identity.
%REVIEW% Should this really be set to the _DEFAULT? What if
a particular DTM wanted to use another value? */
- protected final static int m_mask = DTMManager.IDENT_NODE_DEFAULT;
+ //protected final static int m_mask = DTMManager.IDENT_NODE_DEFAULT;
/** The base URI for this document. */
protected String m_documentBaseURI;
@@ -210,8 +214,7 @@
m_mgr = mgr;
m_documentBaseURI = (null != source) ? source.getSystemId() : null;
- m_dtmIdent = dtmIdentity;
- // m_mask = mgr.getNodeIdentityMask();
+ m_dtmIdent.setElementAt(dtmIdentity,0);
m_wsfilter = whiteSpaceFilter;
m_xstrf = xstringfactory;
m_indexing = doIndexing;
@@ -449,7 +452,7 @@
protected short _type(int identity)
{
- int info = getExpandedTypeID(identity);
+ int info = _exptype(identity);
if (NULL != info)
return ExpandedNameTable.getType(info);
@@ -646,12 +649,12 @@
ps.println("NamespaceURI: " + getNamespaceURI(i));
ps.println("Prefix: " + getPrefix(i));
- int exTypeID = getExpandedTypeID(i);
+ int exTypeID = _exptype(i);
ps.println("Expanded Type ID: "
+ Integer.toHexString(exTypeID));
- int type = getNodeType(i);
+ int type = _type(i);
String typestring;
switch (type)
@@ -860,12 +863,66 @@
public boolean hasChildNodes(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int firstChild = _firstch(identity);
return firstChild != DTM.NULL;
}
+
+ /** Given a node identity, return a node handle. If extended addressing
+ * has been used (multiple DTM IDs), we need to map the high bits of the
+ * identity into the proper DTM ID.
+ *
+ * This has been made FINAL to facilitate inlining, since we do not expect
+ * any subclass of DTMDefaultBase to ever change the algorithm. (I don't
+ * really like doing so, and would love to have an excuse not to...)
+ *
+ * %REVIEW% Is it worth trying to specialcase small documents?
+ * %REVIEW% Should this be exposed at the package/public layers?
+ *
+ * @param nodeIdentity Internal offset to this node's records.
+ * @return NodeHandle (external representation of node)
+ * */
+ final protected int makeNodeHandle(int nodeIdentity)
+ {
+ if(NULL==nodeIdentity) return NULL;
+
+ if(JJK_DEBUG && nodeIdentity>DTMManager.IDENT_NODE_DEFAULT)
+ System.err.println("GONK! (only useful in limited situations)");
+
+ return m_dtmIdent.elementAt(nodeIdentity >>>
DTMManager.IDENT_DTM_NODE_BITS)
+ + (nodeIdentity & DTMManager.IDENT_NODE_DEFAULT) ;
+ }
+
+ /** Given a node handle, return a node identity. If extended addressing
+ * has been used (multiple DTM IDs), we need to map the high bits of the
+ * identity into the proper DTM ID and thence find the proper offset
+ * to add to the low bits of the identity
+ *
+ * This has been made FINAL to facilitate inlining, since we do not expect
+ * any subclass of DTMDefaultBase to ever change the algorithm. (I don't
+ * really like doing so, and would love to have an excuse not to...)
+ *
+ * %REVIEW% Should this be exposed at the package/public layers?
+ *
+ * @param NodeHandle (external representation of node)
+ * @return nodeIdentity Internal offset to this node's records.
+ * */
+ final protected int makeNodeIdentity(int nodeHandle)
+ {
+ if(NULL==nodeHandle) return NULL;
+
+ if(JJK_DEBUG && nodeHandle<DTMManager.IDENT_NODE_DEFAULT)
+ System.err.println("GONK! (only useful in limited situations)");
+
+ int whichDTMid=m_dtmIdent.indexOf(nodeHandle &
DTMManager.IDENT_DTM_DEFAULT);
+ return (whichDTMid==NULL)
+ ? NULL
+ : (whichDTMid << DTMManager.IDENT_DTM_NODE_BITS)
+ + (nodeHandle & DTMManager.IDENT_NODE_DEFAULT);
+ }
+
/**
* Given a node handle, get the handle of the node's first child.
* If not yet resolved, waits for more nodes to be added to the document
and
@@ -877,10 +934,10 @@
public int getFirstChild(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int firstChild = _firstch(identity);
- return firstChild | m_dtmIdent;
+ return makeNodeHandle(firstChild);
}
/**
@@ -895,7 +952,7 @@
public int getLastChild(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int child = _firstch(identity);
int lastChild = DTM.NULL;
@@ -905,7 +962,7 @@
child = _nextsib(child);
}
- return lastChild | m_dtmIdent;
+ return makeNodeHandle(lastChild);
}
/**
@@ -938,17 +995,17 @@
{
// Assume that attributes and namespaces immediately follow the
element.
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
// Assume this can not be null.
- type = getNodeType(identity);
+ type = _type(identity);
if (type == DTM.ATTRIBUTE_NODE)
{
- return identity | m_dtmIdent;
+ return makeNodeHandle(identity);
}
else if (DTM.NAMESPACE_NODE != type)
{
@@ -970,7 +1027,7 @@
*/
public int getNextSibling(int nodeHandle)
{
- return _nextsib(nodeHandle & m_mask) | m_dtmIdent;
+ return makeNodeHandle(_nextsib(makeNodeIdentity(nodeHandle)));
}
/**
@@ -984,7 +1041,7 @@
*/
public int getPreviousSibling(int nodeHandle)
{
- return _prevsib(nodeHandle & m_mask) | m_dtmIdent;
+ return makeNodeHandle(_prevsib(makeNodeIdentity(nodeHandle)));
}
/**
@@ -1004,15 +1061,15 @@
if (DTM.ATTRIBUTE_NODE == type)
{
// Assume that attributes and namespace nodes immediately follow the
element.
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
- type = getNodeType(identity);
+ type = _type(identity);
if (type == DTM.ATTRIBUTE_NODE)
{
- return identity | m_dtmIdent;
+ return makeNodeHandle(identity);
}
else if (type != DTM.NAMESPACE_NODE)
{
@@ -1092,17 +1149,17 @@
// %OPT% Keep sorted? (By expanded-name rather than by doc order...)
// Downside: Would require insertElementAt if not found,
// which has recopying costs. But these are generally short lists...
- int newEType=getExpandedTypeID(namespaceNodeIndex);
+ int newEType=_exptype(namespaceNodeIndex);
for(int i=nsList.size()-1;i>=0;--i)
{
if(newEType==getExpandedTypeID(nsList.elementAt(i)))
{
- nsList.setElementAt(namespaceNodeIndex | m_dtmIdent,i);
+ nsList.setElementAt(makeNodeHandle(namespaceNodeIndex),i);
return;
}
}
- nsList.addElement(namespaceNodeIndex | m_dtmIdent);
+ nsList.addElement(makeNodeHandle(namespaceNodeIndex));
}
/** Retrieve list of namespace declaration locations
@@ -1211,11 +1268,11 @@
{
if(inScope)
{
- SuballocatedIntVector nsContext=findNamespaceContext(nodeHandle
& m_mask);
+ SuballocatedIntVector
nsContext=findNamespaceContext(makeNodeIdentity(nodeHandle));
if(nsContext==null || nsContext.size()<1)
return NULL;
- return nsContext.elementAt(0) | m_dtmIdent;
+ return nsContext.elementAt(0);
}
else
{
@@ -1225,12 +1282,12 @@
// %OPT% Would things be faster if all NS nodes were built
// before all Attr nodes? Some costs at build time for 2nd
// pass...
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
- int type = getNodeType(identity);
+ int type = _type(identity);
if (type == DTM.NAMESPACE_NODE)
- return identity | m_dtmIdent;
+ return makeNodeHandle(identity);
else if (DTM.ATTRIBUTE_NODE != type)
break;
}
@@ -1260,7 +1317,7 @@
//comparison/get-parent faster)
//SuballocatedIntVector
nsContext=findNamespaceContext(nodeHandle & m_mask);
- SuballocatedIntVector
nsContext=findNamespaceContext(baseHandle & m_mask);
+ SuballocatedIntVector
nsContext=findNamespaceContext(makeNodeIdentity(baseHandle));
if(nsContext==null)
return NULL;
@@ -1268,18 +1325,18 @@
if(i<=0 || i==nsContext.size())
return NULL;
- return nsContext.elementAt(i) | m_dtmIdent;
+ return nsContext.elementAt(i);
}
else
{
// Assume that attributes and namespace nodes immediately follow
the element.
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
- int type = getNodeType(identity);
+ int type = _type(identity);
if (type == DTM.NAMESPACE_NODE)
{
- return identity | m_dtmIdent;
+ return makeNodeHandle(identity);
}
else if (type != DTM.ATTRIBUTE_NODE)
{
@@ -1300,10 +1357,10 @@
public int getParent(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
if (identity > 0)
- return _parent(identity) | m_dtmIdent;
+ return makeNodeHandle(_parent(identity));
else
return DTM.NULL;
}
@@ -1316,7 +1373,7 @@
*/
public int getDocument()
{
- return m_dtmIdent;
+ return m_dtmIdent.elementAt(0); // makeNodeHandle(0)
}
/**
@@ -1409,8 +1466,7 @@
*/
public int getExpandedTypeID(int nodeHandle)
{
-
- return _exptype(nodeHandle & m_mask);
+ return _exptype(makeNodeIdentity(nodeHandle));
}
/**
@@ -1469,7 +1525,7 @@
public int getNamespaceType(final int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int expandedNameID = _exptype(identity);
return ExpandedNameTable.getNamespaceID(expandedNameID);
@@ -1562,7 +1618,7 @@
*/
public short getNodeType(int nodeHandle)
{
- return (short)(_exptype(nodeHandle & m_mask) >>
ExpandedNameTable.ROTAMOUNT_TYPE);
+ return (short)(_exptype(makeNodeIdentity(nodeHandle)) >>
ExpandedNameTable.ROTAMOUNT_TYPE);
}
/**
@@ -1576,7 +1632,7 @@
public short getLevel(int nodeHandle)
{
// Apparently, the axis walker stuff requires levels to count from 1.
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
return (short) (_level(identity) + 1);
}
@@ -1796,26 +1852,22 @@
* by other XML applications.
* <p>
* There are some cases where ordering isn't defined, and neither are
- * the results of this function -- though we'll generally return true.
+ * the results of this function -- though we'll generally return false.
*
- * TODO: Make sure this does the right thing with attribute nodes!!!
- *
* @param nodeHandle1 Node handle to perform position comparison on.
* @param nodeHandle2 Second Node handle to perform position comparison on
.
*
- * @return false if node2 comes before node1, otherwise return true.
+ * @return true if node1 comes before node2, otherwise return false.
* You can think of this as
* <code>(node1.documentOrderPosition <=
node2.documentOrderPosition)</code>.
*/
public boolean isNodeAfter(int nodeHandle1, int nodeHandle2)
{
- if((nodeHandle1 & ~m_mask) != (nodeHandle2 & ~m_mask))
- return false;
-
- int index1 = nodeHandle1 & m_mask;
- int index2 = nodeHandle2 & m_mask;
+ // These return NULL if the node doesn't belong to this
document.
+ int index1 = makeNodeIdentity(nodeHandle1);
+ int index2 = makeNodeIdentity(nodeHandle2);
- return index1 <= index2;
+ return index1!=NULL & index2!=NULL & index1 <= index2;
}
/**
@@ -2033,4 +2085,26 @@
{
}
+ /** Query which DTMManager this DTM is currently being handled by.
+ *
+ * %REVEW% Should this become part of the base DTM API?
+ *
+ * @return a DTMManager, or null if this is a "stand-alone" DTM.
+ */
+ public DTMManager getManager()
+ {
+ return m_mgr;
+ }
+
+ /** Query which DTMIDs this DTM is currently using within the
DTMManager.
+ *
+ * %REVEW% Should this become part of the base DTM API?
+ *
+ * @return an IntVector, or null if this is a "stand-alone" DTM.
+ */
+ public SuballocatedIntVector getDTMIDs()
+ {
+ if(m_mgr==null) return null;
+ return m_dtmIdent;
+ }
}
1.9 +5 -5
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java
Index: DTMDefaultBaseIterators.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseIterators.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- DTMDefaultBaseIterators.java 2001/10/01 15:36:17 1.8
+++ DTMDefaultBaseIterators.java 2001/11/26 22:08:28 1.9
@@ -1183,7 +1183,7 @@
if (_isRestartable)
{
- node = node & m_mask;
+ node = makeNodeIdentity(node);
// iterator is not a clone
int parent, index;
@@ -1229,7 +1229,7 @@
if ((_sp >= 0) && (node < _stack[_sp]))
{
- return returnNode((_currentNode = node) | m_dtmIdent);
+ return returnNode(makeNodeHandle(_currentNode = node));
}
else
{
@@ -1615,7 +1615,7 @@
if (_isRestartable)
{
- node = node & m_mask;
+ node = makeNodeIdentity(node);
_startNode = node;
if (_includeSelf)
@@ -1667,7 +1667,7 @@
if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
continue;
- return returnNode(node | m_dtmIdent); // make handle.
+ return returnNode(makeNodeHandle(node)); // make handle.
}
}
} // end of DescendantIterator
@@ -1743,7 +1743,7 @@
while ((node = super.next()) != END)
{
- node = (node & m_mask);
+ node = makeNodeIdentity(node);
int parent = _parent(node);
int child = _firstch(parent);
1.7 +206 -194
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java
Index: DTMDefaultBaseTraversers.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMDefaultBaseTraversers.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DTMDefaultBaseTraversers.java 2001/10/01 15:36:17 1.6
+++ DTMDefaultBaseTraversers.java 2001/11/26 22:08:28 1.7
@@ -68,7 +68,12 @@
/**
* This class implements the traversers for DTMDefaultBase.
- */
+ *
+ * PLEASE NOTE that the public interface for all traversers should be
+ * in terms of DTM Node Handles... but they may use the internal node
+ * identity indices within their logic, for efficiency's sake. Be very
+ * careful to avoid confusing these when maintaining this code.
+ * */
public abstract class DTMDefaultBaseTraversers extends DTMDefaultBase
{
@@ -214,28 +219,28 @@
*/
public int next(int context, int current)
{
- return m_parent.elementAt(current & m_mask) | m_dtmIdent;
+ return getParent(current);
}
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
+ // Process using identities
+ current = makeNodeIdentity(current);
- current = current & m_mask;
-
while (DTM.NULL != (current = m_parent.elementAt(current)))
{
- if (m_exptype.elementAt(current) == extendedTypeID)
- return current | m_dtmIdent;
+ if (m_exptype.elementAt(current) == expandedTypeID)
+ return makeNodeHandle(current);
}
return NULL;
@@ -266,18 +271,18 @@
* By the nature of the stateless traversal, the context node can not be
* returned or the iteration will go into an infinate loop. To see if
* the self node should be processed, use this function. If the context
- * node does not match the extended type ID, this function will return
+ * node does not match the expanded type ID, this function will return
* false.
*
* @param context The context node of this traversal.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
- return (m_exptype.elementAt(context & m_mask) == extendedTypeID)
- ? context : next(context, context, extendedTypeID);
+ return (getExpandedTypeID(context) == expandedTypeID)
+ ? context : next(context, context, expandedTypeID);
}
}
@@ -303,15 +308,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
current = (context == current)
@@ -319,7 +324,7 @@
do
{
- if (m_exptype.elementAt(current) == extendedTypeID)
+ if (getExpandedTypeID(current) == expandedTypeID)
return current;
}
while (DTM.NULL != (current = getNextAttribute(current)));
@@ -335,39 +340,39 @@
{
/**
- * Get the next indexed node that matches the extended type ID. Before
+ * Get the next indexed node that matches the expanded type ID. Before
* calling this function, one should first call
* [EMAIL PROTECTED] #isIndexed(int) isIndexed} to make sure that the
index can
- * contain nodes that match the given extended type ID.
+ * contain nodes that match the given expanded type ID.
*
* @param axisRoot The root identity of the axis.
* @param nextPotential The node found must match or occur after this
node.
- * @param extendedTypeID The extended type ID for the request.
+ * @param expandedTypeID The expanded type ID for the request.
*
- * @return The node or NULL if not found.
+ * @return The node ID or NULL if not found.
*/
protected int getNextIndexed(int axisRoot, int nextPotential,
- int extendedTypeID)
+ int expandedTypeID)
{
- int nsIndex = m_expandedNameTable.getNamespaceID(extendedTypeID);
- int lnIndex = m_expandedNameTable.getLocalNameID(extendedTypeID);
+ int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
+ int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
for (; ; )
{
- int next = findElementFromIndex(nsIndex, lnIndex, nextPotential);
+ int nextID = findElementFromIndex(nsIndex, lnIndex, nextPotential);
- if (NOTPROCESSED != next)
+ if (NOTPROCESSED != nextID)
{
- int parent = m_parent.elementAt(next);
+ int parentID = m_parent.elementAt(nextID);
// Is it a child?
- if(parent == axisRoot)
- return next;
+ if(parentID == axisRoot)
+ return nextID;
// If the parent occured before the subtree root, then
// we know it is past the child axis.
- if(parent < axisRoot)
+ if(parentID < axisRoot)
return NULL;
// Otherwise, it could be a descendant below the subtree root
@@ -377,14 +382,14 @@
// root, in which case we continue to look.
do
{
- parent = m_parent.elementAt(parent);
- if(parent < axisRoot)
+ parentID = m_parent.elementAt(parentID);
+ if(parentID < axisRoot)
return NULL;
}
- while(parent > axisRoot);
+ while(parentID > axisRoot);
// System.out.println("Found node via index: "+first);
- nextPotential = next+1;
+ nextPotential = nextID+1;
continue;
}
@@ -411,7 +416,7 @@
*/
public int first(int context)
{
- return _firstch(context & m_mask) | m_dtmIdent;
+ return getFirstChild(context);
}
/**
@@ -424,29 +429,30 @@
*
* @param context The context node of this traversal. This is the point
* of origin for the traversal -- its "root node" or starting point.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
if(true)
{
- int identity = context & m_mask;
+ int identity = makeNodeIdentity(context);
int firstMatch = getNextIndexed(identity, _firstch(identity),
- extendedTypeID);
+ expandedTypeID);
- return firstMatch | m_dtmIdent;
+ return makeNodeHandle(firstMatch);
}
else
{
- for (int current = _firstch(context & m_mask);
+ // %REVIEW% Dead code. Eliminate?
+ for (int current = _firstch(makeNodeIdentity(context));
DTM.NULL != current;
current = _nextsib(current))
{
- if (m_exptype.elementAt(current) == extendedTypeID)
- return current | m_dtmIdent;
+ if (m_exptype.elementAt(current) == expandedTypeID)
+ return makeNodeHandle(current);
}
return NULL;
}
@@ -462,29 +468,28 @@
*/
public int next(int context, int current)
{
-
- return _nextsib(current & m_mask) | m_dtmIdent;
+ return getNextSibling(current);
}
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
-
- for (current = _nextsib(current & m_mask);
+ // Process in Identifier space
+ for (current = _nextsib(makeNodeIdentity(current));
DTM.NULL != current;
current = _nextsib(current))
{
- if (m_exptype.elementAt(current) == extendedTypeID)
- return current | m_dtmIdent;
+ if (m_exptype.elementAt(current) == expandedTypeID)
+ return makeNodeHandle(current);
}
return NULL;
@@ -499,21 +504,20 @@
{
/**
- * Tell if the indexing is on and the given extended type ID matches
+ * Tell if the indexing is on and the given expanded type ID matches
* what is in the indexes. Derived classes should call this before
* calling [EMAIL PROTECTED] #getNextIndexed(int, int, int)
getNextIndexed} method.
*
- * @param extendedTypeID The extended type ID being requested.
+ * @param expandedTypeID The expanded type ID being requested.
*
* @return true if it is OK to call the
* [EMAIL PROTECTED] #getNextIndexed(int, int, int)
getNextIndexed} method.
*/
- protected final boolean isIndexed(int extendedTypeID)
+ protected final boolean isIndexed(int expandedTypeID)
{
-
return (m_indexing
&& ExpandedNameTable.ELEMENT
- == (extendedTypeID & ExpandedNameTable.MASK_NODETYPE));
+ == (expandedTypeID & ExpandedNameTable.MASK_NODETYPE));
}
/**
@@ -540,23 +544,23 @@
protected abstract boolean axisHasBeenProcessed(int axisRoot);
/**
- * Get the next indexed node that matches the extended type ID. Before
+ * Get the next indexed node that matches the expanded type ID. Before
* calling this function, one should first call
* [EMAIL PROTECTED] #isIndexed(int) isIndexed} to make sure that the
index can
- * contain nodes that match the given extended type ID.
+ * contain nodes that match the given expanded type ID.
*
* @param axisRoot The root identity of the axis.
* @param nextPotential The node found must match or occur after this
node.
- * @param extendedTypeID The extended type ID for the request.
+ * @param expandedTypeID The expanded type ID for the request.
*
- * @return The node or NULL if not found.
+ * @return The node ID or NULL if not found.
*/
protected int getNextIndexed(int axisRoot, int nextPotential,
- int extendedTypeID)
+ int expandedTypeID)
{
- int nsIndex = m_expandedNameTable.getNamespaceID(extendedTypeID);
- int lnIndex = m_expandedNameTable.getLocalNameID(extendedTypeID);
+ int nsIndex = m_expandedNameTable.getNamespaceID(expandedTypeID);
+ int lnIndex = m_expandedNameTable.getLocalNameID(expandedTypeID);
while(true)
{
@@ -621,7 +625,7 @@
*/
protected int getSubtreeRoot(int handle)
{
- return handle & m_mask;
+ return makeNodeIdentity(handle);
}
/**
@@ -654,6 +658,8 @@
protected boolean isAfterAxis(int axisRoot, int identity)
{
// %REVIEW% Is there *any* cheaper way to do this?
+ // Yes. In ID space, compare to axisRoot's successor
+ // (next-sib or ancestor's-next-sib). Probably
shallower search.
do
{
if(identity == axisRoot)
@@ -675,22 +681,22 @@
*
* @param context The context node of this traversal. This is the point
* of origin for the traversal -- its "root node" or starting point.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
- if (isIndexed(extendedTypeID))
+ if (isIndexed(expandedTypeID))
{
int identity = getSubtreeRoot(context);
int firstPotential = getFirstPotential(identity);
- return getNextIndexed(identity, firstPotential,
extendedTypeID)|m_dtmIdent;
+ return makeNodeHandle(getNextIndexed(identity, firstPotential,
expandedTypeID));
}
- return next(context, context, extendedTypeID);
+ return next(context, context, expandedTypeID);
}
/**
@@ -706,7 +712,7 @@
int subtreeRootIdent = getSubtreeRoot(context);
- for (current = (current & m_mask) + 1; ; current++)
+ for (current = makeNodeIdentity(current) + 1; ; current++)
{
int type = _type(current); // may call nextNode()
@@ -716,30 +722,30 @@
if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
int subtreeRootIdent = getSubtreeRoot(context);
- current = (current & m_mask) + 1;
+ current = makeNodeIdentity(current) + 1;
- if (isIndexed(extendedTypeID))
+ if (isIndexed(expandedTypeID))
{
- return getNextIndexed(subtreeRootIdent, current,
extendedTypeID)|m_dtmIdent;
+ return makeNodeHandle(getNextIndexed(subtreeRootIdent, current,
expandedTypeID));
}
for (; ; current++)
@@ -749,10 +755,10 @@
if (!isDescendant(subtreeRootIdent, current))
return NULL;
- if (exptype != extendedTypeID)
+ if (exptype != expandedTypeID)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
}
@@ -808,22 +814,21 @@
public int next(int context, int current)
{
- int subtreeRootIdent = context & m_mask;
+ int subtreeRootIdent = makeNodeIdentity(context);
- for (current = (current & m_mask) + 1; ; current++)
+ for (current = makeNodeIdentity(current) + 1; ; current++)
{
-
// Trickological code: _exptype() has the side-effect of
// running nextNode until the specified node has been loaded,
// and thus can be used to ensure that incremental construction of
// the DTM has gotten this far. Using it just for that side-effect
- // is a bit of a kluge...
+ // is quite a kluge...
_exptype(current); // make sure it's here.
if (!isDescendant(subtreeRootIdent, current))
return NULL;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
}
@@ -843,29 +848,31 @@
*/
public int first(int context)
{
+ // Compute in ID space
+ context=makeNodeIdentity(context);
int first;
- int type = _type(context);
+ int type = _exptype(context);
if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
{
- context = getParent(context);
- first = getFirstChild(context);
+ context = _parent(context);
+ first = _firstch(context);
if (NULL != first)
- return first;
+ return makeNodeHandle(first);
}
do
{
- first = getNextSibling(context);
+ first = _nextsib(context);
if (NULL == first)
- context = getParent(context);
+ context = _parent(context);
}
while (NULL == first && NULL != context);
- return first;
+ return makeNodeHandle(first);
}
/**
@@ -873,15 +880,16 @@
*
* @param context The context node of this traversal. This is the point
* of origin for the traversal -- its "root node" or starting point.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
-
+ // %REVIEW% This looks like it might want shift into
identity space
+ // to avoid repeated conversion in the individual
functions
int first;
- int type = _type(context);
+ int type = getNodeType(context);
if ((DTM.ATTRIBUTE_NODE == type) || (DTM.NAMESPACE_NODE == type))
{
@@ -890,10 +898,10 @@
if (NULL != first)
{
- if (_exptype(first) == extendedTypeID)
+ if (getExpandedTypeID(first) == expandedTypeID)
return first;
else
- return next(context, first, extendedTypeID);
+ return next(context, first, expandedTypeID);
}
}
@@ -905,10 +913,10 @@
context = getParent(context);
else
{
- if (_exptype(first) == extendedTypeID)
+ if (getExpandedTypeID(first) == expandedTypeID)
return first;
else
- return next(context, first, extendedTypeID);
+ return next(context, first, expandedTypeID);
}
}
while (NULL == first && NULL != context);
@@ -926,11 +934,14 @@
*/
public int next(int context, int current)
{
+ // Compute in identity space
+ current=makeNodeIdentity(current);
while (true)
{
- current++;
+ current++; // Only works on IDs, not handles.
+ // %REVIEW% Are we using handles or indexes?
int type = _type(current); // may call nextNode()
if (NULL == type)
@@ -939,22 +950,24 @@
if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
+ // Compute in ID space
+ current=makeNodeIdentity(current);
while (true)
{
@@ -965,10 +978,10 @@
if (NULL == etype)
return NULL;
- if (etype != extendedTypeID)
+ if (etype != expandedTypeID)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
}
@@ -994,20 +1007,20 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
while (DTM.NULL != (current = getNextSibling(current)))
{
- if (m_exptype.elementAt(current & m_mask) == extendedTypeID)
+ if (getExpandedTypeID(current) == expandedTypeID)
return current;
}
@@ -1039,15 +1052,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
current = (context == current)
@@ -1056,7 +1069,7 @@
do
{
- if (m_exptype.elementAt(current) == extendedTypeID)
+ if (getExpandedTypeID(current) == expandedTypeID)
return current;
}
while (DTM.NULL
@@ -1090,15 +1103,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
current = (context == current)
@@ -1107,7 +1120,7 @@
do
{
- if (m_exptype.elementAt(current) == extendedTypeID)
+ if (getExpandedTypeID(current) == expandedTypeID)
return current;
}
while (DTM.NULL
@@ -1136,7 +1149,7 @@
*/
public int first(int context)
{
- return m_parent.elementAt(context & m_mask) | m_dtmIdent;
+ return getParent(context);
}
/**
@@ -1149,18 +1162,19 @@
*
* @param context The context node of this traversal. This is the point
* of origin for the traversal -- its "root node" or starting point.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int current, int extendedTypeID)
+ public int first(int current, int expandedTypeID)
{
- current = current & m_mask;
+ // Compute in ID space
+ current = makeNodeIdentity(current);
while (NULL != (current = m_parent.elementAt(current)))
{
- if (m_exptype.elementAt(current) == extendedTypeID)
- return (current | m_dtmIdent);
+ if (m_exptype.elementAt(current) == expandedTypeID)
+ return makeNodeHandle(current);
}
return NULL;
@@ -1185,15 +1199,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
return NULL;
@@ -1217,7 +1231,8 @@
*/
protected boolean isAncestor(int contextIdent, int currentIdent)
{
-
+ // %REVIEW% See comments in IsAfterAxis; using the
"successor" of
+ // contextIdent is probably more efficient.
for (contextIdent = m_parent.elementAt(contextIdent); DTM.NULL !=
contextIdent;
contextIdent = m_parent.elementAt(contextIdent))
{
@@ -1238,19 +1253,18 @@
*/
public int next(int context, int current)
{
+ // compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context);
- int subtreeRootIdent = context & m_mask;
-
- for (current = (current & m_mask) - 1; current >= 0; current--)
+ for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
{
- int exptype = m_exptype.elementAt(current);
- short type = ExpandedNameTable.getType(exptype);
+ short type = _type(current);
if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type
|| isAncestor(subtreeRootIdent, current))
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
return NULL;
@@ -1258,29 +1272,28 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
-
- int subtreeRootIdent = context & m_mask;
+ // Compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context);
- for (current = (current & m_mask) - 1; current >= 0; current--)
+ for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
{
int exptype = m_exptype.elementAt(current);
- short type = ExpandedNameTable.getType(exptype);
- if (exptype != extendedTypeID
+ if (exptype != expandedTypeID
|| isAncestor(subtreeRootIdent, current))
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
return NULL;
@@ -1304,18 +1317,17 @@
*/
public int next(int context, int current)
{
+ // Compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context );
- int subtreeRootIdent = context & m_mask;
-
- for (current = (current & m_mask) - 1; current >= 0; current--)
+ for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
{
- int exptype = m_exptype.elementAt(current);
- short type = ExpandedNameTable.getType(exptype);
+ short type = _type(current);
if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
return NULL;
@@ -1323,28 +1335,27 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
-
- int subtreeRootIdent = context & m_mask;
+ // Compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context);
- for (current = (current & m_mask) - 1; current >= 0; current--)
+ for (current = makeNodeIdentity(current) - 1; current >= 0; current--)
{
int exptype = m_exptype.elementAt(current);
- short type = ExpandedNameTable.getType(exptype);
- if (exptype != extendedTypeID)
+ if (exptype != expandedTypeID)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
return NULL;
@@ -1372,20 +1383,20 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
while (DTM.NULL != (current = getPreviousSibling(current)))
{
- if (m_exptype.elementAt(current & m_mask) == extendedTypeID)
+ if (getExpandedTypeID(current) == expandedTypeID)
return current;
}
@@ -1417,17 +1428,17 @@
* By the nature of the stateless traversal, the context node can not be
* returned or the iteration will go into an infinate loop. To see if
* the self node should be processed, use this function. If the context
- * node does not match the extended type ID, this function will return
+ * node does not match the expanded type ID, this function will return
* false.
*
* @param context The context node of this traversal.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
- return (m_exptype.elementAt(context & m_mask) == extendedTypeID) ?
context : NULL;
+ return (getExpandedTypeID(context) == expandedTypeID) ? context : NULL;
}
/**
@@ -1445,15 +1456,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
return NULL;
}
@@ -1478,17 +1489,17 @@
}
/**
- * Return the root if it matches the extended type ID.
+ * Return the root if it matches the expanded type ID.
*
* @param context The context node of this traversal.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the first node in the traversal.
*/
- public int first(int context, int extendedTypeID)
+ public int first(int context, int expandedTypeID)
{
- return (m_exptype.elementAt(getDocument() & m_mask) == extendedTypeID)
- ? context : next(context, context, extendedTypeID);
+ return (getExpandedTypeID(getDocument()) == expandedTypeID)
+ ? context : next(context, context, expandedTypeID);
}
/**
@@ -1501,46 +1512,46 @@
*/
public int next(int context, int current)
{
+ // Compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context);
- int subtreeRootIdent = context & m_mask;
-
- for (current = (current & m_mask) + 1; ; current++)
+ for (current = makeNodeIdentity(current) + 1; ; current++)
{
+ // Kluge test: Just make sure +1 yielded a real
node
int type = _type(current); // may call nextNode()
-
if (type == NULL)
return NULL;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
-
- int subtreeRootIdent = context & m_mask;
+ // Compute in ID space
+ int subtreeRootIdent = makeNodeIdentity(context);
- for (current = (current & m_mask) + 1; ; current++)
+ for (current = makeNodeIdentity(current) + 1; ; current++)
{
int exptype = _exptype(current); // may call nextNode()
if (exptype == NULL)
return NULL;
- if (exptype != extendedTypeID)
+ if (exptype != expandedTypeID)
continue;
- return (current | m_dtmIdent); // make handle.
+ return makeNodeHandle(current); // make handle.
}
}
}
@@ -1566,15 +1577,15 @@
/**
* Traverse to the next node after the current node that is matched
- * by the extended type ID.
+ * by the expanded type ID.
*
* @param context The context node of this iteration.
* @param current The current node of the iteration.
- * @param extendedTypeID The extended type ID that must match.
+ * @param expandedTypeID The expanded type ID that must match.
*
* @return the next node in the iteration, or DTM.NULL.
*/
- public int next(int context, int current, int extendedTypeID)
+ public int next(int context, int current, int expandedTypeID)
{
return NULL;
}
@@ -1607,7 +1618,8 @@
*/
protected int getSubtreeRoot(int handle)
{
- return getDocument() & m_mask;
+ // %REVIEW% Shouldn't this always be 0?
+ return makeNodeIdentity(getDocument());
}
/**
@@ -1662,7 +1674,7 @@
*/
public int first(int context)
{
- return _firstch(0) | m_dtmIdent;
+ return makeNodeHandle(_firstch(0));
}
}
1.30 +141 -37
xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java
Index: DTMManagerDefault.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/DTMManagerDefault.java,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- DTMManagerDefault.java 2001/11/05 20:30:46 1.29
+++ DTMManagerDefault.java 2001/11/26 22:08:28 1.30
@@ -103,19 +103,88 @@
{
/**
- * Vector of DTMs that this manager manages.
+ * Map from DTM identifier numbers to DTM objects that this manager
manages.
+ * One DTM may have several prefix numbers, if extended node indexing
+ * is in use; in that case, m_dtm_offsets[] will used to control which
+ * prefix maps to which section of the DTM.
+ *
+ * This array grows as necessary; see addDTM().
+ *
+ * %REVIEW% Could use a Fast...Vector approach. Growth is uncommon,
+ * so I'm not worrying about it.
*/
- protected DTM m_dtms[] = new DTM[IDENT_MAX_DTMS];
+ protected DTM m_dtms[] = new DTM[256];
+
+ /** Map from DTM identifier numbers to offsets. For small DTMs with a
+ * single identifier, this will always be 0. In extended addressing,
where
+ * additional identifiers are allocated to access nodes beyond the
range of
+ * a single Node Handle, this table is used to map the handle's node
field
+ * into the actual node identifier.
+ *
+ * This array grows as necessary; see addDTM().
+ *
+ * %REVIEW% Could use a FastIntVector approach. Growth is uncommon,
+ * so I'm not worrying about it.
+ */
+ protected int m_dtm_offsets[] = new int[256];
+
+ /**
+ * Add a DTM to the DTM table. This convenience call adds it as the
+ * "base DTM ID", with offset 0. The other version of addDTM should
+ * be used if you want to add "extended" DTM IDs with nonzero offsets.
+ *
+ * @param dtm Should be a valid reference to a DTM.
+ * @param id Integer DTM ID to be bound to this DTM
+ */
+ public void addDTM(DTM dtm, int id) { addDTM(dtm,id,0); }
+
/**
* Add a DTM to the DTM table.
*
* @param dtm Should be a valid reference to a DTM.
- */
- public void addDTM(DTM dtm, int id)
- {
+ * @param id Integer DTM ID to be bound to this DTM.
+ * @param offset Integer addressing offset. The internal DTM Node ID is
+ * obtained by adding this offset to the node-number field of the
+ * public DTM Handle. For the first DTM ID accessing each DTM, this is 0;
+ * for extended addressing it will be a multiple of 1<<IDENT_DTM_NODE_BITS.
+ */
+ public void addDTM(DTM dtm, int id, int offset)
+ {
+ if(id>=IDENT_MAX_DTMS)
+ {
+ // TODO: %REVIEW% Not really the right error message.
+ throw new
DTMException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null)); //"No more DTM IDs are available!");
+ }
+
+ // We used to just allocate the array size to IDENT_MAX_DTMS.
+ // But we expect to increase that to 16 bits, and I'm not
willing
+ // to allocate that much space unless needed. We could use one
of our
+ // handy-dandy Fast*Vectors, but this will do for now.
+ // %REVIEW%
+ int oldlen=m_dtms.length;
+ if(oldlen<=id)
+ {
+ // Various growth strategies are possible. I think we
don't want
+ // to over-allocate excessively, and I'm willing to
reallocate
+ // more often to get that. See also Fast*Vector classes.
+ //
+ // %REVIEW% Should throw a more diagnostic error if we
go over the max...
+ int newlen=Math.min((id+256),IDENT_MAX_DTMS);
+
+ DTM new_m_dtms[] = new DTM[newlen];
+ System.arraycopy(m_dtms,0,new_m_dtms,0,oldlen);
+ m_dtms=new_m_dtms;
+ int new_m_dtm_offsets[] = new int[newlen];
+
System.arraycopy(m_dtm_offsets,0,new_m_dtm_offsets,0,oldlen);
+ m_dtm_offsets=new_m_dtm_offsets;
+ }
+
m_dtms[id] = dtm;
+ m_dtm_offsets[id]=offset;
dtm.documentRegistration();
+ // The DTM should have been told who its manager was when we
created it.
+ // Do we need to allow for adopting DTMs _not_ created by this
manager?
}
/**
@@ -131,7 +200,7 @@
return i;
}
}
- throw new
DTMException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null)); //"No more DTM IDs are available!");
+ return n; // count on addDTM() to throw exception if out of
range
}
/**
@@ -193,7 +262,7 @@
DOM2DTM dtm = new DOM2DTM(this, (DOMSource) source, documentID,
whiteSpaceFilter, xstringFactory,
doIndexing);
- addDTM(dtm, dtmPos);
+ addDTM(dtm, dtmPos, 0);
// if (DUMPTREE)
// {
@@ -249,7 +318,7 @@
// Go ahead and add the DTM to the lookup table. This needs to be
// done before any parsing occurs.
- addDTM(dtm, dtmPos);
+ addDTM(dtm, dtmPos, 0);
boolean haveXercesParser =
(null != reader)
@@ -422,8 +491,14 @@
// subtree, but that's going to entail additional work
// checking more DTMs... and getHandleFromNode is not a
// cheap operation in most implementations.
- // [I had to change this to look forward... sorry. -sb]
- int max = m_dtms.length;
+ //
+ // TODO: %REVIEW% If extended addressing, we may
recheck a DTM
+ // already examined. Ouch. But with the increased
number of DTMs,
+ // scanning back to check this is painful.
+ // POSSIBLE SOLUTIONS:
+ // Generate a list of _unique_ DTM objects?
+ // Have each DTM cache last DOM node search?
+ int max = m_dtms.length;
for(int i = 0; i < max; i++)
{
DTM thisDTM=m_dtms[i];
@@ -545,12 +620,11 @@
}
/**
- * NEEDSDOC Method getDTM
+ * Return the DTM object containing a representation of this node.
*
+ * @param nodeHandle DTM Handle indicating which node to retrieve
*
- * NEEDSDOC @param nodeHandle
- *
- * NEEDSDOC (getDTM) @return
+ * @return a reference to the DTM object containing this node.
*/
public DTM getDTM(int nodeHandle)
{
@@ -562,32 +636,41 @@
catch(java.lang.ArrayIndexOutOfBoundsException e)
{
if(nodeHandle==DTM.NULL)
- return null; // Accept as a special case.
+ return null; // Accept as a special
case.
else
- throw e; // Programming error; want to know about it.
+ throw e; // Programming error;
want to know about it.
}
}
/**
- * Given a DTM, find it's ID number in the DTM list.
- *
+ * Given a DTM, find the ID number in the DTM tables which addresses
+ * the start of the document. If extended addressing is in use, other
+ * DTM IDs may also be assigned to this DTM.
*
- * @param dtm The DTM reference in question.
+ * @param dtm The DTM which (hopefully) contains this node.
*
- * @return The ID, or -1 if not found in the list.
+ * @return The ID, or -1 if the DTM doesn't belong to this manager.
*/
public int getDTMIdentity(DTM dtm)
{
-
- // A backwards search should normally be the fastest.
- // [But we can't do it... sorry. -sb]
+ // Shortcut using DTMDefaultBase's extension hooks
+ // %REVIEW% Should the lookup be part of the basic DTM API?
+ if(dtm instanceof DTMDefaultBase)
+ {
+ DTMDefaultBase dtmdb=(DTMDefaultBase)dtm;
+ if(dtmdb.getManager()==this)
+ return dtmdb.getDTMIDs().elementAt(0);
+ else
+ return -1;
+ }
+
int n = m_dtms.length;
for (int i = 0; i < n; i++)
{
DTM tdtm = m_dtms[i];
- if (tdtm == dtm)
+ if (tdtm == dtm && m_dtm_offsets[i]==0)
return i;
}
@@ -595,13 +678,19 @@
}
/**
- * NEEDSDOC Method release
- *
- *
- * NEEDSDOC @param dtm
- * NEEDSDOC @param shouldHardDelete
+ * Release the DTMManager's reference(s) to a DTM, making it unmanaged.
+ * This is typically done as part of returning the DTM to the heap after
+ * we're done with it.
+ *
+ * @param dtm the DTM to be released.
+ *
+ * @param shouldHardDelete If false, this call is a suggestion rather than
an
+ * order, and we may not actually release the DTM. This is intended to
+ * support intelligent caching of documents... which is not implemented
+ * in this version of the DTM manager.
*
- * NEEDSDOC (release) @return
+ * @return true if the DTM was released, false if shouldHardDelete was set
+ * and we decided not to.
*/
public boolean release(DTM dtm, boolean shouldHardDelete)
{
@@ -621,13 +710,29 @@
((SAX2DTM) dtm).clearCoRoutine();
}
- int i = getDTMIdentity(dtm);
+ // Multiple DTM IDs maybe assigned to a single DTM.
+ // The Right Answer is to ask which (if it supports
+ // extension, the DTM will need a list anyway). The
+ // Wrong Answer, applied if the DTM can't help us,
+ // is to linearly search them all; this may be very
+ // painful.
+ //
+ // %REVIEW% Should the lookup move up into the basic DTM API?
+ if(dtm instanceof DTMDefaultBase)
+ {
+ org.apache.xml.utils.SuballocatedIntVector
ids=((DTMDefaultBase)dtm).getDTMIDs();
+ for(int i=ids.size()-1;i>=0;--i)
+
m_dtms[ids.elementAt(i)>>DTMManager.IDENT_DTM_NODE_BITS]=null;
+ }
+ else
+ {
+ int i = getDTMIdentity(dtm);
+ if (i >= 0)
+ {
+ m_dtms[i] = null;
+ }
+ }
- if (i >= 0)
- {
- m_dtms[i] = null;
- }
-
dtm.documentRelease();
return true;
}
@@ -736,5 +841,4 @@
{
return m_expandedNameTable;
}
-
}
1.23 +26 -11
xml-xalan/java/src/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java
Index: DOM2DTM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/dom2dtm/DOM2DTM.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- DOM2DTM.java 2001/11/26 18:51:48 1.22
+++ DOM2DTM.java 2001/11/26 22:08:28 1.23
@@ -213,13 +213,28 @@
int previousSibling, int forceNodeType)
{
int nodeIndex = m_nodes.size();
- // Report DTM overflow
- if(nodeIndex>DTMManager.IDENT_NODE_DEFAULT)
+
+ // Have we overflowed a DTM Identity's addressing range?
+ if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
{
- // %REVIEW% Wrong error message, but I've been told we're trying
- // not to add messages right not for I18N reasons.
- // %REVIEW% Should this be a Fatal Error?
- error(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null));//"No more DTM IDs are available";
+ try
+ {
+ if(m_mgr==null)
+ throw new ClassCastException();
+
+ // Handle as Extended Addressing
+ DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr;
+ int id=mgrD.getFirstFreeDTMID();
+ mgrD.addDTM(this,id,nodeIndex);
+ m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS);
+ }
+ catch(ClassCastException e)
+ {
+ // %REVIEW% Wrong error message, but I've been told we're trying
+ // not to add messages right not for I18N reasons.
+ // %REVIEW% Should this be a Fatal Error?
+
error(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null));//"No more DTM IDs are available";
+ }
}
m_size++;
@@ -378,7 +393,7 @@
if(null != m_wsfilter)
{
short wsv =
-
m_wsfilter.getShouldStripSpace(m_last_parent|m_dtmIdent,this);
+
m_wsfilter.getShouldStripSpace(makeNodeHandle(m_last_parent),this);
boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
? getShouldStripWhitespace()
: (DTMWSFilter.STRIP == wsv);
@@ -616,7 +631,7 @@
public Node getNode(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
return (Node) m_nodes.elementAt(identity);
}
@@ -685,7 +700,7 @@
for (; i < len; i++)
{
if (m_nodes.elementAt(i) == node)
- return i | m_dtmIdent;
+ return makeNodeHandle(i);
}
isMore = nextNode();
@@ -774,7 +789,7 @@
{
// Assume that attributes immediately follow the element.
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
while (DTM.NULL != (identity = getNextNodeIdentity(identity)))
{
@@ -792,7 +807,7 @@
String nodelocalname = node.getLocalName();
if (nodeuri.equals(namespaceURI) && name.equals(nodelocalname))
- return identity | m_dtmIdent;
+ return makeNodeHandle(identity);
}
else if (DTM.NAMESPACE_NODE != type)
{
1.20 +35 -20
xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java
Index: SAX2DTM.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xml/dtm/ref/sax2dtm/SAX2DTM.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- SAX2DTM.java 2001/11/08 19:14:53 1.19
+++ SAX2DTM.java 2001/11/26 22:08:28 1.20
@@ -440,7 +440,7 @@
throws SAXException
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int type = _type(identity);
if (isTextType(type))
@@ -468,7 +468,7 @@
while (DTM.NULL != identity && (_level(identity) > level))
{
- type = getNodeType(identity);
+ type = _type(identity);
if (isTextType(type))
{
@@ -555,7 +555,7 @@
}
else
{
- int qnameIndex = m_dataOrQName.elementAt(nodeHandle & m_mask);
+ int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
if (qnameIndex < 0)
{
@@ -593,7 +593,7 @@
}
else
{
- int qnameIndex = m_dataOrQName.elementAt(nodeHandle & m_mask);
+ int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle));
if (qnameIndex < 0)
{
@@ -812,14 +812,29 @@
// Common to all nodes:
int nodeIndex = m_size++;
- // Report DTM overflow
- if(nodeIndex>DTMManager.IDENT_NODE_DEFAULT)
+ // Have we overflowed a DTM Identity's addressing range?
+ if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS))
{
- // %REVIEW% Wrong error message, but I've been told we're trying
- // not to add messages right not for I18N reasons.
- // %REVIEW% Should this be a Fatal Error?
- error(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null));//"No more DTM IDs are available";
+ try
+ {
+ if(m_mgr==null)
+ throw new ClassCastException();
+
+ // Handle as Extended Addressing
+ DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr;
+ int id=mgrD.getFirstFreeDTMID();
+ mgrD.addDTM(this,id,nodeIndex);
+ m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS);
+ }
+ catch(ClassCastException e)
+ {
+ // %REVIEW% Wrong error message, but I've been told we're trying
+ // not to add messages right not for I18N reasons.
+ // %REVIEW% Should this be a Fatal Error?
+
error(XSLMessages.createMessage(XSLTErrorResources.ER_NO_DTMIDS_AVAIL,
null));//"No more DTM IDs are available";
+ }
}
+
m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL);
m_nextsib.addElement(NOTPROCESSED);
m_prevsib.addElement(previousSibling);
@@ -863,8 +878,8 @@
public String getNodeValue(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
- int type = getNodeType(identity);
+ int identity = makeNodeIdentity(nodeHandle);
+ int type = _type(identity);
if (isTextType(type))
{
@@ -904,7 +919,7 @@
*/
public String getLocalName(int nodeHandle)
{
- return m_expandedNameTable.getLocalName(_exptype(nodeHandle & m_mask));
+ return
m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle)));
}
/**
@@ -1002,7 +1017,7 @@
public String getPrefix(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
+ int identity = makeNodeIdentity(nodeHandle);
int type = getNodeType(identity);
if (DTM.ELEMENT_NODE == type)
@@ -1100,7 +1115,7 @@
public String getNamespaceURI(int nodeHandle)
{
- return m_expandedNameTable.getNamespace(_exptype(nodeHandle & m_mask));
+ return
m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle)));
}
/**
@@ -1115,8 +1130,8 @@
public XMLString getStringValue(int nodeHandle)
{
- int identity = nodeHandle & m_mask;
- int type = getNodeType(identity);
+ int identity = makeNodeIdentity(nodeHandle);
+ int type = _type(identity);
if (isTextType(type))
{
@@ -1140,7 +1155,7 @@
while (DTM.NULL != identity && (_level(identity) > level))
{
- type = getNodeType(identity);
+ type = _type(identity);
if (isTextType(type))
{
@@ -1206,7 +1221,7 @@
intObj = (Integer) m_idAttributes.get(elementId);
if (null != intObj)
- return intObj.intValue() | m_dtmIdent;
+ return makeNodeHandle(intObj.intValue());
if (!isMore || m_endDocumentOccured)
break;
@@ -1743,7 +1758,7 @@
if (null != m_wsfilter)
{
- short wsv = m_wsfilter.getShouldStripSpace(elemNode | m_dtmIdent,
this);
+ short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode),
this);
boolean shouldStrip = (DTMWSFilter.INHERIT == wsv)
? getShouldStripWhitespace()
: (DTMWSFilter.STRIP == wsv);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]