001: package net.sf.saxon.sort;
002:
003: import net.sf.saxon.expr.LastPositionFinder;
004: import net.sf.saxon.expr.XPathContext;
005: import net.sf.saxon.expr.XPathContextMajor;
006: import net.sf.saxon.om.Item;
007: import net.sf.saxon.om.SequenceIterator;
008: import net.sf.saxon.trace.InstructionInfoProvider;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.value.AtomicValue;
011:
012: /**
013: * A SortedGroupIterator is a modified SortedIterator. It sorts a sequence of groups,
014: * and is itself a GroupIterator. The modifications retain extra information about
015: * the items being sorted. The items are each the leading item of a group, and as well
016: * as the item itself, the iterator preserves information about the group: specifically,
017: * an iterator over the items in the group, and the value of the grouping key (if any).
018: */
019:
020: public class SortedGroupIterator extends SortedIterator implements
021: GroupIterator {
022:
023: private InstructionInfoProvider origin;
024:
025: public SortedGroupIterator(XPathContext context,
026: GroupIterator base, FixedSortKeyDefinition[] sortKeys,
027: InstructionInfoProvider origin) throws XPathException {
028: super (context, base, sortKeys);
029: this .origin = origin;
030: // add two items to each tuple, for the iterator over the items in the group,
031: // and the grouping key, respectively.
032: recordSize += 2;
033: }
034:
035: /**
036: * Override the method that builds the array of values and sort keys.
037: * @throws XPathException
038: */
039:
040: protected void buildArray() throws XPathException {
041: int allocated;
042: if ((base.getProperties() & SequenceIterator.LAST_POSITION_FINDER) != 0) {
043: allocated = ((LastPositionFinder) base).getLastPosition();
044: } else {
045: allocated = 100;
046: }
047:
048: nodeKeys = new Object[allocated * recordSize];
049: count = 0;
050:
051: XPathContextMajor c2 = context.newContext();
052: c2.setCurrentIterator(base);
053: c2.setOrigin(origin);
054: c2.setCurrentGroupIterator((GroupIterator) base);
055: // this provides the context for evaluating the sort key
056:
057: // initialise the array with data
058:
059: while (true) {
060: Item item = base.next();
061: if (item == null) {
062: break;
063: }
064: if (count == allocated) {
065: allocated *= 2;
066: Object[] nk2 = new Object[allocated * recordSize];
067: System.arraycopy(nodeKeys, 0, nk2, 0, count
068: * recordSize);
069: nodeKeys = nk2;
070: }
071: int k = count * recordSize;
072: nodeKeys[k] = item;
073: for (int n = 0; n < sortkeys.length; n++) {
074: nodeKeys[k + n + 1] = sortkeys[n].getSortKey()
075: .evaluateItem(c2);
076: }
077: nodeKeys[k + sortkeys.length + 1] = new Integer(count);
078: // extra code added to superclass
079: nodeKeys[k + sortkeys.length + 2] = ((GroupIterator) base)
080: .getCurrentGroupingKey();
081: nodeKeys[k + sortkeys.length + 3] = ((GroupIterator) base)
082: .iterateCurrentGroup();
083: count++;
084: }
085: }
086:
087: public AtomicValue getCurrentGroupingKey() {
088: return (AtomicValue) nodeKeys[(index - 1) * recordSize
089: + sortkeys.length + 2];
090: }
091:
092: public SequenceIterator iterateCurrentGroup() throws XPathException {
093: SequenceIterator iter = (SequenceIterator) nodeKeys[(index - 1)
094: * recordSize + sortkeys.length + 3];
095: return iter.getAnother();
096: }
097: }
098:
099: //
100: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
101: // you may not use this file except in compliance with the License. You may obtain a copy of the
102: // License at http://www.mozilla.org/MPL/
103: //
104: // Software distributed under the License is distributed on an "AS IS" basis,
105: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
106: // See the License for the specific language governing rights and limitations under the License.
107: //
108: // The Original Code is: all this file.
109: //
110: // The Initial Developer of the Original Code is Michael H. Kay
111: //
112: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
113: //
114: // Contributor(s): none
115: //
|