FileDocCategorySizeDatePackage
UnionIterator.javaAPI DocJava SE 5 API6288Fri Aug 26 14:55:40 BST 2005com.sun.org.apache.xalan.internal.xsltc.dom

UnionIterator

public final class UnionIterator extends DTMAxisIteratorBase
UnionIterator takes a set of NodeIterators and produces a merged NodeSet in document order with duplicates removed The individual iterators are supposed to generate nodes in document order
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen

Fields Summary
private final DOM
_dom
wrapper for NodeIterators to support iterator comparison on the value of their next() method
private static final int
InitSize
private int
_heapSize
private int
_size
private LookAheadIterator[]
_heap
private int
_free
private int
_returnedLast
private int
_cachedReturnedLast
private int
_cachedHeapSize
Constructors Summary
public UnionIterator(DOM dom)


       
	_dom = dom;
    
Methods Summary
public com.sun.org.apache.xalan.internal.xsltc.dom.UnionIteratoraddIterator(com.sun.org.apache.xml.internal.dtm.DTMAxisIterator iterator)

	if (_free == _size) {
	    LookAheadIterator[] newArray = new LookAheadIterator[_size *= 2];
	    System.arraycopy(_heap, 0, newArray, 0, _free);
	    _heap = newArray;
	}
	_heapSize++;
	_heap[_free++] = new LookAheadIterator(iterator);
	return this;
    
public com.sun.org.apache.xml.internal.dtm.DTMAxisIteratorcloneIterator()

	_isRestartable = false;
	final LookAheadIterator[] heapCopy = 
	    new LookAheadIterator[_heap.length];
	try {
	    final UnionIterator clone = (UnionIterator)super.clone();
            for (int i = 0; i < _free; i++) {
                heapCopy[i] = _heap[i].cloneIterator();
            }
	    clone.setRestartable(false);
	    clone._heap = heapCopy;
	    return clone.reset();
	} 
	catch (CloneNotSupportedException e) {
	    BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
				      e.toString());
	    return null;
	}
    
public voidgotoMark()

	for (int i = 0; i < _free; i++) {
	    _heap[i].gotoMark();
	}
	// rebuild heap after call last() function. fix for bug 20913
	for (int i = (_heapSize = _cachedHeapSize)/2; i >= 0; i--) {
	    heapify(i);
	}
    _returnedLast = _cachedReturnedLast;    
    
private voidheapify(int i)

	for (int r, l, smallest;;) {
	    r = (i + 1) << 1; l = r - 1;
	    smallest = l < _heapSize 
		&& _dom.lessThan(_heap[l].node, _heap[i].node) ? l : i;
	    if (r < _heapSize && _dom.lessThan(_heap[r].node,
					       _heap[smallest].node)) {
		smallest = r;
	    }
	    if (smallest != i) {
		final LookAheadIterator temp = _heap[smallest];
		_heap[smallest] = _heap[i];
		_heap[i] = temp;
		i = smallest;
	    }
	    else
		break;
	}
    
public intnext()

	while (_heapSize > 0) {
	    final int smallest = _heap[0].node;
	    if (smallest == END) { // iterator _heap[0] is done
		if (_heapSize > 1) {
		    // Swap first and last (iterator must be restartable)
		    final LookAheadIterator temp = _heap[0];
		    _heap[0] = _heap[--_heapSize];
		    _heap[_heapSize] = temp;
		}
		else {
		    return END;
		}
	    }
	    else if (smallest == _returnedLast) {	// duplicate
		_heap[0].step(); // value consumed
	    }
	    else {
		_heap[0].step(); // value consumed
		heapify(0);
		return returnNode(_returnedLast = smallest);
	    }
	    // fallthrough if not returned above
	    heapify(0);
	}
	return END;
    
public com.sun.org.apache.xml.internal.dtm.DTMAxisIteratorreset()

	for (int i = 0; i < _free; i++) {
	    _heap[i].iterator.reset();
	    _heap[i].step();
	}
	// build heap
	for (int i = (_heapSize = _free)/2; i >= 0; i--) {
	    heapify(i);
	}
	_returnedLast = END;
	return resetPosition();
    
public voidsetMark()

	for (int i = 0; i < _free; i++) {
	    _heap[i].setMark();
	}
	_cachedReturnedLast = _returnedLast;    
	_cachedHeapSize = _heapSize;
    
public com.sun.org.apache.xml.internal.dtm.DTMAxisIteratorsetStartNode(int node)

	if (_isRestartable) {
	    _startNode = node;
	    for (int i = 0; i < _free; i++) {
         	if(!_heap[i].isStartSet){
        	   _heap[i].iterator.setStartNode(node);
        	   _heap[i].step();	// to get the first node
        	   _heap[i].isStartSet = true;
        	}
	    }
	    // build heap
	    for (int i = (_heapSize = _free)/2; i >= 0; i--) {
		heapify(i);
	    }
	    _returnedLast = END;
	    return resetPosition();
	}
	return this;