Hi there, I lost your mail with the rather nice re-write you're working on there, but I attach a simple hack I've been working on instead.
The basic idea is to push the iteration over directories down into the stoc/ code instead of having it in the cppuhelper code. That lets us re-use the same representation avoiding the nesting[1]. I guess it is the moral equivalent of concatenating the .rdb files in a given directory. I split my services.rdb into three equally sized pieces to test it, and it appears to continue to work, and I get a substantially faster warm start to match. Debug-enabled patch attached, I'll clean up and push to master unless someone screams as a stop-gap primarily intended for 3.5.next :-) HTH, Michael. [1] - the nesting being something I still don't understand the purpose of ;-) -- michael.me...@suse.com <><, Pseudo Engineer, itinerant idiot
diff --git a/cppuhelper/source/bootstrap.cxx b/cppuhelper/source/bootstrap.cxx index 39e44fe..ea2e383 100644 --- a/cppuhelper/source/bootstrap.cxx +++ b/cppuhelper/source/bootstrap.cxx @@ -215,9 +215,11 @@ css::uno::Reference< css::registry::XSimpleRegistry > readRdbFile( css::uno::Reference< css::lang::XSingleServiceFactory > const & simpleRegistryFactory, css::uno::Reference< css::lang::XSingleServiceFactory > const & - nestedRegistryFactory) + nestedRegistryFactory, + bool isDirectory) { OSL_ASSERT(simpleRegistryFactory.is() && nestedRegistryFactory.is()); + fprintf(stderr, "new readRdbFile '%d'\n", isDirectory); try { css::uno::Reference< css::registry::XSimpleRegistry > simple( simpleRegistryFactory->createInstance(), css::uno::UNO_QUERY_THROW); @@ -249,72 +251,6 @@ css::uno::Reference< css::registry::XSimpleRegistry > readRdbFile( } } -Reference< registry::XSimpleRegistry > readRdbDirectory( - rtl::OUString const & url, bool fatalErrors, - css::uno::Reference< css::registry::XSimpleRegistry > const & lastRegistry, - css::uno::Reference< css::lang::XSingleServiceFactory > const & - simpleRegistryFactory, - css::uno::Reference< css::lang::XSingleServiceFactory > const & - nestedRegistryFactory) -{ - OSL_ASSERT(simpleRegistryFactory.is() && nestedRegistryFactory.is()); - osl::Directory dir(url); - switch (dir.open()) { - case osl::FileBase::E_None: - break; - case osl::FileBase::E_NOENT: - if (!fatalErrors) { - return lastRegistry; - } - // fall through - default: - throw css::uno::RuntimeException( - (rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM("cannot open directory ")) + - url), - css::uno::Reference< css::uno::XInterface >()); - } - for (css::uno::Reference< css::registry::XSimpleRegistry > last( - lastRegistry);;) - { - osl::DirectoryItem i; - switch (dir.getNextItem(i, SAL_MAX_UINT32)) { - case osl::FileBase::E_None: - break; - case osl::FileBase::E_NOENT: - return last; - default: - throw css::uno::RuntimeException( - (rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM("cannot iterate directory ")) + - url), - css::uno::Reference< css::uno::XInterface >()); - } - 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( - RTL_CONSTASCII_USTRINGPARAM("cannot stat in directory ")) + - url), - 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) { //TODO: symlinks - last = readRdbFile( - stat.getFileURL(), fatalErrors, last, simpleRegistryFactory, - nestedRegistryFactory); - } - } -} - Reference< registry::XSimpleRegistry > nestRegistries( const OUString &baseDir, const Reference< lang::XSingleServiceFactory > & xSimRegFac, @@ -358,6 +294,8 @@ Reference< registry::XSimpleRegistry > nestRegistries( if (rdb_name.isEmpty()) { continue; } + fprintf( stderr, "nest registry '%s'\n", + rtl::OUStringToOString( rdb_name, RTL_TEXTENCODING_UTF8 ).getStr() ); bool fatalErrors = !bFallenBack; if (rdb_name[0] == '?') { @@ -374,11 +312,8 @@ Reference< registry::XSimpleRegistry > nestRegistries( osl::FileBase::getAbsoluteFileURL(baseDir, rdb_name, rdb_name); - lastRegistry = directory - ? readRdbDirectory( - rdb_name, fatalErrors, lastRegistry, xSimRegFac, xNesRegFac) - : readRdbFile( - rdb_name, fatalErrors, lastRegistry, xSimRegFac, xNesRegFac); + lastRegistry = readRdbFile(rdb_name, fatalErrors, lastRegistry, + xSimRegFac, xNesRegFac, directory); } while(index != -1 && csl_rdbs.getLength()); // are there more rdbs in list? diff --git a/registry/source/regimpl.cxx b/registry/source/regimpl.cxx index 401fb98..d651534 100644 --- a/registry/source/regimpl.cxx +++ b/registry/source/regimpl.cxx @@ -469,6 +469,9 @@ RegError ORegistry::initRegistry(const OUString& regName, RegAccessMode accessMo storeAccessMode sAccessMode = REG_MODE_OPEN; storeError errCode; + fprintf( stderr, "ORegistry::initRegistry '%s'\n", + rtl::OUStringToOString( regName, RTL_TEXTENCODING_UTF8 ).getStr() ); + if (accessMode & REG_CREATE) { sAccessMode = REG_MODE_CREATE; diff --git a/stoc/source/simpleregistry/simpleregistry.cxx b/stoc/source/simpleregistry/simpleregistry.cxx index f09b204..3f34516 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 ( @@ -1135,22 +1142,11 @@ rtl::OUString SimpleRegistry::getURL() throw (css::uno::RuntimeException) { 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 +1158,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 +1179,70 @@ 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); + if ((eErr = osl::DirectoryItem::get( rURL, aItem )) != osl::FileBase::E_None || + (eErr = aItem.getFileStatus( aStatus )) != osl::FileBase::E_None) + goto err_throw; + + if (!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 ad24a44..2491f55 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 286eb92..0341c15 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 >
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice