/** * Insert rows while we keep getting duplicates from the merge run whose scan is in the open scan * array entry indexed by scanindex. */ void mergeARow(int scanindex) throws StandardException { if (SanityManager.DEBUG) { // Unless there's a bug, the scan index will refer // to an open scan. That's because we never put // a scan index for a closed scan into the sort // buffer (via setNextAux). SanityManager.ASSERT(openScans[scanindex] != null); } DataValueDescriptor[] row; // Read rows from the merge run and stuff them into the // sort buffer for as long as we encounter duplicates. do { row = sortObserver.getArrayClone(); // Fetch the row from the merge run. if (!openScans[scanindex].fetchNext(row)) { // If we're out of rows in the merge run, close the scan. openScans[scanindex].close(); openScans[scanindex] = null; return; } // Save the index of this merge run with // the row we're putting in the sort buffer. sortBuffer.setNextAux(scanindex); } while (sortBuffer.insert(row) == SortBuffer.INSERT_DUPLICATE); }
/** Initialize the scan, returning false if there was some error. */ public boolean init(TransactionManager tran) throws StandardException { if (SanityManager.DEBUG) { // We really expect to have at least one // merge run. SanityManager.ASSERT(mergeRuns != null); SanityManager.ASSERT(mergeRuns.size() > 0); // This sort scan also expects that the // caller has ensured that the sort buffer // capacity will hold a row from all the // merge runs. SanityManager.ASSERT(sortBuffer.capacity() >= mergeRuns.size()); } // Clear the sort buffer. sortBuffer.reset(); // Create an array to hold a scan controller // for each merge run. openScans = new StreamContainerHandle[mergeRuns.size()]; if (openScans == null) return false; // Open a scan on each merge run. int scanindex = 0; Enumeration e = mergeRuns.elements(); while (e.hasMoreElements()) { // get the container id long id = ((Long) e.nextElement()).longValue(); Transaction rawTran = tran.getRawStoreXact(); // get raw transaction int segmentId = StreamContainerHandle.TEMPORARY_SEGMENT; openScans[scanindex++] = rawTran.openStreamContainer(segmentId, id, hold); } // Load the initial rows. for (scanindex = 0; scanindex < openScans.length; scanindex++) mergeARow(scanindex); // Success! return true; }
/** * Move to the next position in the scan. * * @see org.apache.derby.iapi.store.access.ScanController#next */ public boolean next() throws StandardException { current = sortBuffer.removeFirst(); if (current != null) mergeARow(sortBuffer.getLastAux()); return (current != null); }