FileDocCategorySizeDatePackage
MultiValuedNodeHeapIterator.javaAPI DocJava SE 6 API8535Tue Jun 10 00:22:32 BST 2008com.sun.org.apache.xalan.internal.xsltc.dom

MultiValuedNodeHeapIterator

public abstract class MultiValuedNodeHeapIterator extends DTMAxisIteratorBase

MultiValuedNodeHeapIterator takes a set of multi-valued heap nodes and produces a merged NodeSet in document order with duplicates removed.

Each multi-valued heap node (which might be a {@link org.apache.xml.dtm.DTMAxisIterator}, but that's not necessary) generates DTM node handles in document order. The class maintains the multi-valued heap nodes in a heap, not surprisingly, sorted by the next DTM node handle available form the heap node.

After a DTM node is pulled from the heap node that's at the top of the heap, the heap node is advanced to the next DTM node handle it makes available, and the heap nature of the heap is restored to ensure the next DTM node handle pulled is next in document order overall.

author
Jacek Ambroziak
author
Santiago Pericas-Geertsen

Fields Summary
private static final int
InitSize
private int
_heapSize
private int
_size
private HeapNode[]
_heap
private int
_free
private int
_returnedLast
private int
_cachedReturnedLast
private int
_cachedHeapSize
Constructors Summary
Methods Summary
protected voidaddHeapNode(com.sun.org.apache.xalan.internal.xsltc.dom.MultiValuedNodeHeapIterator$HeapNode node)

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



       
	_isRestartable = false;
	final HeapNode[] heapCopy = new HeapNode[_heap.length];
	try {
	    MultiValuedNodeHeapIterator clone =
                    (MultiValuedNodeHeapIterator)super.clone();

            for (int i = 0; i < _free; i++) {
                heapCopy[i] = _heap[i].cloneHeapNode();
            }
	    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 
		&& _heap[l].isLessThan(_heap[i]) ? l : i;
	    if (r < _heapSize && _heap[r].isLessThan(_heap[smallest])) {
		smallest = r;
	    }
	    if (smallest != i) {
		final HeapNode temp = _heap[smallest];
		_heap[smallest] = _heap[i];
		_heap[i] = temp;
		i = smallest;
	    } else {
		break;
            }
	}
    
protected voidinit()

        for (int i =0; i < _free; i++) {
            _heap[i] = null;
        }

        _heapSize = 0;
        _free = 0;
    
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 HeapNode 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].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].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;