summaryrefslogtreecommitdiff
path: root/stoc
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2012-04-13 15:25:23 +0200
committerMichael Meeks <michael.meeks@suse.com>2012-04-14 01:34:59 +0200
commit09524d410bbaad2a0b9b39811cb5cc16621b1396 (patch)
tree4f648522110b5f87ea6f357dd4a7501ac23e1ac8 /stoc
parenta871537f328711f02d3b5ba18612bbf25c6f563b (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')
-rw-r--r--stoc/source/simpleregistry/simpleregistry.cxx94
-rw-r--r--stoc/source/simpleregistry/textualservices.cxx11
-rw-r--r--stoc/source/simpleregistry/textualservices.hxx3
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 >