configmgr/source/access.cxx | 81 ++++++++++++++++++++++++++++---------------- configmgr/source/access.hxx | 3 + 2 files changed, 55 insertions(+), 29 deletions(-)
New commits: commit 300763ddf666b8f2e428231ffa892ecd4efb2eae Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Oct 31 15:54:18 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Oct 31 18:10:30 2023 +0100 reduce reference counting traffic in configmgr no need to construct a vector when iterating over children Change-Id: I717e92be3c576a6e5d877f4333264a5bed9daadf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158728 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx index 46657374030a..4bb66cb5f025 100644 --- a/configmgr/source/access.cxx +++ b/configmgr/source/access.cxx @@ -354,7 +354,7 @@ sal_Bool Access::hasElements() { assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - return !getAllChildren().empty(); //TODO: optimize + return !isAllChildrenEmpty(); } bool Access::getByNameFast(const OUString & name, css::uno::Any & value) @@ -410,14 +410,13 @@ css::uno::Sequence< OUString > Access::getElementNames() assert(thisIs(IS_ANY)); osl::MutexGuard g(*lock_); checkLocalizedPropertyAccess(); - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); - css::uno::Sequence<OUString> names(children.size()); - OUString* pArray = names.getArray(); - for (auto const& child : children) + std::vector<OUString> childNames; + forAllChildren([&childNames] (ChildAccess& rChild) { - *pArray++ = child->getNameInternal(); - } - return names; + childNames.push_back(rChild.getNameInternal()); + return true; + }); + return comphelper::containerToSequence(childNames); } sal_Bool Access::hasByName(OUString const & aName) @@ -537,13 +536,12 @@ css::uno::Sequence< css::beans::Property > Access::getProperties() { assert(thisIs(IS_GROUP)); osl::MutexGuard g(*lock_); - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); std::vector< css::beans::Property > properties; - properties.reserve(children.size()); - for (auto const& child : children) + forAllChildren([&properties] (ChildAccess& rChild) { - properties.push_back(child->asProperty()); - } + properties.push_back(rChild.asProperty()); + return true; + }); return comphelper::containerToSequence(properties); } @@ -1423,19 +1421,22 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { locale = locale.copy(0, i); } assert(!locale.isEmpty()); - std::vector< rtl::Reference< ChildAccess > > children( - getAllChildren()); - for (auto const& child : children) + rtl::Reference< ChildAccess > foundChild; + forAllChildren([&foundChild, &locale] (ChildAccess& rChild) { - const OUString & name2(child->getNameInternal()); + const OUString & name2(rChild.getNameInternal()); if (name2.startsWith(locale) && (name2.getLength() == locale.getLength() || name2[locale.getLength()] == '-' || name2[locale.getLength()] == '_')) { - return child; + foundChild = &rChild; + return false; } - } + return true; + }); + if (foundChild) + return foundChild; } // Defaults are the "en-US" locale, the "en" locale, the empty string locale, the first child (if // any, and if the property is non-nillable), or a null ChildAccess, in that order: @@ -1452,9 +1453,15 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { return child; } if (!static_cast<LocalizedPropertyNode *>(getNode().get())->isNillable()) { - std::vector< rtl::Reference< ChildAccess > > children(getAllChildren()); - if (!children.empty()) { - return children.front(); + // look for first child in list + rtl::Reference< ChildAccess > foundChild; + forAllChildren([&foundChild] (ChildAccess& rChild) + { + foundChild = &rChild; + return false; + }); + if (foundChild) { + return foundChild; } } return rtl::Reference< ChildAccess >(); @@ -1464,14 +1471,14 @@ rtl::Reference< ChildAccess > Access::getChild(OUString const & name) { ? getUnmodifiedChild(name) : getModifiedChild(i); } -std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() { - std::vector< rtl::Reference< ChildAccess > > vec; +void Access::forAllChildren(const std::function<bool(ChildAccess&)> & func) { NodeMap const & members = getNode()->getMembers(); for (auto const& member : members) { if (modifiedChildren_.find(member.first) == modifiedChildren_.end()) { - vec.push_back(getUnmodifiedChild(member.first)); - assert(vec.back().is()); + bool bContinue = func(*getUnmodifiedChild(member.first)); + if (!bContinue) + return; } } for (ModifiedChildren::iterator i(modifiedChildren_.begin()); @@ -1479,10 +1486,28 @@ std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() { { rtl::Reference< ChildAccess > child(getModifiedChild(i)); if (child.is()) { - vec.push_back(child); + bool bContinue = func(*child); + if (!bContinue) + return; } } - return vec; +} + +bool Access::isAllChildrenEmpty() { + NodeMap const & members = getNode()->getMembers(); + for (auto const& member : members) + { + if (modifiedChildren_.find(member.first) == modifiedChildren_.end()) + return false; + } + for (ModifiedChildren::iterator i(modifiedChildren_.begin()); + i != modifiedChildren_.end(); ++i) + { + rtl::Reference< ChildAccess > child(getModifiedChild(i)); + if (child.is()) + return false; + } + return true; } void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) { diff --git a/configmgr/source/access.hxx b/configmgr/source/access.hxx index 51e43d5bcfcc..7b59e81cfdc8 100644 --- a/configmgr/source/access.hxx +++ b/configmgr/source/access.hxx @@ -323,7 +323,8 @@ protected: rtl::Reference< Node > getParentNode(); rtl::Reference< ChildAccess > getChild(OUString const & name); - std::vector< rtl::Reference< ChildAccess > > getAllChildren(); + void forAllChildren(const std::function<bool(ChildAccess&)> & f); + bool isAllChildrenEmpty(); void checkValue( css::uno::Any const & value, Type type, bool nillable);