diff options
| author | Carl C. Trieloff <cctrieloff@apache.org> | 2011-03-11 00:37:04 +0000 |
|---|---|---|
| committer | Carl C. Trieloff <cctrieloff@apache.org> | 2011-03-11 00:37:04 +0000 |
| commit | 4401bac8a7da563b6cb12d16a09986e1a47d3788 (patch) | |
| tree | ffda0a8698ebf676f36980be2d05a862527a1f77 /qpid/cpp | |
| parent | 69351ac728699068f55db02a64248073cb9ae2bd (diff) | |
| download | qpid-python-4401bac8a7da563b6cb12d16a09986e1a47d3788.tar.gz | |
QPID-3138 Topic exchange perf improvement
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1080411 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp')
| -rw-r--r-- | qpid/cpp/src/qpid/broker/TopicExchange.cpp | 19 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/broker/TopicExchange.h | 14 |
2 files changed, 29 insertions, 4 deletions
diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.cpp b/qpid/cpp/src/qpid/broker/TopicExchange.cpp index 1b0fe71bcf..f3baf00d1f 100644 --- a/qpid/cpp/src/qpid/broker/TopicExchange.cpp +++ b/qpid/cpp/src/qpid/broker/TopicExchange.cpp @@ -221,6 +221,7 @@ TopicExchange::TopicExchange(const std::string& _name, bool _durable, bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, const FieldTable* args) { + ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit. string fedOp(args ? args->getAsString(qpidFedOp) : fedOpBind); string fedTags(args ? args->getAsString(qpidFedTags) : ""); string fedOrigin(args ? args->getAsString(qpidFedOrigin) : ""); @@ -288,6 +289,7 @@ bool TopicExchange::bind(Queue::shared_ptr queue, const string& routingKey, cons } bool TopicExchange::unbind(Queue::shared_ptr queue, const string& constRoutingKey, const FieldTable* /*args*/){ + ClearCache cc(&cacheLock,&bindingCache); // clear the cache on function exit. RWlock::ScopedWlock l(lock); string routingKey = normalize(constRoutingKey); BindingKey* bk = bindingTree.getBindingKey(routingKey); @@ -333,13 +335,24 @@ bool TopicExchange::isBound(Queue::shared_ptr queue, const string& pattern) void TopicExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* /*args*/) { // Note: PERFORMANCE CRITICAL!!! - BindingList b(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >); + BindingList b; + std::map<std::string, BindingList>::iterator it; + { // only lock the cache for read + RWlock::ScopedRlock cl(cacheLock); + it = bindingCache.find(routingKey); + } PreRoute pr(msg, this); - BindingsFinderIter bindingsFinder(b); + if (it == bindingCache.end()) // no cache hit { RWlock::ScopedRlock l(lock); + b = BindingList(new std::vector<boost::shared_ptr<qpid::broker::Exchange::Binding> >); + BindingsFinderIter bindingsFinder(b); bindingTree.iterateMatch(routingKey, bindingsFinder); - } + RWlock::ScopedWlock cwl(cacheLock); + bindingCache[routingKey] = b; // update cache + }else { + b = it->second; + } doRoute(msg, b); } diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.h b/qpid/cpp/src/qpid/broker/TopicExchange.h index a6c457dcb3..3d2b3a95a9 100644 --- a/qpid/cpp/src/qpid/broker/TopicExchange.h +++ b/qpid/cpp/src/qpid/broker/TopicExchange.h @@ -135,7 +135,19 @@ class TopicExchange : public virtual Exchange { BindingNode bindingTree; unsigned long nBindings; qpid::sys::RWlock lock; // protects bindingTree and nBindings - + qpid::sys::RWlock cacheLock; // protects cache + std::map<std::string, BindingList> bindingCache; // cache of matched routes. + class ClearCache { + private: + qpid::sys::RWlock* cacheLock; + std::map<std::string, BindingList>* bindingCache; + public: + ClearCache(qpid::sys::RWlock* l, std::map<std::string, BindingList>* bc): cacheLock(l),bindingCache(bc) {}; + ~ClearCache(){ + qpid::sys::RWlock::ScopedWlock l(*cacheLock); + bindingCache->clear(); + }; + }; bool isBound(Queue::shared_ptr queue, const std::string& pattern); class ReOriginIter; |
