📄 largeselect.java
字号:
log.debug("getResults(): Paging past end of loaded data as " + "start+size-1 (" + (start + size - 1) + ") > blockEnd (" + blockEnd + ")"); } stopQuery(); blockBegin = start; blockEnd = blockBegin + memoryLimit - 1; startQuery(size); // Re-invoke getResults() to provide the wait processing. return getResults(start, size); } else { throw new IllegalArgumentException("Parameter configuration not " + "accounted for."); } int fromIndex = start - blockBegin; int toIndex = fromIndex + Math.min(size, results.size() - fromIndex); if (log.isDebugEnabled()) { log.debug("getResults(): Retrieving records from results elements " + "start-blockBegin (" + fromIndex + ") through " + "fromIndex + Math.min(size, results.size() - fromIndex) (" + toIndex + ")"); } List returnResults = results.subList(fromIndex, toIndex); if (null != returnBuilderClass) { // Invoke the populateObjects() method Object[] theArgs = { returnResults }; try { returnResults = (List) populateObjectsMethod.invoke( returnBuilderClass.newInstance(), theArgs); } catch (Exception e) { throw new TorqueException("Unable to populate results", e); } } position = start + size; lastResults = returnResults; return returnResults; } /** * A background thread that retrieves the rows. */ public void run() { int size = pageSize; /* The connection to the database. */ Connection conn = null; try { // Add 1 to memory limit to check if the query ends on a page break. results = new ArrayList(memoryLimit + 1); // Use the criteria to limit the rows that are retrieved to the // block of records that fit in the predefined memoryLimit. criteria.setOffset(blockBegin); // Add 1 to memory limit to check if the query ends on a page break. criteria.setLimit(memoryLimit + 1); query = BasePeer.createQueryString(criteria); // Get a connection to the db. conn = Torque.getConnection(dbName); // Execute the query. if (log.isDebugEnabled()) { log.debug("run(): query = " + query); log.debug("run(): memoryLimit = " + memoryLimit); log.debug("run(): blockBegin = " + blockBegin); log.debug("run(): blockEnd = " + blockEnd); } qds = new QueryDataSet(conn, query); // Continue getting rows one page at a time until the memory limit // is reached, all results have been retrieved, or the rest // of the results have been determined to be irrelevant. while (!killThread && !qds.allRecordsRetrieved() && currentlyFilledTo + pageSize <= blockEnd) { // This caters for when memoryLimit is not a multiple of // pageSize which it never is because we always add 1 above. if ((currentlyFilledTo + pageSize) >= blockEnd) { // Add 1 to check if the query ends on a page break. size = blockEnd - currentlyFilledTo + 1; } if (log.isDebugEnabled()) { log.debug("run(): Invoking BasePeer.getSelectResults(qds, " + size + ", false)"); } List tempResults = BasePeer.getSelectResults(qds, size, false); for (int i = 0, n = tempResults.size(); i < n; i++) { results.add(tempResults.get(i)); } currentlyFilledTo += tempResults.size(); boolean perhapsLastPage = true; // If the extra record was indeed found then we know we are not // on the last page but we must now get rid of it. if (results.size() == memoryLimit + 1) { results.remove(currentlyFilledTo--); perhapsLastPage = false; } if (results.size() > 0 && blockBegin + currentlyFilledTo >= totalRecords) { // Add 1 because index starts at 0 totalRecords = blockBegin + currentlyFilledTo + 1; } if (qds.allRecordsRetrieved()) { queryCompleted = true; // The following ugly condition ensures that the totals are // not finalized when a user does something like requesting // a page greater than what exists in the database. if (perhapsLastPage && getCurrentPageNumber() <= getTotalPages()) { totalsFinalized = true; } } qds.clearRecords(); } if (log.isDebugEnabled()) { log.debug("run(): While loop terminated because either:"); log.debug("run(): 1. qds.allRecordsRetrieved(): " + qds.allRecordsRetrieved()); log.debug("run(): 2. killThread: " + killThread); log.debug("run(): 3. !(currentlyFilledTo + size <= blockEnd): !" + (currentlyFilledTo + pageSize <= blockEnd)); log.debug("run(): - currentlyFilledTo: " + currentlyFilledTo); log.debug("run(): - size: " + pageSize); log.debug("run(): - blockEnd: " + blockEnd); log.debug("run(): - results.size(): " + results.size()); } } catch (TorqueException e) { log.error(e); } catch (SQLException e) { log.error(e); } catch (DataSetException e) { log.error(e); } finally { try { if (qds != null) { qds.close(); } Torque.closeConnection(conn); } catch (SQLException e) { log.error(e); } catch (DataSetException e) { log.error(e); } threadRunning = false; } } /** * Starts a new thread to retrieve the result set. * * @param initialSize the initial size for each block. */ private synchronized void startQuery(int initialSize) { if (!threadRunning) { pageSize = initialSize; currentlyFilledTo = -1; queryCompleted = false; thread = new Thread(this); thread.start(); threadRunning = true; } } /** * Used to stop filling the memory with the current block of results, if it * has been determined that they are no longer relevant. * * @throws TorqueException if a sleep is interrupted. */ private synchronized void stopQuery() throws TorqueException { if (threadRunning) { killThread = true; while (thread.isAlive()) { try { Thread.sleep(100); } catch (InterruptedException e) { throw new TorqueException("Unexpected interruption", e); } } killThread = false; } } /** * Retrieve the number of the current page. * * @return the current page number. */ public int getCurrentPageNumber() { return currentPageNumber; } /** * Retrieve the total number of search result records that are known to * exist (this will be the actual value when the query has completeted (see * <code>getTotalsFinalized()</code>). The convenience method * <code>getRecordProgressText()</code> may be more useful for presenting to * users. * * @return the number of result records known to exist (not accurate until * <code>getTotalsFinalized()</code> returns <code>true</code>). */ public int getTotalRecords() { return totalRecords; } /** * Provide an indication of whether or not paging of results will be * required. * * @return <code>true</code> when multiple pages of results exist. */ public boolean getPaginated() { // Handle a page memory limit of 1 page. if (!getTotalsFinalized()) { return true; } return blockBegin + currentlyFilledTo + 1 > pageSize; } /** * Retrieve the total number of pages of search results that are known to * exist (this will be the actual value when the query has completeted (see * <code>getQyeryCompleted()</code>). The convenience method * <code>getPageProgressText()</code> may be more useful for presenting to * users. * * @return the number of pages of results known to exist (not accurate until * <code>getTotalsFinalized()</code> returns <code>true</code>). */ public int getTotalPages() { if (totalPages > -1) { return totalPages; } int tempPageCount = getTotalRecords() / pageSize + (getTotalRecords() % pageSize > 0 ? 1 : 0); if (getTotalsFinalized()) { totalPages = tempPageCount; } return tempPageCount; } /** * Retrieve the page size. * * @return the number of records returned on each invocation of * <code>getNextResults()</code>/<code>getPreviousResults()</code>. */ public int getPageSize() { return pageSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -