diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-04-13 15:25:23 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-04-14 01:34:59 +0200 |
commit | 09524d410bbaad2a0b9b39811cb5cc16621b1396 (patch) | |
tree | 4f648522110b5f87ea6f357dd4a7501ac23e1ac8 /stoc/source/simpleregistry | |
parent | a871537f328711f02d3b5ba18612bbf25c6f563b (diff) |
stoc: accelerate opening of multiple XML .rdb files in a directory
Instead of nesting these, we aggregate them into a single non-nested
registry, which saves lots of CPU at startup, sadly we can only do
that for the new-style XML registries, so we have to sniff files,
nevertheless this is still far faster. The merged xml files also
break the XSimpleRegistry::getURL() method - but it appears not
to get called.
Diffstat (limited to 'stoc/source/simpleregistry')
-rw-r--r-- | stoc/source/simpleregistry/simpleregistry.cxx | 94 | ||||
-rw-r--r-- | stoc/source/simpleregistry/textualservices.cxx | 11 | ||||
-rw-r--r-- | stoc/source/simpleregistry/textualservices.hxx | 3 |
3 files changed, 92 insertions, 16 deletions
diff --git a/stoc/source/simpleregistry/simpleregistry.cxx b/stoc/source/simpleregistry/simpleregistry.cxx index f09b204e19fb..9eebb4f087a1 100644 --- a/stoc/source/simpleregistry/simpleregistry.cxx +++ b/stoc/source/simpleregistry/simpleregistry.cxx @@ -48,6 +48,7 @@ #include "cppuhelper/implbase2.hxx" #include "cppuhelper/weak.hxx" #include "osl/mutex.hxx" +#include "osl/file.hxx" #include "registry/registry.hxx" #include "registry/regtype.h" #include "rtl/ref.hxx" @@ -84,6 +85,12 @@ public: private: virtual rtl::OUString SAL_CALL getURL() throw (css::uno::RuntimeException); + virtual void SAL_CALL openRdb( + rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) + throw ( + css::registry::InvalidRegistryException, + css::uno::RuntimeException); + virtual void SAL_CALL open( rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) throw ( @@ -1130,27 +1137,17 @@ rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName) return resolved; } -rtl::OUString SimpleRegistry::getURL() throw (css::uno::RuntimeException) { +rtl::OUString SimpleRegistry::getURL() throw (css::uno::RuntimeException) +{ osl::MutexGuard guard(mutex_); return textual_.get() == 0 ? registry_.getName() : textual_->getUri(); } -void SimpleRegistry::open( +void SimpleRegistry::openRdb( rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) { osl::MutexGuard guard(mutex_); - if (textual_.get() != 0) { - throw css::registry::InvalidRegistryException( - (rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "com.sun.star.registry.SimpleRegistry.open(")) + - rURL + - rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( - "): instance already open"))), - static_cast< OWeakObject * >(this)); - } RegError err = (rURL.isEmpty() && bCreate) ? REG_REGISTRY_NOT_EXISTS : registry_.open(rURL, bReadOnly ? REG_READONLY : REG_READWRITE); @@ -1162,7 +1159,10 @@ void SimpleRegistry::open( break; case REG_INVALID_REGISTRY: if (bReadOnly && !bCreate) { - textual_.reset(new stoc::simpleregistry::TextualServices(rURL)); + if (!textual_.get()) + textual_.reset(new stoc::simpleregistry::TextualServices(rURL)); + else + textual_->merge(rURL); break; } // fall through @@ -1180,6 +1180,72 @@ void SimpleRegistry::open( } } +void SimpleRegistry::open( + rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate) + throw (css::registry::InvalidRegistryException, css::uno::RuntimeException) +{ + osl::MutexGuard guard(mutex_); + + osl::DirectoryItem aItem; + osl::FileBase::RC eErr; + osl::FileStatus aStatus(osl_FileStatus_Mask_Type); + + // FIXME: busts the 'create' mode ... + if ((eErr = osl::DirectoryItem::get( rURL, aItem )) != osl::FileBase::E_None || + (eErr = aItem.getFileStatus( aStatus )) != osl::FileBase::E_None || + !aStatus.isDirectory()) + { + if (textual_.get() != 0) + throw css::registry::InvalidRegistryException( + (rtl::OUString("com.sun.star.registry.SimpleRegistry.open(") + + rURL + rtl::OUString("): instance already open")), + static_cast< OWeakObject * >(this)); + openRdb (rURL, bReadOnly, bCreate); + } + else + { + osl::Directory dir(rURL); + eErr = dir.open(); + if (eErr != osl::FileBase::E_None) + goto err_throw; + + for (;;) { + osl::DirectoryItem i; + if (dir.getNextItem(i, SAL_MAX_UINT32) != osl::FileBase::E_None) + break; + osl::FileStatus stat(osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName | + osl_FileStatus_Mask_FileURL); + if (i.getFileStatus(stat) != osl::FileBase::E_None) + throw css::uno::RuntimeException( + (rtl::OUString("cannot stat in directory ") + rURL ), + css::uno::Reference< css::uno::XInterface >()); + + rtl::OUString aName = stat.getFileName(); + + // Ignore backup files - to allow people to edit their + // services/ without extremely confusing behaviour + if (aName.toChar() == '.' || aName.endsWithAsciiL("~", 1)) + continue; + + if (stat.getFileType() != osl::FileStatus::Directory) + openRdb(stat.getFileURL(), bReadOnly, bCreate); + } + } + return; + +err_throw: + throw css::registry::InvalidRegistryException( + (rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.registry.SimpleRegistry.open(")) + + rURL + + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "): error statting url = ")) + + rtl::OUString::valueOf(static_cast< sal_Int32 >(eErr))), + static_cast< OWeakObject * >(this)); +} + sal_Bool SimpleRegistry::isValid() throw (css::uno::RuntimeException) { osl::MutexGuard guard(mutex_); return textual_.get() != 0 || registry_.isValid(); diff --git a/stoc/source/simpleregistry/textualservices.cxx b/stoc/source/simpleregistry/textualservices.cxx index ad24a4454550..2491f55cb39b 100644 --- a/stoc/source/simpleregistry/textualservices.cxx +++ b/stoc/source/simpleregistry/textualservices.cxx @@ -1236,6 +1236,15 @@ css::uno::Sequence< rtl::OUString > Key::getChildren() { TextualServices::TextualServices(rtl::OUString const & uri): uri_(uri), data_(new Data) { + merge(uri); +} + +TextualServices::~TextualServices() {} + +// load and merge registry contents from uri +void TextualServices::merge(const rtl::OUString &uri) + throw (com::sun::star::registry::InvalidRegistryException) +{ try { Parser(uri, data_); } catch (css::container::NoSuchElementException &) { @@ -1247,8 +1256,6 @@ TextualServices::TextualServices(rtl::OUString const & uri): } } -TextualServices::~TextualServices() {} - css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey() { return new Key(data_, std::vector< rtl::OUString >()); diff --git a/stoc/source/simpleregistry/textualservices.hxx b/stoc/source/simpleregistry/textualservices.hxx index 286eb922a1b4..0341c15d5d34 100644 --- a/stoc/source/simpleregistry/textualservices.hxx +++ b/stoc/source/simpleregistry/textualservices.hxx @@ -53,6 +53,9 @@ public: virtual ~TextualServices(); + void merge(const rtl::OUString &uri) + throw (com::sun::star::registry::InvalidRegistryException); + inline rtl::OUString getUri() { return uri_; } com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey > |