Kaydet (Commit) 879aa54e authored tarafından Michael Meeks's avatar Michael Meeks

configmgr: accelerate simple config key fetches.

Avoid heap allocating UNO object wrappers for the underlying Node
structures only to convert to Any and immediately free them agian
when we can.

Change-Id: Iae4612e9602f872f5d8cca2e516df594c9f1118c
üst e820df57
...@@ -344,6 +344,42 @@ sal_Bool Access::hasElements() throw (css::uno::RuntimeException, std::exception ...@@ -344,6 +344,42 @@ sal_Bool Access::hasElements() throw (css::uno::RuntimeException, std::exception
return !getAllChildren().empty(); //TODO: optimize return !getAllChildren().empty(); //TODO: optimize
} }
bool Access::getByNameFast(const OUString & name, css::uno::Any & value)
{
bool bGotValue = false;
rtl::Reference< ChildAccess > child;
if (getNode()->kind() != Node::KIND_LOCALIZED_PROPERTY)
{ // try to get it directly
ModifiedChildren::iterator i(modifiedChildren_.find(name));
if (i != modifiedChildren_.end())
{
child = getModifiedChild(i);
if (child.is())
{
value = child->asValue();
bGotValue = true;
}
}
else
{
rtl::Reference< Node > node(getNode()->getMember(name));
if (!node.is())
return false;
bGotValue = ChildAccess::asSimpleValue(node, value, components_);
}
}
if (!bGotValue)
{
child = getChild(name);
if (!child.is())
return false;
value = child->asValue();
}
return true;
}
css::uno::Any Access::getByName(OUString const & aName) css::uno::Any Access::getByName(OUString const & aName)
throw ( throw (
css::container::NoSuchElementException, css::container::NoSuchElementException,
...@@ -352,12 +388,11 @@ css::uno::Any Access::getByName(OUString const & aName) ...@@ -352,12 +388,11 @@ css::uno::Any Access::getByName(OUString const & aName)
assert(thisIs(IS_ANY)); assert(thisIs(IS_ANY));
osl::MutexGuard g(*lock_); osl::MutexGuard g(*lock_);
checkLocalizedPropertyAccess(); checkLocalizedPropertyAccess();
rtl::Reference< ChildAccess > child(getChild(aName)); css::uno::Any value;
if (!child.is()) { if (!getByNameFast(aName, value))
throw css::container::NoSuchElementException( throw css::container::NoSuchElementException(
aName, static_cast< cppu::OWeakObject * >(this)); aName, static_cast< cppu::OWeakObject * >(this));
} return value;
return child->asValue();
} }
css::uno::Sequence< OUString > Access::getElementNames() css::uno::Sequence< OUString > Access::getElementNames()
...@@ -852,15 +887,15 @@ css::uno::Sequence< css::uno::Any > Access::getPropertyValues( ...@@ -852,15 +887,15 @@ css::uno::Sequence< css::uno::Any > Access::getPropertyValues(
assert(thisIs(IS_GROUP)); assert(thisIs(IS_GROUP));
osl::MutexGuard g(*lock_); osl::MutexGuard g(*lock_);
css::uno::Sequence< css::uno::Any > vals(aPropertyNames.getLength()); css::uno::Sequence< css::uno::Any > vals(aPropertyNames.getLength());
for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i) {
rtl::Reference< ChildAccess > child(getChild(aPropertyNames[i])); for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i)
if (!child.is()) { {
if (!getByNameFast(aPropertyNames[i], vals[i]))
throw css::uno::RuntimeException( throw css::uno::RuntimeException(
"configmgr getPropertyValues inappropriate property name", "configmgr getPropertyValues inappropriate property name",
static_cast< cppu::OWeakObject * >(this)); static_cast< cppu::OWeakObject * >(this));
}
vals[i] = child->asValue();
} }
return vals; return vals;
} }
...@@ -1988,6 +2023,15 @@ rtl::Reference< ChildAccess > Access::getModifiedChild( ...@@ -1988,6 +2023,15 @@ rtl::Reference< ChildAccess > Access::getModifiedChild(
? childIterator->second.child : rtl::Reference< ChildAccess >(); ? childIterator->second.child : rtl::Reference< ChildAccess >();
} }
rtl::Reference< ChildAccess > Access::createUnmodifiedChild(
const OUString &name, const rtl::Reference< Node > &node)
{
rtl::Reference< ChildAccess > child(
new ChildAccess(components_, getRootAccess(), this, name, node));
cachedChildren_[name] = child.get();
return child;
}
rtl::Reference< ChildAccess > Access::getUnmodifiedChild( rtl::Reference< ChildAccess > Access::getUnmodifiedChild(
OUString const & name) OUString const & name)
{ {
...@@ -2008,10 +2052,7 @@ rtl::Reference< ChildAccess > Access::getUnmodifiedChild( ...@@ -2008,10 +2052,7 @@ rtl::Reference< ChildAccess > Access::getUnmodifiedChild(
return child; return child;
} }
} }
rtl::Reference< ChildAccess > child( return createUnmodifiedChild(name,node);
new ChildAccess(components_, getRootAccess(), this, name, node));
cachedChildren_[name] = child.get();
return child;
} }
rtl::Reference< ChildAccess > Access::getSubChild(OUString const & path) { rtl::Reference< ChildAccess > Access::getSubChild(OUString const & path) {
......
...@@ -497,10 +497,14 @@ private: ...@@ -497,10 +497,14 @@ private:
rtl::Reference< ChildAccess > getSubChild(OUString const & path); rtl::Reference< ChildAccess > getSubChild(OUString const & path);
bool setChildProperty( bool setChildProperty(
OUString const & name, com::sun::star::uno::Any const & value, OUString const & name, css::uno::Any const & value,
Modifications * localModifications); Modifications * localModifications);
com::sun::star::beans::Property asProperty(); css::beans::Property asProperty();
bool getByNameFast(const OUString & name, css::uno::Any & value);
rtl::Reference< ChildAccess > createUnmodifiedChild(const OUString &name,
const rtl::Reference< Node > &node);
void checkFinalized(); void checkFinalized();
......
...@@ -252,33 +252,48 @@ void ChildAccess::setProperty( ...@@ -252,33 +252,48 @@ void ChildAccess::setProperty(
localModifications->add(getRelativePath()); localModifications->add(getRelativePath());
} }
css::uno::Any ChildAccess::asValue() {
css::uno::Any ChildAccess::asValue()
{
if (changedValue_.get() != 0) { if (changedValue_.get() != 0) {
return *changedValue_; return *changedValue_;
} }
switch (node_->kind()) { css::uno::Any value;
case Node::KIND_PROPERTY: if (!asSimpleValue(node_, value, getComponents()))
return static_cast< PropertyNode * >(node_.get())->getValue( {
getComponents()); if (node_->kind() == Node::KIND_LOCALIZED_PROPERTY)
case Node::KIND_LOCALIZED_PROPERTY:
{ {
OUString locale(getRootAccess()->getLocale()); OUString locale(getRootAccess()->getLocale());
if (!Components::allLocales(locale)) { if (!Components::allLocales(locale)) {
rtl::Reference< ChildAccess > child(getChild("*" + locale)); rtl::Reference< ChildAccess > child(getChild("*" + locale));
// As a last resort, return a nil value even though it may be // As a last resort, return a nil value even though it may be
// illegal for the given property: // illegal for the given property:
return child.is() ? child->asValue() : css::uno::Any(); if (child.is())
return child->asValue();
} }
} }
break; value = css::uno::makeAny(
css::uno::Reference< css::uno::XInterface >(
static_cast< cppu::OWeakObject * >(this)));
}
return value;
}
/// Can we quickly extract a simple value into value ? if so returns true
bool ChildAccess::asSimpleValue(const rtl::Reference< Node > &rNode,
css::uno::Any &value,
Components &components)
{
switch (rNode->kind()) {
case Node::KIND_PROPERTY:
value = static_cast< PropertyNode * >(rNode.get())->getValue(components);
return true;
case Node::KIND_LOCALIZED_VALUE: case Node::KIND_LOCALIZED_VALUE:
return static_cast< LocalizedValueNode * >(node_.get())->getValue(); value = static_cast< LocalizedValueNode * >(rNode.get())->getValue();
return true;
default: default:
break; return false;
} }
return css::uno::makeAny(
css::uno::Reference< css::uno::XInterface >(
static_cast< cppu::OWeakObject * >(this)));
} }
void ChildAccess::commitChanges(bool valid, Modifications * globalModifications) void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
......
...@@ -113,7 +113,10 @@ public: ...@@ -113,7 +113,10 @@ public:
com::sun::star::uno::Any const & value, com::sun::star::uno::Any const & value,
Modifications * localModifications); Modifications * localModifications);
com::sun::star::uno::Any asValue(); css::uno::Any asValue();
static bool asSimpleValue(const rtl::Reference< Node > &rNode,
css::uno::Any &value,
Components &components);
void commitChanges(bool valid, Modifications * globalModifications); void commitChanges(bool valid, Modifications * globalModifications);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment