wuattr.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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 "wuattr.hpp"
  14. #include "jptree.hpp"
  15. #include "jstats.h"
  16. struct WuAttrInfo
  17. {
  18. public:
  19. WuAttr kind; // The attribute enumeration
  20. StatisticMeasure measure; // units for the measure
  21. const char * name; // text version of the attribute
  22. const char * graphPath; // The xpath required to extract a result from a graph node.
  23. const char * overridePath; // Alternative xpath to check 1st for some overloaded attributes
  24. const char * childPath; // The name of the <atr> for setting, or matching when iterating
  25. const char * dft; // default value if not present
  26. WuAttr singleKind;
  27. WuAttr multiKind;
  28. };
  29. #define CHILDPATH(x) "att[@name='" x "']/@value"
  30. #define CHILDMPATH(x) "att[@name='" x "'][1]/@value"
  31. #define ATTR(kind, measure, path) { Wa ## kind, measure, #kind, path, nullptr, nullptr, nullptr, WaNone, WaNone }
  32. #define ALTATTR(kind, measure, path, alt) { Wa ## kind, measure, #kind, path, alt, nullptr, nullptr, WaNone, WaNone }
  33. #define CHILD(kind, measure, path) { Wa ## kind, measure, #kind, CHILDPATH(path), nullptr, path, nullptr, WaNone, WaNone }
  34. #define CHILD_MULTI(kind, measure, path) { Wa ## kind, measure, #kind, CHILDMPATH(path), nullptr, path, nullptr, Wa ## kind, Wa ## kind ## List }
  35. #define CHILD_LIST(kind, measure) { Wa ## kind ## List, measure, #kind "List", nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
  36. #define CHILD_D(kind, measure, path, dft) { Wa ## kind, measure, #kind, CHILDPATH(path), nullptr, path, dft, WaNone, WaNone }
  37. #define ATTRX(kind, measure) { Wa ## kind, measure, #kind, nullptr, nullptr, nullptr, nullptr, WaNone, WaNone }
  38. #define ATTRX_MULTI(kind, measure) { Wa ## kind , measure, #kind, nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
  39. #define ATTRX_LIST(kind, measure) { Wa ## kind ## List, measure, #kind "List", nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
  40. const static WuAttrInfo attrInfo[] = {
  41. { WaNone, SMeasureNone, "none", nullptr, nullptr, nullptr, nullptr, WaNone, WaNone },
  42. { WaAll, SMeasureNone, "all", nullptr, nullptr, nullptr, nullptr, WaNone, WaNone },
  43. CHILD(Kind, SMeasureEnum, "_kind"),
  44. ALTATTR(IdSource, SMeasureId, "@source", "att[@name='_sourceActivity']/@value"),
  45. ALTATTR(IdTarget, SMeasureId, "@target", "att[@name='_targetActivity']/@value"),
  46. CHILD_D(SourceIndex, SMeasureText, "_sourceIndex", "0"),
  47. CHILD_D(TargetIndex, SMeasureText, "_targetIndex", "0"),
  48. ATTR(Label, SMeasureText, "@label"),
  49. CHILD(IsDependency, SMeasureBool, "_dependsOn"),
  50. CHILD(IsChildGraph, SMeasureBool, "_childGraph"),
  51. CHILD_MULTI(Definition, SMeasureText, "definition"),
  52. CHILD_LIST(Definition, SMeasureText),
  53. CHILD_MULTI(EclName, SMeasureText, "name"),
  54. CHILD_LIST(EclName, SMeasureText),
  55. CHILD(EclText, SMeasureText, "ecl"),
  56. CHILD(RecordSize, SMeasureText, "recordSize"),
  57. CHILD(PredictedCount, SMeasureText, "predictedCount"),
  58. CHILD(IsGrouped, SMeasureBool, "grouped"),
  59. CHILD(IsLocal, SMeasureBool, "local"),
  60. CHILD(IsCoLocal, SMeasureBool, "coLocal"),
  61. CHILD(IsOrdered, SMeasureBool, "ordered"),
  62. CHILD(IsInternal, SMeasureBool, "_internal"),
  63. CHILD(IsNoAccess, SMeasureBool, "noAccess"),
  64. CHILD(IsGraphIndependent, SMeasureBool, "_graphIndependent"),
  65. CHILD(IsUpdateIfChanged, SMeasureBool, "_updateIfChanged"),
  66. CHILD(IsKeyed, SMeasureBool, "_isKeyed"),
  67. CHILD(IsPreload, SMeasureBool, "preload"),
  68. CHILD(IsDiskAccessRequired, SMeasureBool, "_diskAccessRequired"),
  69. CHILD(IsFileOpt, SMeasureBool, "_isOpt"),
  70. CHILD(IsIndexOpt, SMeasureBool, "_isIndexOpt"),
  71. CHILD(IsPatchOpt, SMeasureBool, "_isPatchOpt"),
  72. CHILD(Filename, SMeasureFilename, "_fileName"),
  73. CHILD(Indexname, SMeasureFilename, "_indexFileName"),
  74. CHILD(PatchFilename, SMeasureFilename, "_patchName"),
  75. CHILD(IsFilenameDynamic, SMeasureBool, "_file_dynamic"),
  76. CHILD(IsIndexnameDynamic, SMeasureBool, "_indexFile_dynamic"),
  77. CHILD(IsPatchFilenameDynamic, SMeasureBool, "_patch_dynamic"),
  78. CHILD(IsEmbedded, SMeasureBool, "embedded"),
  79. CHILD(IsSpill, SMeasureBool, "_isSpill"),
  80. CHILD(IsGlobalSpill, SMeasureBool, "_isSpillGlobal"),
  81. CHILD(IsAccessedFromChild, SMeasureBool, "_fromChild"),
  82. CHILD(IsTransformSpill, SMeasureBool, "_isTransformSpill"),
  83. CHILD(OriginalFilename, SMeasureFilename, "_originalName"),
  84. CHILD(OutputFilename, SMeasureFilename, "_outputName"),
  85. CHILD(UpdatedFilename, SMeasureFilename, "_updatedName"),
  86. CHILD(DistributeIndexname, SMeasureFilename, "_distributeIndexName"),
  87. CHILD(IsOriginalFilenameDynamic, SMeasureBool, "_originalName_dynamic"),
  88. CHILD(IsOutputFilenameDynamic, SMeasureBool, "_outputName_dynamic"),
  89. CHILD(IsUpdatedFilenameDynamic, SMeasureBool, "_updatedName_dynamic"),
  90. CHILD(IsDistributeIndexnameDynamic, SMeasureBool, "_distributeIndexName_dynamic"),
  91. CHILD(SignedBy, SMeasureText, "signedBy"),
  92. CHILD(MetaDistribution, SMeasureText, "metaDistribution"),
  93. CHILD(MetaGrouping, SMeasureText, "metaGrouping"),
  94. CHILD(MetaGlobalSortOrder, SMeasureText, "metaGlobalSortOrder"),
  95. CHILD(MetaLocalSortOrder, SMeasureText, "metaLocalSortOrder"),
  96. CHILD(MetaGroupSortOrder, SMeasureText, "metaGroupSortOrder"),
  97. CHILD_MULTI(Section, SMeasureText, "section"),
  98. CHILD_LIST(Section, SMeasureText),
  99. CHILD(LibraryName, SMeasureText, "libname"),
  100. CHILD(MatchLikelihood, SMeasureText, "matchLikelihood"),
  101. CHILD(SpillReason, SMeasureText, "spillReason"),
  102. CHILD(NumChildQueries, SMeasureCount, "childQueries"),
  103. CHILD(SizeClassApprox, SMeasureSize, "approxClassSize"),
  104. CHILD(IdParentActivity, SMeasureId, "_parentActivity"),
  105. CHILD(NumParallel, SMeasureCount, "parallel"),
  106. CHILD(Algorithm, SMeasureText, "algorithm"),
  107. CHILD(SizePreload, SMeasureSize, "_preloadSize"),
  108. CHILD(IdLoop, SMeasureId, "_loopid"),
  109. CHILD(IdSubGraph, SMeasureId, "_subgraph"),
  110. CHILD(IdGraph, SMeasureId, "graph"),
  111. CHILD(IdChildGraph, SMeasureId, "_graphId"),
  112. CHILD(IdAmbiguousGraph, SMeasureId, "_graphid"),
  113. CHILD(IdLibraryGraph, SMeasureId, "_libraryGraphId"),
  114. CHILD(IdRemoteSubGraph, SMeasureId, "_remoteSubGraph"),
  115. CHILD(InterfaceHash, SMeasureText, "_interfaceHash"),
  116. CHILD(NumMaxOutputs, SMeasureCount, "_maxOutputs"),
  117. CHILD(IsRootGraph, SMeasureBool, "rootGraph"),
  118. ATTR(IsNWay, SMeasureBool, "@nWay"),
  119. CHILD(IsCosort, SMeasureBool, "cosort"),
  120. CHILD(NumGlobalUses, SMeasureCount, "_globalUsageCount"),
  121. ATTR(IsMultiInstance, SMeasureBool, "@multiInstance"),
  122. ATTR(IsDelayed, SMeasureBool, "@delayed"),
  123. ATTR(IsChild, SMeasureBool, "@child"),
  124. ATTR(IsSequential, SMeasureBool, "@sequential"),
  125. ATTR(IsLoopBody, SMeasureBool, "@loopBody"),
  126. CHILD(NumResults, SMeasureCount, "_numResults"),
  127. CHILD(WhenIndex, SMeasureText, "_when"),
  128. ATTRX_MULTI(IdDependency, SMeasureId),
  129. ATTRX_LIST(IdDependency, SMeasureId),
  130. ATTRX(IsScheduled, SMeasureBool),
  131. ATTRX(IdSuccess, SMeasureId),
  132. ATTRX(IdFailure, SMeasureId),
  133. ATTRX(IdRecovery, SMeasureId),
  134. ATTRX(IdPersist, SMeasureId),
  135. ATTRX(IdScheduled, SMeasureId),
  136. ATTRX(PersistName, SMeasureText),
  137. ATTRX(Type, SMeasureText),
  138. ATTRX(Mode, SMeasureText),
  139. ATTRX(State, SMeasureText),
  140. ATTRX(Cluster, SMeasureText),
  141. ATTRX(CriticalSection, SMeasureText),
  142. CHILD(DiskFormat, SMeasureText, "diskFormat"),
  143. CHILD(RecordFormat, SMeasureText, "recordFormat"),
  144. CHILD(ServiceName, SMeasureText, "serviceName"),
  145. { WaMax, SMeasureNone, nullptr, nullptr, nullptr, nullptr, nullptr, WaNone, WaNone }
  146. };
  147. static MapConstStringTo<WuAttr, WuAttr> nameToWa(true); // Names are case insensitive
  148. static MapConstStringTo<WuAttr, WuAttr> graphAttrToWa(false); // paths and attrs are cases sensitive
  149. static MapConstStringTo<WuAttr, WuAttr> childAttrToWa(false);
  150. MODULE_INIT(INIT_PRIORITY_STANDARD)
  151. {
  152. static_assert(_elements_in(attrInfo) >= (WaMax-WaNone)+1, "Elements missing from attrInfo[]");
  153. static_assert(_elements_in(attrInfo) <= (WaMax-WaNone)+1, "Extra elements in attrInfo[]");
  154. for (unsigned i=0; i < _elements_in(attrInfo); i++)
  155. {
  156. const WuAttrInfo & info = attrInfo[i];
  157. WuAttr attr = (WuAttr)(WaNone + i);
  158. assertex(info.kind == attr);
  159. if (info.name)
  160. nameToWa.setValue(info.name, attr); // cannot clash since derived from a unique name
  161. #ifdef _DEBUG
  162. const char * prefix = queryMeasurePrefix(info.measure);
  163. if (info.name && prefix && *prefix)
  164. {
  165. if (!startsWith(info.name, prefix))
  166. printf("Mismatched prefix %s %s\n", info.name, prefix);
  167. }
  168. #endif
  169. const char * path = info.graphPath;
  170. if (path && path[0] == '@')
  171. {
  172. if (graphAttrToWa.getValue(path+1))
  173. throwUnexpectedX("Duplicate Graph Attr");
  174. graphAttrToWa.setValue(path+1, attr);
  175. }
  176. const char * childPath = info.childPath;
  177. if (childPath)
  178. {
  179. if (childAttrToWa.getValue(childPath))
  180. throwUnexpectedX("Duplicate Child Attr");
  181. childAttrToWa.setValue(childPath, attr);
  182. }
  183. }
  184. return true;
  185. }
  186. const char * queryWuAttributeName(WuAttr kind)
  187. {
  188. if ((kind >= WaNone) && (kind < WaMax))
  189. return attrInfo[kind-WaNone].name;
  190. return nullptr;
  191. }
  192. WuAttr queryWuAttribute(const char * kind, WuAttr dft)
  193. {
  194. WuAttr * match = nameToWa.getValue(kind);
  195. if (match)
  196. return *match;
  197. return dft;
  198. }
  199. extern WORKUNIT_API const char * queryAttributeValue(IPropertyTree & src, WuAttr kind, StringBuffer & scratchpad)
  200. {
  201. if ((kind <= WaNone) || (kind >= WaMax))
  202. return nullptr;
  203. const WuAttrInfo & info = attrInfo[kind-WaNone];
  204. const char * path = info.graphPath;
  205. const char * altpath = info.overridePath;
  206. const char * value = altpath ? src.queryProp(altpath) : nullptr;
  207. if (!value)
  208. value = src.queryProp(path);
  209. if (!value && info.dft)
  210. value = info.dft;
  211. //The following switch statement allows the value returned to be transformed from the value stored.
  212. switch (kind)
  213. {
  214. case WaIdSource:
  215. case WaIdTarget:
  216. case WaIdParentActivity:
  217. value = scratchpad.clear().append(ActivityScopePrefix).append(value).str();
  218. break;
  219. case WaIdLibraryGraph:
  220. value = scratchpad.clear().append(GraphScopePrefix).append(value).str();
  221. break;
  222. // case WaIdLoop:
  223. //?Prefix with the graph id?
  224. //value = scratchpad.clear().append(ChildGraphScopePrefix).append(value).str();
  225. break;
  226. case WaIdLoop:
  227. case WaIdSubGraph:
  228. case WaIdRemoteSubGraph:
  229. value = scratchpad.clear().append(ChildGraphScopePrefix).append(value).str();
  230. break;
  231. }
  232. return value;
  233. }
  234. extern WORKUNIT_API WuAttr queryGraphAttrToWuAttr(const char * name)
  235. {
  236. WuAttr * match = graphAttrToWa.getValue(name);
  237. if (match)
  238. return *match;
  239. return WaNone;
  240. }
  241. extern WORKUNIT_API WuAttr queryGraphChildAttToWuAttr(const char * name)
  242. {
  243. WuAttr * match = childAttrToWa.getValue(name);
  244. if (match)
  245. return *match;
  246. return WaNone;
  247. }
  248. static IPropertyTree * addGraphAttribute(IPropertyTree * node, const char * name)
  249. {
  250. IPropertyTree * att = createPTree();
  251. att->setProp("@name", name);
  252. return node->addPropTree("att", att);
  253. }
  254. void setAttributeValue(IPropertyTree & tgt, WuAttr kind, const char * value)
  255. {
  256. const WuAttrInfo & info = attrInfo[kind-WaNone];
  257. const char * path = info.graphPath;
  258. if (path[0] == '@')
  259. tgt.setProp(path, value);
  260. else
  261. addGraphAttribute(&tgt, info.childPath)->setProp("@value", value);
  262. }
  263. void setAttributeValueBool(IPropertyTree & tgt, WuAttr kind, bool value, bool alwaysAdd)
  264. {
  265. const WuAttrInfo & info = attrInfo[kind-WaNone];
  266. const char * path = info.graphPath;
  267. if (value || alwaysAdd)
  268. {
  269. if (path[0] == '@')
  270. tgt.setPropBool(path, value);
  271. else
  272. addGraphAttribute(&tgt, info.childPath)->setPropBool("@value", value);
  273. }
  274. }
  275. void setAttributeValueInt(IPropertyTree & tgt, WuAttr kind, __int64 value)
  276. {
  277. const WuAttrInfo & info = attrInfo[kind-WaNone];
  278. const char * path = info.graphPath;
  279. if (path[0] == '@')
  280. tgt.setPropInt64(path, value);
  281. else
  282. addGraphAttribute(&tgt, info.childPath)->setPropInt64("@value", value);
  283. }
  284. bool isListAttribute(WuAttr kind)
  285. {
  286. const WuAttrInfo & info = attrInfo[kind-WaNone];
  287. return (info.multiKind != WaNone) && (info.multiKind == kind);
  288. }
  289. bool isMultiAttribute(WuAttr kind)
  290. {
  291. const WuAttrInfo & info = attrInfo[kind-WaNone];
  292. return (info.singleKind != WaNone) && (info.singleKind == kind);
  293. }
  294. WuAttr getListAttribute(WuAttr kind)
  295. {
  296. const WuAttrInfo & info = attrInfo[kind-WaNone];
  297. WuAttr multiKind = info.multiKind;
  298. return (multiKind != WaNone) && (multiKind != kind) ? multiKind : WaNone;
  299. }
  300. WuAttr getSingleKindOfListAttribute(WuAttr kind)
  301. {
  302. const WuAttrInfo & info = attrInfo[kind-WaNone];
  303. return info.singleKind;
  304. }