From c895031c16e70b4a178205ac9df3677c46186869 Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 15 Feb 2012 17:26:51 +0000 Subject: Improved script component caching, performance tweaks and related fixes for persistent objects --- project2/cgi/cgiAppEngine.cpp | 5 +++++ project2/common/presenterCache.cpp | 5 +++++ project2/common/presenterCache.h | 1 + project2/common/scriptLoader.cpp | 24 ++++++++++++------------ project2/common/scripts.h | 3 +++ project2/common/transform.cpp | 6 ++++++ project2/common/transform.h | 1 + project2/files/presenterCache.cpp | 18 ++++++++++++++---- project2/xml/xmlScriptParser.cpp | 13 ++++++++----- project2/xml/xmlScriptParser.h | 1 + 10 files changed, 56 insertions(+), 21 deletions(-) diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 07aa737..d062d87 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -7,6 +7,7 @@ #include #include #include "ostreamWrapper.h" +#include "scopeObject.h" #include const std::string SESSIONID = "sessionID"; @@ -136,6 +137,7 @@ CgiApplicationEngine::process() const } if (TransformSourcePtr ts = currentStage.get<2>()) { TransformSourcePtr final = finalTransformSource(ts); + ScopeObject emptyFinal(boost::bind(&TransformSource::clearTargets, final)); final->addTarget(new CgiResult(header, IO, rs && rs->root ? rs->root->value("encoding", _env->outputEncoding) : VariableType(_env->outputEncoding)), NULL); BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { @@ -149,6 +151,9 @@ CgiApplicationEngine::process() const } } ts->doTransforms(); + BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { + p->flushCache(); + } if (ddd) { delete ddd; } diff --git a/project2/common/presenterCache.cpp b/project2/common/presenterCache.cpp index 4771eed..d5897ad 100644 --- a/project2/common/presenterCache.cpp +++ b/project2/common/presenterCache.cpp @@ -16,6 +16,11 @@ PresenterCache::applyKeys(const boost::function2 { public: void transform(const WritableContent * wc, PresenterCache * pc) const { diff --git a/project2/common/presenterCache.h b/project2/common/presenterCache.h index 92de2d2..85aafab 100644 --- a/project2/common/presenterCache.h +++ b/project2/common/presenterCache.h @@ -11,6 +11,7 @@ class PresenterCache : public SourceObject, public virtual TransformSource, publ virtual bool check() const = 0; virtual std::ostream & writeCache(const std::string & ct, const std::string & encoding) = 0; + virtual void flushCache(); const std::string encoding; protected: diff --git a/project2/common/scriptLoader.cpp b/project2/common/scriptLoader.cpp index 6d5abdb..360076c 100644 --- a/project2/common/scriptLoader.cpp +++ b/project2/common/scriptLoader.cpp @@ -88,29 +88,29 @@ LoaderBase::collectAll(ScriptNodePtr node, bool childrenOnly, const StorerPtrs & DepthCounter dc(depth); unsigned int created = 0; if (!childrenOnly && node->componentNamespace()) { - Glib::ustring name = node->get_name(); unsigned int stored = 0; created += 1; - boost::intrusive_ptr o; - BOOST_FOREACH(const StorerPtr & s, sts) { - try { - o = s->create(node); - break; - } - catch (const NotSupported &) { + if (!node->obj) { + BOOST_FOREACH(const StorerPtr & s, sts) { + try { + node->obj = s->create(node); + break; + } + catch (const NotSupported &) { + } } } - if (!o) { - throw NotSupported(name); + if (!node->obj) { + throw NotSupported(node->get_name()); } BOOST_FOREACH(const StorerPtr & s, sts) { - if (s->save(o, node)) { + if (s->save(node->obj, node)) { stored += 1; break; } } if (stored < 1) { - throw NotSupported(name); + throw NotSupported(node->get_name()); } } if (created == 0 && (recursive || childrenOnly)) { diff --git a/project2/common/scripts.h b/project2/common/scripts.h index 020cf50..b7fdec9 100644 --- a/project2/common/scripts.h +++ b/project2/common/scripts.h @@ -47,6 +47,9 @@ class ScriptNode : public IntrusivePtrBase { virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0; const ScriptReaderPtr script; + private: + friend class LoaderBase; + mutable boost::intrusive_ptr obj; }; class ScriptReader : public virtual IntrusivePtrBase { diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp index 5a40ce3..9a53107 100644 --- a/project2/common/transform.cpp +++ b/project2/common/transform.cpp @@ -56,6 +56,12 @@ TransformSource::addTarget(TransformChainLinkPtr tcl, ScriptNodePtr e) throw NotSupported("Couldn't find a suitable transformation"); } +void +TransformSource::clearTargets() +{ + targets.clear(); +} + void TransformSource::doTransforms() const { diff --git a/project2/common/transform.h b/project2/common/transform.h index e3bdf4f..e2216d7 100644 --- a/project2/common/transform.h +++ b/project2/common/transform.h @@ -20,6 +20,7 @@ class TransformSource : public TransformChainLink { public: TransformSource(); TransformSource(ScriptNodePtr); + void clearTargets(); void addTarget(TransformChainLinkPtr, ScriptNodePtr e = NULL); void doTransforms() const; const Targets & getTargets() const; diff --git a/project2/files/presenterCache.cpp b/project2/files/presenterCache.cpp index 76a4e86..789dd95 100644 --- a/project2/files/presenterCache.cpp +++ b/project2/files/presenterCache.cpp @@ -43,7 +43,9 @@ class FilePresenterCache : public PresenterCache, public StaticContent, public S bool check() const { try { - readcachefd = safesys(-1, open(getCacheFile().string().c_str(), O_RDONLY)); + if (readcachefd == 0) { + readcachefd = safesys(-1, open(getCacheFile().string().c_str(), O_RDONLY)); + } struct stat st; safesys(-1, fstat(readcachefd, &st)); if (st.st_mtime < time(NULL) - FilePresenterCache::CacheLife) { @@ -52,12 +54,13 @@ class FilePresenterCache : public PresenterCache, public StaticContent, public S readcachefd = 0; return false; } - safesys(-1, ::flock(readcachefd, LOCK_SH)); return true; } catch (...) { - close(readcachefd); - readcachefd = 0; + if (readcachefd) { + close(readcachefd); + readcachefd = 0; + } return false; } } @@ -76,9 +79,11 @@ class FilePresenterCache : public PresenterCache, public StaticContent, public S } void writeTo(std::ostream & o) const { + safesys(-1, ::flock(readcachefd, LOCK_SH)); boost::iostreams::stream cache(readcachefd, boost::iostreams::never_close_handle); cache.seekg(0); o << cache.rdbuf(); + safesys(-1, ::flock(readcachefd, LOCK_UN)); } operator const StaticContent * () const { return this; @@ -95,6 +100,11 @@ class FilePresenterCache : public PresenterCache, public StaticContent, public S writecache = new boost::iostreams::stream(fd, boost::iostreams::close_handle); return *writecache; } + void flushCache() + { + delete writecache; + writecache = NULL; + } std::ostream * writecache; private: diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp index abb4cbe..d2ee6e7 100644 --- a/project2/xml/xmlScriptParser.cpp +++ b/project2/xml/xmlScriptParser.cpp @@ -34,6 +34,7 @@ void XmlScriptParser::load(const CommonObjects * co, bool childrenOnly) const { ScriptReader::load(co, childrenOnly); + // call me when isCurrent is false _root.reset(); } @@ -88,13 +89,15 @@ XmlScriptNode::valueExists(const Glib::ustring & n) const ScriptNode::ScriptNodes XmlScriptNode::children() const { - ScriptNodes sns; - BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) { - if (const xmlpp::Element * e = dynamic_cast(n)) { - sns.push_back(new XmlScriptNode(e, script)); + if (!childrenCache) { + childrenCache = boost::shared_ptr(new ScriptNodes()); + BOOST_FOREACH(const xmlpp::Node * n, element->get_children()) { + if (const xmlpp::Element * e = dynamic_cast(n)) { + childrenCache->push_back(new XmlScriptNode(e, script)); + } } } - return sns; + return *childrenCache; } ScriptNodePtr diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h index c85795a..8fa35c9 100644 --- a/project2/xml/xmlScriptParser.h +++ b/project2/xml/xmlScriptParser.h @@ -29,6 +29,7 @@ class XmlScriptNode : public ScriptNode { private: const xmlpp::Element * element; + mutable boost::shared_ptr childrenCache; }; class XmlScriptParser : public xmlpp::DomParser, public ScriptReader { -- cgit v1.2.3