Browse Source

HPCC-25101 Clean up some IPropertyTree interfaces

also

* optimize a couple of functions
* always copy the value of an element when merging
* ensure first item in a list is processed as a list element

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 4 years ago
parent
commit
1d4def0647
3 changed files with 27 additions and 23 deletions
  1. 17 13
      system/jlib/jptree.cpp
  2. 6 6
      system/jlib/jptree.hpp
  3. 4 4
      system/jlib/jptree.ipp

+ 17 - 13
system/jlib/jptree.cpp

@@ -234,7 +234,7 @@ unsigned ChildMap::getHashFromElement(const void *e) const
     return elem.queryHash();
 }
 
-unsigned ChildMap::numChildren()
+unsigned ChildMap::numChildren() const
 {
     SuperHashIteratorOf<IPropertyTree> iter(*this);
     if (!iter.first()) return 0;
@@ -2706,13 +2706,13 @@ void PTree::localizeElements(const char *xpath, bool allTail)
     // null action for local ptree
 }
 
-unsigned PTree::numChildren()
+unsigned PTree::numChildren() const
 {
     if (!checkChildren()) return 0;
     return children->numChildren();
 }
 
-unsigned PTree::getCount(const char *xpath)
+unsigned PTree::getCount(const char *xpath) const
 {
     unsigned c=0;
     Owned<IPropertyTreeIterator> iter = getElements(xpath);
@@ -3132,6 +3132,7 @@ void PTree::addLocal(size32_t l, const void *data, bool _binary, int pos)
         IPropertyTree *element1 = detach();
         array = new CPTArray();
         addingNewElement(*element1, ANE_APPEND);
+        static_cast<PTree *>(element1)->setOwner(array);
         array->addElement(element1);
         value = array;
     }
@@ -3857,7 +3858,7 @@ bool CAtomPTree::removeAttribute(const char *key)
 ///////////////////
 
 
-bool isEmptyPTree(IPropertyTree *t)
+bool isEmptyPTree(const IPropertyTree *t)
 {
     if (!t)
         return true;
@@ -4273,12 +4274,15 @@ void mergePTree(IPropertyTree *target, IPropertyTree *toMerge)
     }
 }
 
-void _synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool removeTargetsNotInSource)
+void _synchronizePTree(IPropertyTree *target, const IPropertyTree *source, bool removeTargetsNotInSource)
 {
     Owned<IAttributeIterator> aiter = target->getAttributes();
     StringArray targetAttrs;
-    ForEach (*aiter)
-        targetAttrs.append(aiter->queryName());
+    if (removeTargetsNotInSource)
+    {
+        ForEach (*aiter)
+            targetAttrs.append(aiter->queryName());
+    }
 
     aiter.setown(source->getAttributes());
     ForEach (*aiter)
@@ -4298,7 +4302,8 @@ void _synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool remove
             else if (NULL == tValue ||0 != strcmp(sValue, tValue))
                 target->setProp(attr, sValue);
 
-            targetAttrs.zap(attr);
+            if (removeTargetsNotInSource)
+                targetAttrs.zap(attr);
         }
     }
 
@@ -4409,7 +4414,7 @@ void _synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool remove
  * presevers ordering of matching elements.
  * If removeTargetsNotInSource = true (default) elements in the target not present in the source will be removed
  */
-void synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool removeTargetsNotInSource, bool rootsMustMatch)
+void synchronizePTree(IPropertyTree *target, const IPropertyTree *source, bool removeTargetsNotInSource, bool rootsMustMatch)
 {
     if (rootsMustMatch)
     {
@@ -6956,7 +6961,7 @@ class COrderedPTree : public BASE_PTREE
         COrderedChildMap<BASECHILDMAP>() : BASECHILDMAP() { }
         ~COrderedChildMap<BASECHILDMAP>() { SELF::kill(); }
 
-        virtual unsigned numChildren() override { return order.ordinality(); }
+        virtual unsigned numChildren() const override { return order.ordinality(); }
         virtual IPropertyTreeIterator *getIterator(bool sort) override
         {
             class CPTArrayIterator : public ArrayIIteratorOf<IArrayOf<IPropertyTree>, IPropertyTree, IPropertyTreeIterator>
@@ -8244,7 +8249,7 @@ static IPropertyTree *ensureMergeConfigTarget(IPropertyTree &target, const char
     return match;
 }
 
-void mergeConfiguration(IPropertyTree & target, IPropertyTree & source, const char *altNameAttribute, bool overwriteAttr)
+void mergeConfiguration(IPropertyTree & target, const IPropertyTree & source, const char *altNameAttribute, bool overwriteAttr)
 {
     Owned<IAttributeIterator> aiter = source.getAttributes();
     ForEach(*aiter)
@@ -8280,8 +8285,7 @@ void mergeConfiguration(IPropertyTree & target, IPropertyTree & source, const ch
     }
 
     const char * sourceValue = source.queryProp("");
-    if (sourceValue)
-        target.setProp("", sourceValue);
+    target.setProp("", sourceValue);
 }
 
 /*

+ 6 - 6
system/jlib/jptree.hpp

@@ -122,12 +122,12 @@ interface jlib_decl IPropertyTree : extends serializable
     virtual IPropertyTree *getBranch(const char *xpath) const = 0;
     virtual IPropertyTree *queryBranch(const char *xpath) const = 0;
     virtual bool hasChildren() const = 0;
-    virtual unsigned numUniq() = 0;
-    virtual unsigned numChildren() = 0;
+    virtual unsigned numUniq() const = 0;
+    virtual unsigned numChildren() const = 0;
     virtual bool isCaseInsensitive() const = 0;
     virtual bool IsShared() const = 0;
     virtual void localizeElements(const char *xpath, bool allTail=false) = 0;
-    virtual unsigned getCount(const char *xpath) = 0;
+    virtual unsigned getCount(const char *xpath) const = 0;
     virtual IPropertyTree *addPropTreeArrayItem(const char *xpath, IPropertyTree *val) = 0;
     virtual bool isArray(const char *xpath=NULL) const = 0;
     virtual unsigned getAttributeCount() const = 0;
@@ -214,7 +214,7 @@ jlib_decl IPullPTreeReader *createPullJSONStringReader(const char *json, IPTreeN
 jlib_decl IPullPTreeReader *createPullJSONBufferReader(const void *buf, size32_t bufLength, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace);
 
 jlib_decl void mergePTree(IPropertyTree *target, IPropertyTree *toMerge);
-jlib_decl void synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool removeTargetsNotInSource=true, bool rootsMustMatch=true);
+jlib_decl void synchronizePTree(IPropertyTree *target, const IPropertyTree *source, bool removeTargetsNotInSource=true, bool rootsMustMatch=true);
 jlib_decl IPropertyTree *ensurePTree(IPropertyTree *root, const char *xpath);
 jlib_decl bool areMatchingPTrees(const IPropertyTree * left, const IPropertyTree * right);
 
@@ -277,7 +277,7 @@ jlib_decl bool validateXPathSyntax(const char *xpath, StringBuffer *error=NULL);
 jlib_decl bool validateXMLParseXPath(const char *xpath, StringBuffer *error=NULL);
 jlib_decl IPropertyTree *getXPathMatchTree(IPropertyTree &parent, const char *xpath);
 jlib_decl IPropertyTreeIterator *createNullPTreeIterator();
-jlib_decl bool isEmptyPTree(IPropertyTree *t);
+jlib_decl bool isEmptyPTree(const IPropertyTree *t);
 
 jlib_decl void extractJavadoc(IPropertyTree * result, const char * text);       // Pass in a javadoc style comment (without head/tail) and extract information into a property tree.
 
@@ -299,7 +299,7 @@ inline static bool isValidXPathChr(char c)
 }
 
 //export for unit test
-jlib_decl void mergeConfiguration(IPropertyTree & target, IPropertyTree & source, const char *altNameAttribute=nullptr, bool overwriteAttr=true);
+jlib_decl void mergeConfiguration(IPropertyTree & target, const IPropertyTree & source, const char *altNameAttribute=nullptr, bool overwriteAttr=true);
 
 jlib_decl IPropertyTree * loadArgsIntoConfiguration(IPropertyTree *config, const char * * argv, std::initializer_list<const char *> ignoreOptions = {});
 jlib_decl IPropertyTree * loadConfiguration(IPropertyTree * defaultConfig, const char * * argv, const char * componentTag, const char * envPrefix, const char * legacyFilename, IPropertyTree * (mapper)(IPropertyTree *), const char *altNameAttribute=nullptr);

+ 4 - 4
system/jlib/jptree.ipp

@@ -81,7 +81,7 @@ public:
     { 
         _releaseAll();
     }
-    virtual unsigned numChildren();
+    virtual unsigned numChildren() const;
     virtual IPropertyTreeIterator *getIterator(bool sort);
     virtual bool set(const char *key, IPropertyTree *tree)
     {
@@ -672,10 +672,10 @@ public:
     virtual IPropertyTreeIterator *getElements(const char *xpath, IPTIteratorCodes flags = iptiter_null) const override;
     virtual void localizeElements(const char *xpath, bool allTail=false) override;
     virtual bool hasChildren() const override { return children && children->count()?true:false; }
-    virtual unsigned numUniq() override { return checkChildren()?children->count():0; }
-    virtual unsigned numChildren() override;
+    virtual unsigned numUniq() const override { return checkChildren()?children->count():0; }
+    virtual unsigned numChildren() const override;
     virtual bool isCaseInsensitive() const override { return isnocase(); }
-    virtual unsigned getCount(const char *xpath) override;
+    virtual unsigned getCount(const char *xpath) const override;
     virtual IPropertyTree *addPropTreeArrayItem(const char *xpath, IPropertyTree *val) override;
     virtual bool isArray(const char *xpath=NULL) const override;
     virtual unsigned getAttributeCount() const override;