hqlresource.ipp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef __HQLRESOURCE_IPP_
  15. #define __HQLRESOURCE_IPP_
  16. #include "hqlresource.hpp"
  17. enum ResourceType {
  18. //Slave specific
  19. RESslavememory,
  20. RESslavesocket,
  21. //Master specific
  22. RESmastermemory,
  23. RESmastersocket,
  24. //General
  25. REShashdist,
  26. RESheavy,
  27. RESactivities,
  28. RESmax
  29. };
  30. class CResourceOptions
  31. {
  32. public:
  33. CResourceOptions() { state.updateSequence = 0; }
  34. IHqlExpression * createSpillName(bool isGraphResult);
  35. void noteGraphsChanged() { state.updateSequence++; }
  36. public:
  37. unsigned filteredSpillThreshold;
  38. unsigned minimizeSpillSize;
  39. bool allowThroughSpill;
  40. bool allowThroughResult;
  41. bool cloneFilteredIndex;
  42. bool spillSharedConditionals;
  43. bool shareDontExpand;
  44. bool useGraphResults;
  45. bool noConditionalLinks;
  46. bool minimiseSpills;
  47. bool hoistResourced;
  48. bool isChildQuery;
  49. bool groupedChildIterators;
  50. bool allowSplitBetweenSubGraphs;
  51. bool supportsChildQueries;
  52. bool preventKeyedSplit;
  53. bool preventSteppedSplit;
  54. bool mangleSpillNameWithWuid;
  55. bool minimizeSkewBeforeSpill;
  56. bool useMpForDistribute;
  57. bool expandSingleConstRow;
  58. bool createSpillAsDataset;
  59. bool useLinkedRawIterator;
  60. bool optimizeSharedInputs;
  61. bool combineSiblings;
  62. IHqlExpression * graphIdExpr;
  63. unsigned nextResult;
  64. unsigned clusterSize;
  65. StringAttr filenameMangler;
  66. ClusterType targetClusterType;
  67. //Used
  68. struct
  69. {
  70. unsigned updateSequence;
  71. } state;
  72. inline bool canSplit() const { return targetClusterType != HThorCluster; }
  73. inline bool checkResources() const { return isThorCluster(targetClusterType) && !isChildQuery; }
  74. inline bool targetRoxie() const { return targetClusterType == RoxieCluster; }
  75. inline bool targetThor() const { return targetClusterType == ThorCluster || targetClusterType == ThorLCRCluster; }
  76. };
  77. struct CResources : public CInterface
  78. {
  79. public:
  80. CResources(unsigned _clusterSize) { clusterSize = _clusterSize; _clear(resource); }
  81. CResources(const CResources & other) { clusterSize = other.clusterSize; set(other); }
  82. void add(const CResources & other);
  83. bool addExceeds(const CResources & other, const CResources & limit) const;
  84. void clear() { _clear(resource); }
  85. bool exceeds(const CResources & limit) const;
  86. StringBuffer & getExceedsReason(StringBuffer & reasonText, const CResources & other, const CResources & limit) const;
  87. void maximize(const CResources & other);
  88. CResources & set(ResourceType kind, unsigned value) { resource[kind] = value; return *this; }
  89. CResources & set(const CResources & other) { memcpy(&resource, &other.resource, sizeof(resource)); return *this; }
  90. CResources & setLightweight();
  91. CResources & setHeavyweight();
  92. CResources & setManyToManySockets(unsigned num);
  93. CResources & setManyToMasterSockets(unsigned num);
  94. void sub(const CResources & other);
  95. public:
  96. unsigned resource[RESmax];
  97. unsigned clusterSize;
  98. };
  99. enum LinkKind { UnconditionalLink, ConditionalLink, SequenceLink };
  100. class ResourceGraphInfo;
  101. class ResourceGraphLink : public CInterface
  102. {
  103. public:
  104. ResourceGraphLink(ResourceGraphInfo * _sourceGraph, IHqlExpression * _sourceNode, ResourceGraphInfo * _sinkGraph, IHqlExpression * _sinkNode, LinkKind _kind);
  105. ~ResourceGraphLink();
  106. virtual void changeSourceGraph(ResourceGraphInfo * newGraph);
  107. virtual void changeSinkGraph(ResourceGraphInfo * newGraph);
  108. virtual bool isRedundantLink();
  109. virtual bool isDependency() { return false; }
  110. protected:
  111. void trace(const char * name);
  112. public:
  113. Owned<ResourceGraphInfo> sourceGraph;
  114. Owned<ResourceGraphInfo> sinkGraph;
  115. OwnedHqlExpr sourceNode;
  116. OwnedHqlExpr sinkNode;
  117. byte linkKind;
  118. };
  119. class ResourceGraphDependencyLink : public ResourceGraphLink
  120. {
  121. public:
  122. ResourceGraphDependencyLink(ResourceGraphInfo * _sourceGraph, IHqlExpression * _sourceNode, ResourceGraphInfo * _sinkGraph, IHqlExpression * _sinkNode);
  123. virtual void changeSourceGraph(ResourceGraphInfo * newGraph);
  124. virtual void changeSinkGraph(ResourceGraphInfo * newGraph);
  125. virtual bool isRedundantLink() { return false; }
  126. virtual bool isDependency() { return true; }
  127. };
  128. typedef CIArrayOf<ResourceGraphInfo> ResourceGraphArray;
  129. typedef CopyCIArrayOf<ResourceGraphLink> GraphLinkArray;
  130. class ResourceGraphInfo : public CInterface
  131. {
  132. public:
  133. ResourceGraphInfo(CResourceOptions * _options);
  134. ~ResourceGraphInfo();
  135. bool addCondition(IHqlExpression * condition);
  136. bool allocateResources(const CResources & value, const CResources & limit);
  137. bool containsActiveSinks();
  138. unsigned getDepth();
  139. void getMergeFailReason(StringBuffer & reasonText, ResourceGraphInfo * otherGraph, const CResources & limit);
  140. bool hasSameConditions(ResourceGraphInfo & other);
  141. bool isDependentOn(ResourceGraphInfo & other, bool allowDirect);
  142. bool isVeryCheap();
  143. bool mergeInSibling(ResourceGraphInfo & other, const CResources & limit);
  144. bool mergeInSource(ResourceGraphInfo & other, const CResources & limit, bool isConditionalLink);
  145. void removeResources(const CResources & value);
  146. bool isSharedInput(IHqlExpression * expr);
  147. void addSharedInput(IHqlExpression * expr, IHqlExpression * mapped);
  148. IHqlExpression * queryMappedSharedInput(IHqlExpression * expr);
  149. protected:
  150. void display();
  151. void mergeGraph(ResourceGraphInfo & other, bool isConditionalLink, bool mergeConditions);
  152. bool evalDependentOn(ResourceGraphInfo & other, bool ignoreSources);
  153. public:
  154. OwnedHqlExpr createdGraph;
  155. CResourceOptions * options;
  156. GraphLinkArray dependsOn; // NB: These do no link....
  157. GraphLinkArray sources;
  158. GraphLinkArray sinks;
  159. HqlExprArray conditions;
  160. HqlExprArray sharedInputs;
  161. HqlExprArray unbalancedExternalSources;
  162. HqlExprArray balancedExternalSources;
  163. CResources resources;
  164. unsigned depth;
  165. unsigned depthSequence;
  166. bool beenResourced;
  167. bool isUnconditional;
  168. bool mergedConditionSource;
  169. bool hasConditionSource;
  170. bool isDead;
  171. bool startedGeneratingResourced;
  172. bool inheritedExpandedDependencies;
  173. struct
  174. {
  175. ResourceGraphInfo * other;
  176. unsigned updateSequence;
  177. bool ignoreSources;
  178. bool value;
  179. } cachedDependent;
  180. };
  181. class ResourcerInfo : public CInterface, public IInterface
  182. {
  183. public:
  184. enum { PathUnknown, PathConditional, PathUnconditional };
  185. ResourcerInfo(IHqlExpression * _original, CResourceOptions * _options);
  186. IMPLEMENT_IINTERFACE
  187. IHqlExpression * createSpilledRead(IHqlExpression * spillReason);
  188. IHqlExpression * createTransformedExpr(IHqlExpression * expr);
  189. bool addCondition(IHqlExpression * condition);
  190. bool alwaysExpand();
  191. unsigned calcNumConditionalUses();
  192. bool expandRatherThanSpill(bool noteOtherSpills);
  193. bool expandRatherThanSplit();
  194. bool isExternalSpill();
  195. bool neverCommonUp();
  196. bool isSplit();
  197. bool isSpilledWrite();
  198. bool okToSpillThrough();
  199. void noteUsedFromChild() { linkedFromChild = true; outputToUseForSpill = NULL; }
  200. unsigned numInternalUses() { return numUses - numExternalUses - aggregates.ordinality(); }
  201. unsigned numSplitPaths();
  202. void setConditionSource(IHqlExpression * condition, bool isFirst);
  203. //hthor - don't merge anything to a global result because we don't allow splitters.
  204. inline bool preventMerge() { return !options->canSplit() && useGlobalResult(); }
  205. inline bool isUnconditional() { return (pathToExpr == ResourcerInfo::PathUnconditional); }
  206. inline bool isConditionExpr()
  207. {
  208. switch (original->getOperator())
  209. {
  210. case no_if:
  211. return true;
  212. case no_output:
  213. case no_buildindex:
  214. return isUpdatedConditionally(original);
  215. }
  216. return false;
  217. }
  218. protected:
  219. bool spillSharesSplitter();
  220. bool useGraphResult();
  221. bool useGlobalResult();
  222. IHqlExpression * createAggregation(IHqlExpression * expr);
  223. IHqlExpression * createSpilledWrite(IHqlExpression * transformed);
  224. IHqlExpression * createSpiller(IHqlExpression * transformed, bool reuseSplitter);
  225. IHqlExpression * createSplitter(IHqlExpression * transformed);
  226. protected:
  227. void addSpillFlags(HqlExprArray & args, bool isRead);
  228. IHqlExpression * createSpillName();
  229. IHqlExpression * wrapRowOwn(IHqlExpression * expr);
  230. public:
  231. HqlExprAttr original;
  232. Owned<ResourceGraphInfo> graph;
  233. HqlExprAttr spillName;
  234. IHqlExpression * transformed;
  235. IHqlExpression * outputToUseForSpill;
  236. CResourceOptions * options;
  237. HqlExprAttr pathToSplitter;
  238. HqlExprArray aggregates;
  239. HqlExprArray conditions;
  240. HqlExprArray childDependents;
  241. HqlExprCopyArray originalChildDependents;
  242. BoolArray childSingleNode;
  243. HqlExprAttr spilledDataset;
  244. HqlExprAttr splitterOutput;
  245. unsigned numUses;
  246. unsigned numExternalUses;
  247. unsigned conditionSourceCount;
  248. unsigned currentSource;
  249. bool containsActivity;
  250. bool isActivity;
  251. bool gatheredDependencies;
  252. bool isSpillPoint;
  253. bool balanced;
  254. bool isAlreadyInScope;
  255. bool linkedFromChild;
  256. bool neverSplit;
  257. byte pathToExpr;
  258. };
  259. struct DependencySourceInfo
  260. {
  261. HqlExprArray search;
  262. CIArrayOf<ResourceGraphInfo> graphs;
  263. HqlExprArray exprs;
  264. };
  265. class EclResourcer
  266. {
  267. friend class SelectHoistTransformer;
  268. public:
  269. EclResourcer(IErrorReceiver * _errors, IConstWorkUnit * _wu, ClusterType _targetClusterType, unsigned _clusterSize, const HqlCppOptions & _translatorOptions);
  270. ~EclResourcer();
  271. void resourceGraph(HqlExprArray & exprs, HqlExprArray & transformed);
  272. void resourceRemoteGraph(HqlExprArray & exprs, HqlExprArray & transformed);
  273. void setChildQuery(bool value);
  274. void setNewChildQuery(IHqlExpression * graphIdExpr, unsigned numResults);
  275. void setUseGraphResults(bool _useGraphResults)
  276. {
  277. options.useGraphResults = _useGraphResults;
  278. if (_useGraphResults)
  279. options.createSpillAsDataset = false;
  280. }
  281. void tagActiveCursors(HqlExprCopyArray & activeRows);
  282. inline unsigned numGraphResults() { return options.nextResult; }
  283. protected:
  284. void changeGraph(IHqlExpression * expr, ResourceGraphInfo * newGraph);
  285. void connectGraphs(ResourceGraphInfo * sourceGraph, IHqlExpression * sourceNode, ResourceGraphInfo * sinkGraph, IHqlExpression * sinkNode, LinkKind linkKind);
  286. ResourceGraphInfo * createGraph();
  287. ResourcerInfo * queryCreateResourceInfo(IHqlExpression * expr);
  288. void removeLink(ResourceGraphLink & link, bool keepExternalUses);
  289. void replaceGraphReferences(IHqlExpression * expr, ResourceGraphInfo * oldGraph, ResourceGraphInfo * newGraph);
  290. void replaceGraphReferences(ResourceGraphInfo * oldGraph, ResourceGraphInfo * newGraph);
  291. //Pass 1
  292. void gatherChildSplitPoints(IHqlExpression * expr, BoolArray & alwaysHoistChild, ResourcerInfo * info, unsigned first, unsigned last);
  293. bool findSplitPoints(IHqlExpression * expr);
  294. void findSplitPoints(HqlExprArray & exprs);
  295. void noteConditionalChildren(BoolArray & alwaysHoistChild);
  296. void extendSplitPoints();
  297. //Pass 2
  298. void createInitialGraph(IHqlExpression * expr, IHqlExpression * owner, ResourceGraphInfo * ownerGraph, LinkKind linkKind, bool forceNewGraph);
  299. void createInitialGraphs(HqlExprArray & exprs);
  300. void createInitialRemoteGraph(IHqlExpression * expr, IHqlExpression * owner, ResourceGraphInfo * ownerGraph, bool forceNewGraph);
  301. void createInitialRemoteGraphs(HqlExprArray & exprs);
  302. //Pass 3
  303. void markAsUnconditional(IHqlExpression * expr, ResourceGraphInfo * ownerGraph, IHqlExpression * condition);
  304. void markCondition(IHqlExpression * expr, IHqlExpression * condition, bool wasConditional);
  305. void markConditionBranch(unsigned childIndex, IHqlExpression * expr, IHqlExpression * condition, bool wasConditional);
  306. void markConditions(HqlExprArray & exprs);
  307. void markChildDependentsAsUnconditional(ResourcerInfo * info, IHqlExpression * condition);
  308. //Pass 4
  309. void createResourceSplit(IHqlExpression * expr, IHqlExpression * owner, ResourceGraphInfo * ownerNewGraph, ResourceGraphInfo * originalGraph);
  310. void getResources(IHqlExpression * expr, CResources & exprResources);
  311. bool calculateResourceSpillPoints(IHqlExpression * expr, ResourceGraphInfo * graph, CResources & resourcesSoFar, bool hasGoodSpillPoint, bool canSpill);
  312. void insertResourceSpillPoints(IHqlExpression * expr, IHqlExpression * owner, ResourceGraphInfo * ownerOriginalGraph, ResourceGraphInfo * ownerNewGraph);
  313. void resourceSubGraph(ResourceGraphInfo * graph);
  314. void resourceSubGraphs(HqlExprArray & exprs);
  315. //Pass 5
  316. void addDependencySource(IHqlExpression * search, ResourceGraphInfo * curGraph, IHqlExpression * expr);
  317. void addDependencyUse(IHqlExpression * search, ResourceGraphInfo * curGraph, IHqlExpression * expr);
  318. bool addExprDependency(IHqlExpression * expr, ResourceGraphInfo * curGraph, IHqlExpression * activityExpr);
  319. void addRefExprDependency(IHqlExpression * expr, ResourceGraphInfo * curGraph, IHqlExpression * activityExpr);
  320. void doAddChildDependencies(IHqlExpression * expr, ResourceGraphInfo * graph, IHqlExpression * activityExpr);
  321. void addChildDependencies(IHqlExpression * expr, ResourceGraphInfo * graph, IHqlExpression * activityExpr);
  322. void addDependencies(IHqlExpression * expr, ResourceGraphInfo * graph, IHqlExpression * activityExpr);
  323. void addDependencies(HqlExprArray & exprs);
  324. //Pass 6
  325. bool queryMergeGraphLink(ResourceGraphLink & link);
  326. void mergeSubGraphs();
  327. void mergeSubGraphs(unsigned pass);
  328. void mergeSiblings();
  329. //Pass 6b
  330. void spotUnbalancedSplitters(IHqlExpression * expr, unsigned whichSource, IHqlExpression * path, ResourceGraphInfo * graph);
  331. void spotUnbalancedSplitters(HqlExprArray & exprs);
  332. //Pass 6c
  333. void spotSharedInputs(IHqlExpression * expr, ResourceGraphInfo * graph);
  334. void spotSharedInputs();
  335. //Pass 7
  336. bool optimizeAggregate(IHqlExpression * expr);
  337. void optimizeAggregates();
  338. //Pass 8
  339. IHqlExpression * findPredecessor(IHqlExpression * expr, IHqlExpression * search, IHqlExpression * prev);
  340. IHqlExpression * findPredecessor(ResourcerInfo * search);
  341. void moveExternalSpillPoints();
  342. //Pass 9
  343. IHqlExpression * replaceResourcedReferences(ResourcerInfo * info, IHqlExpression * expr);
  344. IHqlExpression * doCreateResourced(IHqlExpression * expr, ResourceGraphInfo * graph, bool expandInParent, bool defineSideEffect);
  345. IHqlExpression * createResourced(IHqlExpression * expr, ResourceGraphInfo * graph, bool expandInParent, bool defineSideEffect);
  346. void createResourced(HqlExprArray & transformed);
  347. void createResourced(ResourceGraphInfo * graph, HqlExprArray & transformed);
  348. void inheritRedundantDependencies(ResourceGraphInfo * thisGraph);
  349. void display(StringBuffer & out);
  350. void trace();
  351. void doCheckRecursion(ResourceGraphInfo * graph, PointerArray & visited);
  352. void checkRecursion(ResourceGraphInfo * graph, PointerArray & visited);
  353. void checkRecursion(ResourceGraphInfo * graph);
  354. unsigned getMaxDepth() const;
  355. protected:
  356. Owned<IConstWorkUnit> wu;
  357. CIArrayOf<ResourceGraphInfo> graphs;
  358. CIArrayOf<ResourceGraphLink> links;
  359. ClusterType targetClusterType;
  360. DependencySourceInfo dependencySource;
  361. unsigned clusterSize;
  362. CResources * resourceLimit;
  363. IErrorReceiver * errors;
  364. bool spilled;
  365. bool spillMultiCondition;
  366. bool spotThroughAggregate;
  367. bool insideNeverSplit;
  368. CResourceOptions options;
  369. HqlExprArray rootConditions;
  370. HqlExprCopyArray activeSelectors;
  371. HqlExprCopyArray conditionalChildren;
  372. };
  373. #endif