From: Markus R. <rol...@us...> - 2007-02-16 15:36:56
|
Update of /cvsroot/simspark/simspark/spark/zeitgeist In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv21907 Modified Files: Tag: WIN32 core.cpp core.h Log Message: - added class Core::CachedPath that implements a pointer that carries along a path string and is therefore able to refresh the managed reference incase the object pointed to is replaced or removed. Index: core.cpp =================================================================== RCS file: /cvsroot/simspark/simspark/spark/zeitgeist/core.cpp,v retrieving revision 1.2.2.2 retrieving revision 1.2.2.3 diff -C2 -d -r1.2.2.2 -r1.2.2.3 *** core.cpp 12 Feb 2007 23:52:04 -0000 1.2.2.2 --- core.cpp 16 Feb 2007 15:36:51 -0000 1.2.2.3 *************** *** 334,343 **** } ! boost::shared_ptr<Leaf> Core::GetInternal(const std::string &pathStr, ! const boost::shared_ptr<Leaf>& leaf) { ! // lookup the path in the internal cache ! CacheKey key(leaf, pathStr); ! TPathCache::iterator iter = mPathCache.find(key); if (iter != mPathCache.end()) --- 334,340 ---- } ! boost::weak_ptr<Leaf> Core::GetCachedInternal(const CacheKey& key) { ! // lookup the key in the internal cache TPathCache::iterator iter = mPathCache.find(key); if (iter != mPathCache.end()) *************** *** 346,351 **** if (! entry.expired()) { ! return entry.lock(); ! } // remove entry as it points to an expired node --- 343,348 ---- if (! entry.expired()) { ! return entry; ! } // remove entry as it points to an expired node *************** *** 353,369 **** } // walk the hierarchy ! Path path(pathStr); ! boost::shared_ptr<Leaf> current; if ( (path.IsAbsolute()) || ! (leaf.get() == NULL) ) { ! current= mRoot; } else { ! current = leaf; } --- 350,384 ---- } + return shared_ptr<Leaf>(); + } + + void Core::PutCachedInternal(const CacheKey& key, const boost::weak_ptr<Leaf>& leaf) + { + // update cache; note that we can't cache the fact, that a node is + // not present as it may be created later on + + if (leaf.expired()) + { + return; + } + + mPathCache[key] = leaf; + } + + boost::shared_ptr<Leaf> Core::GetUncachedInternal(const CacheKey& key) + { // walk the hierarchy ! shared_ptr<Leaf> current; ! Path path(key.path); if ( (path.IsAbsolute()) || ! (key.root.expired()) ) { ! current = mRoot; } else { ! current = key.root.lock(); } *************** *** 378,389 **** } ! // update cache; note that we can't cache the fact, that a node is ! // not present as it may be created later on ! if (current.get() != 0) { ! mPathCache[key] = current; } ! return current; } --- 393,415 ---- } ! // update cache ! PutCachedInternal(key, current); ! ! return current; ! } ! ! boost::shared_ptr<Leaf> Core::GetInternal(const std::string &pathStr, ! const boost::shared_ptr<Leaf>& leaf) ! { ! // lookup the path in the internal cache ! CacheKey key(leaf, pathStr); ! ! boost::weak_ptr<Leaf> cached(GetCachedInternal(key)); ! if (! cached.expired()) { ! return cached.lock(); } ! return GetUncachedInternal(key); } Index: core.h =================================================================== RCS file: /cvsroot/simspark/simspark/spark/zeitgeist/core.h,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -C2 -d -r1.2 -r1.2.2.1 *** core.h 10 Mar 2006 00:16:06 -0000 1.2 --- core.h 16 Feb 2007 15:36:51 -0000 1.2.2.1 *************** *** 26,29 **** --- 26,30 ---- #include <list> #include <map> + #include <set> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> *************** *** 55,59 **** class Core { ! protected: // // types --- 56,60 ---- class Core { ! public: // // types *************** *** 73,81 **** public: ! CacheKey(boost::weak_ptr<Leaf> r, const std::string& p) : root(r), path(p) {}; bool operator == (const CacheKey& key) const; bool operator < (const CacheKey& key) const; }; /** TPathCache defines a mapping from a CacheKey to a weak reference of the corresponding Leaf --- 74,179 ---- public: ! CacheKey() ! {} ! ! CacheKey(boost::weak_ptr<Leaf> r, const std::string& p) : root(r), path(p) ! {}; ! bool operator == (const CacheKey& key) const; bool operator < (const CacheKey& key) const; }; + /** CachedLeafPath defines a pair of path key and it's + corresponding weak reference. It acts like a smart pointer + that is able to update the keep the managed reference up to + date with the help of the core and the CacheKey + */ + struct CachedLeafPath + { + protected: + CacheKey key; + boost::weak_ptr<Leaf> leaf; + + public: + const CacheKey& GetKey() + { return key; } + + boost::weak_ptr<Leaf>& GetLeaf() + { return leaf; } + + virtual void Cache(boost::shared_ptr<Core> core, const std::string& pathStr) = 0; + virtual void Update(boost::shared_ptr<Core> core) = 0; + + bool operator == (const CachedLeafPath& p) + { + return (key == p.key); + } + + bool operator < (const CachedLeafPath& p) + { + return (key < p.key); + } + + bool expired() + { + return leaf.expired(); + } + }; + + template<typename _CLASS> + struct CachedPath : public CachedLeafPath + { + public: + CachedPath() : CachedLeafPath() + {} + + CachedPath(const CacheKey& k, const boost::weak_ptr<_CLASS> &l) + : CachedLeafPath(k,l) + {} + + virtual void Cache(boost::shared_ptr<Core> core, const std::string& pathStr) + { + if (core.get() == NULL) + { + leaf.reset(); + return; + } + + key = CacheKey(core->mRoot, pathStr); + Update(core); + } + + virtual void Update(boost::shared_ptr<Core> core) + { + if (core.get() == NULL) + { + leaf.reset(); + return; + } + + // lookup the path in the internal core cache + boost::weak_ptr<Leaf> lookup = core->GetCachedInternal(key); + if (! lookup.expired()) + { + leaf = boost::shared_dynamic_cast<_CLASS>(lookup.lock()); + return; + } + + leaf = boost::shared_dynamic_cast<_CLASS> + (core->GetUncachedInternal(key)); + } + + boost::shared_ptr<_CLASS> get() + { + return boost::shared_static_cast<_CLASS>(leaf.lock()); + } + + _CLASS* operator -> () + { + return boost::shared_static_cast<_CLASS>(leaf.lock()).get(); + } + }; + + protected: /** TPathCache defines a mapping from a CacheKey to a weak reference of the corresponding Leaf *************** *** 141,145 **** boost::shared_ptr<Leaf> GetRoot() const { return mRoot; } ! /** returns a reference to the object denoted by the path expression 'pathStr'. */ boost::shared_ptr<Leaf> Get(const std::string &pathStr); --- 239,245 ---- boost::shared_ptr<Leaf> GetRoot() const { return mRoot; } ! /** returns a reference to the object denoted by the path ! expression 'pathStr'. ! */ boost::shared_ptr<Leaf> Get(const std::string &pathStr); *************** *** 175,178 **** --- 275,296 ---- protected: + /** returns a cached reference to the Leaf corresponding to the + given key. If the cached reference expired the entry is + removed from the cache + */ + boost::weak_ptr<Leaf> GetCachedInternal(const CacheKey& key); + + /** returns a reference to the object denoted by the path + expression 'pathStr', relative to the node base. This method + does not lookup for a cached reference but does update the + cache accordingly + */ + boost::shared_ptr<Leaf> GetUncachedInternal(const CacheKey& key); + + /** checks that the leaf reference isn't expired and inserts the + given key,leaf pair into the cache + */ + void PutCachedInternal(const CacheKey& key, const boost::weak_ptr<Leaf>& leaf); + /** returns a reference to the object denoted by the path expression 'pathStr', relative to the node base. |