public QueryThread( int totalThreads, int queryThreadIndex, Integer rows, int batchSize, boolean distinct, boolean isLinkIndex, boolean isSuperIndex, QueryThread parameters) throws TechnicalException { this( totalThreads, queryThreadIndex, rows, batchSize, distinct, isLinkIndex, isSuperIndex, parameters.getDatabaseParameter(), parameters.getTableName(), parameters.getLeftJoinFields(), parameters.getRightJoinFields(), parameters.getResultFields()); }
private boolean processBatchResults( int currentQueryThreadIndex, QueryRunnerIntermediaryResult previousThreadResults) throws TechnicalException, FunctionalException { if (!first) { outln("Merging results"); } Timer intermediaryResultsProcessingTimer = null; if (!this.first && !this.last) { intermediaryResultsProcessingTimer = new Timer(); intermediaryResultsProcessingTimer.startTimer(); } // Prepare results for join with the next query this.batchResult = prepareResults(previousThreadResults, currentBatchResults); if (!last) { // wait till next thread is start processing the latest results List<Status> nextReadyList = nextQueryThread.getReadyList(); List<Status> tmp = null; Status firstStatus = null; synchronized (nextReadyList) { outln("wait for next thread to be ready"); while (nextReadyList.isEmpty()) { try { nextReadyList.wait(); } catch (InterruptedException e) { throw new TechnicalException(e); } } if (!nextReadyList.isEmpty()) { firstStatus = nextReadyList.remove(0); } else { MyUtils.errorProgram("SPONTANEOUS NOTIFICATION!!!!!!!!"); // shouldn't happen really } tmp = new ArrayList<Status>(nextReadyList); } outln("next status to process: " + firstStatus); if (checkCancelThread()) { // check here in case we sent a signal because of cancelling return true; } check(tmp.isEmpty(), checklog("nextReadyList = " + nextReadyList)); check( null == this .currentResult); // Must have been freed by next thread (call to // resetCurrentResult()) // Add the newest results for the next thread to process as soon as it's ready outln("Add input for next thread"); this.currentResult = batchResult; synchronized (this.statusList) { this.statusList.add(Status.RESULTS); this.statusList.notify(); // To notify next thread } } else { // Add final results outln("Add final results"); List<Integer> ignoreList = ThreadCommunication.getIgnoreList(); boolean cancelationInProcess = this.rows != null && ThreadCommunication.getTotalRows() >= this.rows; if (!cancelationInProcess) { try { for (List<String> list : batchResult.getValues()) { boolean first = true; for (int i = 0; i < list.size(); i++) { if (!ignoreList.contains(i)) { ThreadCommunication.bufferedWriter.write( (first ? "" : MyUtils.TAB_SEPARATOR) + list.get(i)); if (!QueryRunnerPrototypeConstants.LOG) { System.out.print((first ? "" : MyUtils.TAB_SEPARATOR) + list.get(i)); } first = false; } } ThreadCommunication.bufferedWriter.write(MyUtils.LINE_SEPARATOR); if (!QueryRunnerPrototypeConstants.LOG) { System.out.println(); } int totalRows = ThreadCommunication.addRowToTotalRows(); if (!this.unsynchronizedFirstFinalResults && totalRows == 1) { // if first row outln("notify first results have arrived"); synchronized (this.firstFinalResults) { this.firstFinalResults.setTrue(); this.firstFinalResults.notify(); // notify main thread this.unsynchronizedFirstFinalResults = true; } } if (!this.unsynchronizedSomeFinalResults && this.rows != null && totalRows == this.rows.intValue()) { outln("notify some results have arrived"); synchronized (this.someFinalResults) { this.unsynchronizedSomeFinalResults = true; this.someFinalResults.setTrue(); this.someFinalResults.notify(); // notify main thread } break; } } if (QueryRunnerPrototypeConstants.LOG) { ThreadCommunication.bufferedWriter.flush(); } } catch (IOException e) { throw new TechnicalException(e); } } } this.batchResult = null; if (!this.first && !this.last) { intermediaryResultsProcessingTimer.stopTimer(); this.intermediaryResultsProcessingAverageTime.addToAverage( intermediaryResultsProcessingTimer.getTimeEllapsedMs()); } return false; }