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 425094e commit 04a2bf1
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
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 @@ -52,6 +53,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 @@ -536,23 +540,29 @@ class BgpXmppChannel::XmppPeer : public IPeer {
uint64_t closed_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 @@ -599,6 +609,8 @@ BgpXmppChannel::BgpXmppChannel(XmppChannel *channel, BgpServer *bgp_server,
delete_in_progress_(false),
deleted_(false),
defer_peer_close_(false),
skip_update_send_(false),
skip_update_send_cached_(false),
membership_unavailable_(false),
end_of_rib_timer_(NULL),
membership_response_worker_(
Expand Down
3 changes: 3 additions & 0 deletions src/bgp/bgp_xmpp_channel.h
Expand Up @@ -131,6 +131,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 @@ -269,6 +270,8 @@ class BgpXmppChannel {
bool delete_in_progress_;
bool deleted_;
bool defer_peer_close_;
bool skip_update_send_;
bool skip_update_send_cached_;
bool membership_unavailable_;
Timer *end_of_rib_timer_;
WorkQueue<std::string> membership_response_worker_;
Expand Down

0 comments on commit 04a2bf1

Please sign in to comment.