123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "wuattr.hpp"
- #include "jptree.hpp"
- #include "jstats.h"
- struct WuAttrInfo
- {
- public:
- WuAttr kind; // The attribute enumeration
- StatisticMeasure measure; // units for the measure
- const char * name; // text version of the attribute
- const char * graphPath; // The xpath required to extract a result from a graph node.
- const char * overridePath; // Alternative xpath to check 1st for some overloaded attributes
- const char * childPath; // The name of the <atr> for setting, or matching when iterating
- const char * dft; // default value if not present
- WuAttr singleKind;
- WuAttr multiKind;
- };
- #define CHILDPATH(x) "att[@name='" x "']/@value"
- #define CHILDMPATH(x) "att[@name='" x "'][1]/@value"
- #define ATTR(kind, measure, path) { Wa ## kind, measure, #kind, path, nullptr, nullptr, nullptr, WaNone, WaNone }
- #define ALTATTR(kind, measure, path, alt) { Wa ## kind, measure, #kind, path, alt, nullptr, nullptr, WaNone, WaNone }
- #define CHILD(kind, measure, path) { Wa ## kind, measure, #kind, CHILDPATH(path), nullptr, path, nullptr, WaNone, WaNone }
- #define CHILD_MULTI(kind, measure, path) { Wa ## kind, measure, #kind, CHILDMPATH(path), nullptr, path, nullptr, Wa ## kind, Wa ## kind ## List }
- #define CHILD_LIST(kind, measure) { Wa ## kind ## List, measure, #kind "List", nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
- #define CHILD_D(kind, measure, path, dft) { Wa ## kind, measure, #kind, CHILDPATH(path), nullptr, path, dft, WaNone, WaNone }
- #define ATTRX(kind, measure) { Wa ## kind, measure, #kind, nullptr, nullptr, nullptr, nullptr, WaNone, WaNone }
- #define ATTRX_MULTI(kind, measure) { Wa ## kind , measure, #kind, nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
- #define ATTRX_LIST(kind, measure) { Wa ## kind ## List, measure, #kind "List", nullptr, nullptr, nullptr, nullptr, Wa ## kind, Wa ## kind ## List }
- const static WuAttrInfo attrInfo[] = {
- { WaNone, SMeasureNone, "none", nullptr, nullptr, nullptr, nullptr, WaNone, WaNone },
- { WaAll, SMeasureNone, "all", nullptr, nullptr, nullptr, nullptr, WaNone, WaNone },
- CHILD(Kind, SMeasureEnum, "_kind"),
- ALTATTR(IdSource, SMeasureId, "@source", "att[@name='_sourceActivity']/@value"),
- ALTATTR(IdTarget, SMeasureId, "@target", "att[@name='_targetActivity']/@value"),
- CHILD_D(SourceIndex, SMeasureText, "_sourceIndex", "0"),
- CHILD_D(TargetIndex, SMeasureText, "_targetIndex", "0"),
- ATTR(Label, SMeasureText, "@label"),
- CHILD(IsDependency, SMeasureBool, "_dependsOn"),
- CHILD(IsChildGraph, SMeasureBool, "_childGraph"),
- CHILD_MULTI(Definition, SMeasureText, "definition"),
- CHILD_LIST(Definition, SMeasureText),
- CHILD_MULTI(EclName, SMeasureText, "name"),
- CHILD_LIST(EclName, SMeasureText),
- CHILD(EclText, SMeasureText, "ecl"),
- CHILD(RecordSize, SMeasureText, "recordSize"),
- CHILD(PredictedCount, SMeasureText, "predictedCount"),
- CHILD(IsGrouped, SMeasureBool, "grouped"),
- CHILD(IsLocal, SMeasureBool, "local"),
- CHILD(IsCoLocal, SMeasureBool, "coLocal"),
- CHILD(IsOrdered, SMeasureBool, "ordered"),
- CHILD(IsInternal, SMeasureBool, "_internal"),
- CHILD(IsNoAccess, SMeasureBool, "noAccess"),
- CHILD(IsGraphIndependent, SMeasureBool, "_graphIndependent"),
- CHILD(IsUpdateIfChanged, SMeasureBool, "_updateIfChanged"),
- CHILD(IsKeyed, SMeasureBool, "_isKeyed"),
- CHILD(IsPreload, SMeasureBool, "preload"),
- CHILD(IsDiskAccessRequired, SMeasureBool, "_diskAccessRequired"),
- CHILD(IsFileOpt, SMeasureBool, "_isOpt"),
- CHILD(IsIndexOpt, SMeasureBool, "_isIndexOpt"),
- CHILD(IsPatchOpt, SMeasureBool, "_isPatchOpt"),
- CHILD(Filename, SMeasureFilename, "_fileName"),
- CHILD(Indexname, SMeasureFilename, "_indexFileName"),
- CHILD(PatchFilename, SMeasureFilename, "_patchName"),
- CHILD(IsFilenameDynamic, SMeasureBool, "_file_dynamic"),
- CHILD(IsIndexnameDynamic, SMeasureBool, "_indexFile_dynamic"),
- CHILD(IsPatchFilenameDynamic, SMeasureBool, "_patch_dynamic"),
- CHILD(IsEmbedded, SMeasureBool, "embedded"),
- CHILD(IsSpill, SMeasureBool, "_isSpill"),
- CHILD(IsGlobalSpill, SMeasureBool, "_isSpillGlobal"),
- CHILD(IsAccessedFromChild, SMeasureBool, "_fromChild"),
- CHILD(IsTransformSpill, SMeasureBool, "_isTransformSpill"),
- CHILD(OriginalFilename, SMeasureFilename, "_originalName"),
- CHILD(OutputFilename, SMeasureFilename, "_outputName"),
- CHILD(UpdatedFilename, SMeasureFilename, "_updatedName"),
- CHILD(DistributeIndexname, SMeasureFilename, "_distributeIndexName"),
- CHILD(IsOriginalFilenameDynamic, SMeasureBool, "_originalName_dynamic"),
- CHILD(IsOutputFilenameDynamic, SMeasureBool, "_outputName_dynamic"),
- CHILD(IsUpdatedFilenameDynamic, SMeasureBool, "_updatedName_dynamic"),
- CHILD(IsDistributeIndexnameDynamic, SMeasureBool, "_distributeIndexName_dynamic"),
- CHILD(SignedBy, SMeasureText, "signedBy"),
- CHILD(MetaDistribution, SMeasureText, "metaDistribution"),
- CHILD(MetaGrouping, SMeasureText, "metaGrouping"),
- CHILD(MetaGlobalSortOrder, SMeasureText, "metaGlobalSortOrder"),
- CHILD(MetaLocalSortOrder, SMeasureText, "metaLocalSortOrder"),
- CHILD(MetaGroupSortOrder, SMeasureText, "metaGroupSortOrder"),
- CHILD_MULTI(Section, SMeasureText, "section"),
- CHILD_LIST(Section, SMeasureText),
- CHILD(LibraryName, SMeasureText, "libname"),
- CHILD(MatchLikelihood, SMeasureText, "matchLikelihood"),
- CHILD(SpillReason, SMeasureText, "spillReason"),
- CHILD(NumChildQueries, SMeasureCount, "childQueries"),
- CHILD(SizeClassApprox, SMeasureSize, "approxClassSize"),
- CHILD(IdParentActivity, SMeasureId, "_parentActivity"),
- CHILD(NumParallel, SMeasureCount, "parallel"),
- CHILD(Algorithm, SMeasureText, "algorithm"),
- CHILD(SizePreload, SMeasureSize, "_preloadSize"),
- CHILD(IdLoop, SMeasureId, "_loopid"),
- CHILD(IdSubGraph, SMeasureId, "_subgraph"),
- CHILD(IdGraph, SMeasureId, "graph"),
- CHILD(IdChildGraph, SMeasureId, "_graphId"),
- CHILD(IdAmbiguousGraph, SMeasureId, "_graphid"),
- CHILD(IdLibraryGraph, SMeasureId, "_libraryGraphId"),
- CHILD(IdRemoteSubGraph, SMeasureId, "_remoteSubGraph"),
- CHILD(InterfaceHash, SMeasureText, "_interfaceHash"),
- CHILD(NumMaxOutputs, SMeasureCount, "_maxOutputs"),
- CHILD(IsRootGraph, SMeasureBool, "rootGraph"),
- ATTR(IsNWay, SMeasureBool, "@nWay"),
- CHILD(IsCosort, SMeasureBool, "cosort"),
- CHILD(NumGlobalUses, SMeasureCount, "_globalUsageCount"),
- ATTR(IsMultiInstance, SMeasureBool, "@multiInstance"),
- ATTR(IsDelayed, SMeasureBool, "@delayed"),
- ATTR(IsChild, SMeasureBool, "@child"),
- ATTR(IsSequential, SMeasureBool, "@sequential"),
- ATTR(IsLoopBody, SMeasureBool, "@loopBody"),
- CHILD(NumResults, SMeasureCount, "_numResults"),
- CHILD(WhenIndex, SMeasureText, "_when"),
- ATTRX_MULTI(IdDependency, SMeasureId),
- ATTRX_LIST(IdDependency, SMeasureId),
- ATTRX(IsScheduled, SMeasureBool),
- ATTRX(IdSuccess, SMeasureId),
- ATTRX(IdFailure, SMeasureId),
- ATTRX(IdRecovery, SMeasureId),
- ATTRX(IdPersist, SMeasureId),
- ATTRX(IdScheduled, SMeasureId),
- ATTRX(PersistName, SMeasureText),
- ATTRX(Type, SMeasureText),
- ATTRX(Mode, SMeasureText),
- ATTRX(State, SMeasureText),
- ATTRX(Cluster, SMeasureText),
- ATTRX(CriticalSection, SMeasureText),
- CHILD(DiskFormat, SMeasureText, "diskFormat"),
- CHILD(RecordFormat, SMeasureText, "recordFormat"),
- { WaMax, SMeasureNone, nullptr, nullptr, nullptr, nullptr, nullptr, WaNone, WaNone }
- };
- static MapConstStringTo<WuAttr, WuAttr> nameToWa(true); // Names are case insensitive
- static MapConstStringTo<WuAttr, WuAttr> graphAttrToWa(false); // paths and attrs are cases sensitive
- static MapConstStringTo<WuAttr, WuAttr> childAttrToWa(false);
- MODULE_INIT(INIT_PRIORITY_STANDARD)
- {
- static_assert(_elements_in(attrInfo) >= (WaMax-WaNone)+1, "Elements missing from attrInfo[]");
- static_assert(_elements_in(attrInfo) <= (WaMax-WaNone)+1, "Extra elements in attrInfo[]");
- for (unsigned i=0; i < _elements_in(attrInfo); i++)
- {
- const WuAttrInfo & info = attrInfo[i];
- WuAttr attr = (WuAttr)(WaNone + i);
- assertex(info.kind == attr);
- if (info.name)
- nameToWa.setValue(info.name, attr); // cannot clash since derived from a unique name
- #ifdef _DEBUG
- const char * prefix = queryMeasurePrefix(info.measure);
- if (info.name && prefix && *prefix)
- {
- if (!startsWith(info.name, prefix))
- printf("Mismatched prefix %s %s\n", info.name, prefix);
- }
- #endif
- const char * path = info.graphPath;
- if (path && path[0] == '@')
- {
- if (graphAttrToWa.getValue(path+1))
- throwUnexpectedX("Duplicate Graph Attr");
- graphAttrToWa.setValue(path+1, attr);
- }
- const char * childPath = info.childPath;
- if (childPath)
- {
- if (childAttrToWa.getValue(childPath))
- throwUnexpectedX("Duplicate Child Attr");
- childAttrToWa.setValue(childPath, attr);
- }
- }
- return true;
- }
- const char * queryWuAttributeName(WuAttr kind)
- {
- if ((kind >= WaNone) && (kind < WaMax))
- return attrInfo[kind-WaNone].name;
- return nullptr;
- }
- WuAttr queryWuAttribute(const char * kind, WuAttr dft)
- {
- WuAttr * match = nameToWa.getValue(kind);
- if (match)
- return *match;
- return dft;
- }
- extern WORKUNIT_API const char * queryAttributeValue(IPropertyTree & src, WuAttr kind, StringBuffer & scratchpad)
- {
- if ((kind <= WaNone) || (kind >= WaMax))
- return nullptr;
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- const char * path = info.graphPath;
- const char * altpath = info.overridePath;
- const char * value = altpath ? src.queryProp(altpath) : nullptr;
- if (!value)
- value = src.queryProp(path);
- if (!value && info.dft)
- value = info.dft;
- //The following switch statement allows the value returned to be transformed from the value stored.
- switch (kind)
- {
- case WaIdSource:
- case WaIdTarget:
- case WaIdParentActivity:
- value = scratchpad.clear().append(ActivityScopePrefix).append(value).str();
- break;
- case WaIdLibraryGraph:
- value = scratchpad.clear().append(GraphScopePrefix).append(value).str();
- break;
- // case WaIdLoop:
- //?Prefix with the graph id?
- //value = scratchpad.clear().append(ChildGraphScopePrefix).append(value).str();
- break;
- case WaIdLoop:
- case WaIdSubGraph:
- case WaIdRemoteSubGraph:
- value = scratchpad.clear().append(ChildGraphScopePrefix).append(value).str();
- break;
- }
- return value;
- }
- extern WORKUNIT_API WuAttr queryGraphAttrToWuAttr(const char * name)
- {
- WuAttr * match = graphAttrToWa.getValue(name);
- if (match)
- return *match;
- return WaNone;
- }
- extern WORKUNIT_API WuAttr queryGraphChildAttToWuAttr(const char * name)
- {
- WuAttr * match = childAttrToWa.getValue(name);
- if (match)
- return *match;
- return WaNone;
- }
- static IPropertyTree * addGraphAttribute(IPropertyTree * node, const char * name)
- {
- IPropertyTree * att = createPTree();
- att->setProp("@name", name);
- return node->addPropTree("att", att);
- }
- void setAttributeValue(IPropertyTree & tgt, WuAttr kind, const char * value)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- const char * path = info.graphPath;
- if (path[0] == '@')
- tgt.setProp(path, value);
- else
- addGraphAttribute(&tgt, info.childPath)->setProp("@value", value);
- }
- void setAttributeValueBool(IPropertyTree & tgt, WuAttr kind, bool value, bool alwaysAdd)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- const char * path = info.graphPath;
- if (value || alwaysAdd)
- {
- if (path[0] == '@')
- tgt.setPropBool(path, value);
- else
- addGraphAttribute(&tgt, info.childPath)->setPropBool("@value", value);
- }
- }
- void setAttributeValueInt(IPropertyTree & tgt, WuAttr kind, __int64 value)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- const char * path = info.graphPath;
- if (path[0] == '@')
- tgt.setPropInt64(path, value);
- else
- addGraphAttribute(&tgt, info.childPath)->setPropInt64("@value", value);
- }
- bool isListAttribute(WuAttr kind)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- return (info.multiKind != WaNone) && (info.multiKind == kind);
- }
- bool isMultiAttribute(WuAttr kind)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- return (info.singleKind != WaNone) && (info.singleKind == kind);
- }
- WuAttr getListAttribute(WuAttr kind)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- WuAttr multiKind = info.multiKind;
- return (multiKind != WaNone) && (multiKind != kind) ? multiKind : WaNone;
- }
- WuAttr getSingleKindOfListAttribute(WuAttr kind)
- {
- const WuAttrInfo & info = attrInfo[kind-WaNone];
- return info.singleKind;
- }
|