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

Reply via email to