Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


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.meeks@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 >

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.