PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/thorlcr/activities/msort/thmsortslave.cpp

http://github.com/hpcc-systems/HPCC-Platform
C++ | 231 lines | 193 code | 19 blank | 19 comment | 11 complexity | d98495f8b397f38dd16323490a04d40a MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, MIT
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "platform.h"
  14. #include "limits.h"
  15. #include "slave.ipp"
  16. #include "thmsortslave.ipp"
  17. #include "thorport.hpp"
  18. #include "jio.hpp"
  19. #include "tsorts.hpp"
  20. #include "thsortu.hpp"
  21. #include "thactivityutil.ipp"
  22. #include "thexception.hpp"
  23. #define NUMSLAVEPORTS 2 // actually should be num MP tags
  24. //--------------------------------------------------------------------------------------------
  25. // MSortSlaveActivity
  26. //
  27. class MSortSlaveActivity : public CSlaveActivity
  28. {
  29. typedef CSlaveActivity PARENT;
  30. Owned<IRowStream> output;
  31. IHThorSortArg *helper;
  32. Owned<IThorSorter> sorter;
  33. unsigned portbase;
  34. rowcount_t totalrows;
  35. mptag_t mpTagRPC;
  36. Owned<IBarrier> barrier;
  37. SocketEndpoint server;
  38. CriticalSection statsCs;
  39. CRuntimeStatisticCollection spillStats;
  40. bool isUnstable()
  41. {
  42. return (helper&&helper->getAlgorithmFlags()&TAFunstable);
  43. }
  44. public:
  45. MSortSlaveActivity(CGraphElementBase *_container) : CSlaveActivity(_container), spillStats(spillStatistics)
  46. {
  47. portbase = 0;
  48. totalrows = RCUNSET;
  49. appendOutputLinked(this);
  50. }
  51. ~MSortSlaveActivity()
  52. {
  53. if (portbase)
  54. queryJobChannel().freePort(portbase,NUMSLAVEPORTS);
  55. }
  56. virtual void init(MemoryBuffer &data, MemoryBuffer &slaveData) override
  57. {
  58. mpTagRPC = container.queryJobChannel().deserializeMPTag(data);
  59. mptag_t barrierTag = container.queryJobChannel().deserializeMPTag(data);
  60. barrier.setown(container.queryJobChannel().createBarrier(barrierTag));
  61. portbase = queryJobChannel().allocPort(NUMSLAVEPORTS);
  62. ActPrintLog("MSortSlaveActivity::init portbase = %d, mpTagRPC = %d",portbase,(int)mpTagRPC);
  63. server.setLocalHost(portbase);
  64. helper = (IHThorSortArg *)queryHelper();
  65. sorter.setown(CreateThorSorter(this, server,&container.queryJob().queryIDiskUsage(),&queryJobChannel().queryJobComm(),mpTagRPC));
  66. server.serialize(slaveData);
  67. }
  68. virtual void start() override
  69. {
  70. ActivityTimer s(slaveTimerStats, timeActivities);
  71. try
  72. {
  73. try
  74. {
  75. PARENT::start();
  76. }
  77. catch (IException *e)
  78. {
  79. fireException(e);
  80. barrier->cancel();
  81. throw;
  82. }
  83. catch (CATCHALL)
  84. {
  85. Owned<IException> e = MakeActivityException(this, 0, "Unknown exception starting sort input");
  86. fireException(e);
  87. barrier->cancel();
  88. throw;
  89. }
  90. Linked<IThorRowInterfaces> rowif = queryRowInterfaces(input);
  91. Owned<IThorRowInterfaces> auxrowif;
  92. if (helper->querySortedRecordSize())
  93. auxrowif.setown(createRowInterfaces(helper->querySortedRecordSize()));
  94. sorter->Gather(
  95. rowif,
  96. inputStream,
  97. helper->queryCompare(),
  98. helper->queryCompareLeftRight(),
  99. NULL,helper->querySerialize(),
  100. NULL,
  101. NULL,
  102. false,
  103. isUnstable(),
  104. abortSoon,
  105. auxrowif);
  106. PARENT::stopInput(0);
  107. if (abortSoon)
  108. {
  109. ActPrintLogEx(&queryContainer(), thorlog_null, MCwarning, "MSortSlaveActivity::start aborting");
  110. barrier->cancel();
  111. return;
  112. }
  113. }
  114. catch (IException *e)
  115. {
  116. fireException(e);
  117. barrier->cancel();
  118. throw;
  119. }
  120. catch (CATCHALL)
  121. {
  122. Owned<IException> e = MakeActivityException(this, 0, "Unknown exception gathering sort input");
  123. fireException(e);
  124. barrier->cancel();
  125. throw;
  126. }
  127. ActPrintLog("SORT waiting barrier.1");
  128. if (!barrier->wait(false)) {
  129. Sleep(1000); // let original error through
  130. throw MakeThorException(TE_BarrierAborted,"SORT: Barrier Aborted");
  131. }
  132. ActPrintLog("SORT barrier.1 raised");
  133. output.setown(sorter->startMerge(totalrows));
  134. }
  135. virtual void stop() override
  136. {
  137. if (output)
  138. {
  139. output->stop();
  140. output.clear();
  141. }
  142. if (hasStarted())
  143. {
  144. ActPrintLog("SORT waiting barrier.2");
  145. barrier->wait(false);
  146. ActPrintLog("SORT barrier.2 raised");
  147. ActPrintLog("SORT waiting for merge");
  148. sorter->stopMerge();
  149. }
  150. PARENT::stop();
  151. }
  152. virtual void reset() override
  153. {
  154. PARENT::reset();
  155. if (sorter) return; // JCSMORE loop - shouldn't have to recreate sorter between loop iterations
  156. sorter.setown(CreateThorSorter(this, server,&container.queryJob().queryIDiskUsage(),&queryJobChannel().queryJobComm(),mpTagRPC));
  157. }
  158. virtual void kill() override
  159. {
  160. ActPrintLog("MSortSlaveActivity::kill");
  161. {
  162. CriticalBlock block(statsCs);
  163. mergeStats(spillStats, sorter);
  164. sorter.clear();
  165. }
  166. if (portbase)
  167. {
  168. queryJobChannel().freePort(portbase, NUMSLAVEPORTS);
  169. portbase = 0;
  170. }
  171. PARENT::kill();
  172. }
  173. virtual void serializeStats(MemoryBuffer &mb) override
  174. {
  175. CSlaveActivity::serializeStats(mb);
  176. CriticalBlock block(statsCs);
  177. CRuntimeStatisticCollection mergedStats(spillStats);
  178. mergeStats(mergedStats, sorter);
  179. mergedStats.serialize(mb);
  180. }
  181. CATCH_NEXTROW()
  182. {
  183. ActivityTimer t(slaveTimerStats, timeActivities);
  184. if (abortSoon)
  185. return NULL;
  186. OwnedConstThorRow row = output->nextRow();
  187. if (!row)
  188. return NULL;
  189. dataLinkIncrement();
  190. return row.getClear();
  191. }
  192. virtual bool isGrouped() const override { return false; }
  193. virtual void getMetaInfo(ThorDataLinkMetaInfo &info) const override
  194. {
  195. initMetaInfo(info);
  196. info.buffersInput = true;
  197. info.unknownRowsOutput = false; // shuffles rows
  198. if (totalrows!=RCUNSET) { // NB totalrows not available until after start
  199. info.totalRowsMin = totalrows;
  200. info.totalRowsMax = totalrows;
  201. }
  202. }
  203. };
  204. CActivityBase *createMSortSlave(CGraphElementBase *container)
  205. {
  206. ActPrintLog(container, "MSortSlaveActivity::createMSortSlave");
  207. return new MSortSlaveActivity(container);
  208. }