1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.dom; 21 22 import com.sun.org.apache.xalan.internal.xsltc.DOM; 23 import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary; 24 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 25 import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase; 26 27 44 public abstract class MultiValuedNodeHeapIterator extends DTMAxisIteratorBase { 45 48 49 53 public abstract class HeapNode implements Cloneable { 54 protected int _node, _markedNode; 55 protected boolean _isStartSet = false; 56 57 62 public abstract int step(); 63 64 65 71 public HeapNode cloneHeapNode() { 72 HeapNode clone; 73 74 try { 75 clone = (HeapNode) super.clone(); 76 } catch (CloneNotSupportedException e) { 77 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 78 e.toString()); 79 return null; 80 } 81 82 clone._node = _node; 83 clone._markedNode = _node; 84 85 return clone; 86 } 87 88 91 public void setMark() { 92 _markedNode = _node; 93 } 94 95 98 public void gotoMark() { 99 _node = _markedNode; 100 } 101 102 110 public abstract boolean isLessThan(HeapNode heapNode); 111 112 119 public abstract HeapNode setStartNode(int node); 120 121 127 public abstract HeapNode reset(); 128 } 130 private static final int InitSize = 8; 131 132 private int _heapSize = 0; 133 private int _size = InitSize; 134 private HeapNode[] _heap = new HeapNode[InitSize]; 135 private int _free = 0; 136 137 private int _returnedLast; 140 141 private int _cachedReturnedLast = END; 143 144 private int _cachedHeapSize; 146 147 148 public DTMAxisIterator cloneIterator() { 149 _isRestartable = false; 150 final HeapNode[] heapCopy = new HeapNode[_heap.length]; 151 try { 152 MultiValuedNodeHeapIterator clone = 153 (MultiValuedNodeHeapIterator)super.clone(); 154 155 for (int i = 0; i < _free; i++) { 156 heapCopy[i] = _heap[i].cloneHeapNode(); 157 } 158 clone.setRestartable(false); 159 clone._heap = heapCopy; 160 return clone.reset(); 161 } 162 catch (CloneNotSupportedException e) { 163 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 164 e.toString()); 165 return null; 166 } 167 } 168 169 protected void addHeapNode(HeapNode node) { 170 if (_free == _size) { 171 HeapNode[] newArray = new HeapNode[_size *= 2]; 172 System.arraycopy(_heap, 0, newArray, 0, _free); 173 _heap = newArray; 174 } 175 _heapSize++; 176 _heap[_free++] = node; 177 } 178 179 public int next() { 180 while (_heapSize > 0) { 181 final int smallest = _heap[0]._node; 182 if (smallest == END) { if (_heapSize > 1) { 184 final HeapNode temp = _heap[0]; 186 _heap[0] = _heap[--_heapSize]; 187 _heap[_heapSize] = temp; 188 } 189 else { 190 return END; 191 } 192 } 193 else if (smallest == _returnedLast) { _heap[0].step(); } 196 else { 197 _heap[0].step(); heapify(0); 199 return returnNode(_returnedLast = smallest); 200 } 201 heapify(0); 203 } 204 return END; 205 } 206 207 public DTMAxisIterator setStartNode(int node) { 208 if (_isRestartable) { 209 _startNode = node; 210 for (int i = 0; i < _free; i++) { 211 if(!_heap[i]._isStartSet){ 212 _heap[i].setStartNode(node); 213 _heap[i].step(); _heap[i]._isStartSet = true; 215 } 216 } 217 for (int i = (_heapSize = _free)/2; i >= 0; i--) { 219 heapify(i); 220 } 221 _returnedLast = END; 222 return resetPosition(); 223 } 224 return this; 225 } 226 227 protected void init() { 228 for (int i =0; i < _free; i++) { 229 _heap[i] = null; 230 } 231 232 _heapSize = 0; 233 _free = 0; 234 } 235 236 239 private void heapify(int i) { 240 for (int r, l, smallest;;) { 241 r = (i + 1) << 1; l = r - 1; 242 smallest = l < _heapSize 243 && _heap[l].isLessThan(_heap[i]) ? l : i; 244 if (r < _heapSize && _heap[r].isLessThan(_heap[smallest])) { 245 smallest = r; 246 } 247 if (smallest != i) { 248 final HeapNode temp = _heap[smallest]; 249 _heap[smallest] = _heap[i]; 250 _heap[i] = temp; 251 i = smallest; 252 } else { 253 break; 254 } 255 } 256 } 257 258 public void setMark() { 259 for (int i = 0; i < _free; i++) { 260 _heap[i].setMark(); 261 } 262 _cachedReturnedLast = _returnedLast; 263 _cachedHeapSize = _heapSize; 264 } 265 266 public void gotoMark() { 267 for (int i = 0; i < _free; i++) { 268 _heap[i].gotoMark(); 269 } 270 for (int i = (_heapSize = _cachedHeapSize)/2; i >= 0; i--) { 272 heapify(i); 273 } 274 _returnedLast = _cachedReturnedLast; 275 } 276 277 public DTMAxisIterator reset() { 278 for (int i = 0; i < _free; i++) { 279 _heap[i].reset(); 280 _heap[i].step(); 281 } 282 283 for (int i = (_heapSize = _free)/2; i >= 0; i--) { 285 heapify(i); 286 } 287 288 _returnedLast = END; 289 return resetPosition(); 290 } 291 292 } 293 | Popular Tags |