Skip to content

Commit

Permalink
Cache regex pattern matches for XMPP_SKIP_UPDATE_SEND pattern
Browse files Browse the repository at this point in the history
Regex pattern matching can be expensive. Hence cache the result inside
BgpXmppChannel object to avoid redundant regex evaluation.

Change-Id: I85f136e273b045284c32a1cecff7a41f3dcb0054
Partial-Bug: 1464016
  • Loading branch information
ananth-at-camphor-networks committed Jul 21, 2016
1 parent 3bd6a95 commit c730ad2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/bgp/bgp_xmpp_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "bgp/bgp_xmpp_channel.h"

#include <boost/foreach.hpp>
#include <boost/regex.hpp>

#include <limits>
#include <vector>
Expand Down Expand Up @@ -49,6 +50,9 @@ using autogen::SecurityGroupListType;
using autogen::CommunityTagListType;
using autogen::TunnelEncapsulationListType;

using boost::regex;
using boost::regex_search;
using boost::smatch;
using boost::system::error_code;
using pugi::xml_node;
using std::auto_ptr;
Expand Down Expand Up @@ -441,23 +445,29 @@ class BgpXmppChannel::XmppPeer : public IPeer {
uint64_t deleted_at_;
};

static bool SkipUpdateSend() {
static bool init_;
static bool skip_;

if (init_) return skip_;

skip_ = getenv("XMPP_SKIP_UPDATE_SEND") != NULL;
init_ = true;
// Skip sending updates if the destinatin matches against the pattern.
// XXX Used in test environments only
bool BgpXmppChannel::SkipUpdateSend() {
static char *skip_env_ = getenv("XMPP_SKIP_UPDATE_SEND");
if (!skip_env_)
return false;

return skip_;
// Use XMPP_SKIP_UPDATE_SEND as a regex pattern to match against destination
// Cache the result to avoid redundant regex evaluation
if (!skip_update_send_cached_) {
smatch matches;
skip_update_send_ = regex_search(ToString(), matches, regex(skip_env_));
skip_update_send_cached_ = true;
}
return skip_update_send_;
}

bool BgpXmppChannel::XmppPeer::SendUpdate(const uint8_t *msg, size_t msgsize) {
XmppChannel *channel = parent_->channel_;
if (channel->GetPeerState() == xmps::READY) {
parent_->stats_[TX].rt_updates++;
if (SkipUpdateSend()) return true;
if (parent_->SkipUpdateSend())
return true;
send_ready_ = channel->Send(msg, msgsize, xmps::BGP,
boost::bind(&BgpXmppChannel::XmppPeer::WriteReadyCb, this, _1));
if (!send_ready_) {
Expand Down Expand Up @@ -499,6 +509,8 @@ BgpXmppChannel::BgpXmppChannel(XmppChannel *channel, BgpServer *bgp_server,
close_in_progress_(false),
deleted_(false),
defer_peer_close_(false),
skip_update_send_(false),
skip_update_send_cached_(false),
membership_response_worker_(
TaskScheduler::GetInstance()->GetTaskId("xmpp::StateMachine"),
channel->connection()->GetIndex(),
Expand Down
3 changes: 3 additions & 0 deletions src/bgp/bgp_xmpp_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class BgpXmppChannel {
uint64_t get_tx_route_reach() const { return stats_[TX].reach; }
uint64_t get_tx_route_unreach() const { return stats_[TX].unreach; }
uint64_t get_tx_update() const { return stats_[TX].rt_updates; }
bool SkipUpdateSend();

protected:
XmppChannel *channel_;
Expand Down Expand Up @@ -234,6 +235,8 @@ class BgpXmppChannel {
bool close_in_progress_;
bool deleted_;
bool defer_peer_close_;
bool skip_update_send_;
bool skip_update_send_cached_;
WorkQueue<std::string> membership_response_worker_;
SubscribedRoutingInstanceList routing_instances_;
PublishedRTargetRoutes rtarget_routes_;
Expand Down

0 comments on commit c730ad2

Please sign in to comment.