12 #ifndef __SANDESH_UVE_H__ 
   13 #define __SANDESH_UVE_H__ 
   17 #include <boost/ptr_container/ptr_map.hpp> 
   18 #include <boost/assign/ptr_map_inserter.hpp> 
   19 #include <sandesh/sandesh_types.h> 
   20 #include <sandesh/sandesh.h> 
   21 #include <tbb/mutex.h> 
   22 #include <tbb/concurrent_hash_map.h> 
   23 #include <boost/functional/hash.hpp> 
   41         assert(
GetMap()->insert(std::make_pair(s,
 
   42             std::make_pair(period, tmap))).second);
 
   45         uve_global_map::const_iterator it = 
GetMap()->find(s);
 
   51     static void SyncAllMaps(
const std::map<std::string,uint32_t> &,
 
   52         bool periodic = 
false);
 
   53     static uint32_t 
Clear(
const std::string& proxy, 
int partition);
 
   55         const std::map<std::string, ds_conf_elem> &);
 
   56     static void SyncIntrospect(std::string tname, std::string table, std::string key);
 
   58     static uve_global_map::const_iterator 
Begin() { 
return GetMap()->begin(); }
 
   59     static uve_global_map::const_iterator 
End() { 
return GetMap()->end(); }
 
   80             uint32_t seqno, uint32_t cycle, 
const std::string &ctx) = 0;
 
   82             const std::map<std::string,std::string> & dsconf) = 0;
 
   83     virtual bool SendUVE(
const std::string& table, 
const std::string& name,
 
   84             const std::string& ctx) 
const = 0;
 
   85     virtual std::map<std::string, std::string> 
GetDSConf(
void) 
const = 0;
 
   87     virtual uint32_t 
ClearUVEs(
const std::string& proxy, 
int partition) = 0;
 
  108 template<
typename T, 
typename U, 
int P, 
int TM>
 
  113         static size_t hash( 
const std::string& key )
 
  115         static bool   equal( 
const std::string& key1, 
const std::string& key2 )
 
  116             { 
return ( key1 == key2 ); }
 
  133     typedef tbb::concurrent_hash_map<std::string, uve_table_map, HashCompare > 
uve_cmap;
 
  141     bool UpdateUVE(U& data, uint32_t seqnum, uint64_t mono_usec,
 
  144         tbb::mutex::scoped_lock lock;
 
  145         const std::string &table = data.table_;
 
  146         assert(!table.empty());
 
  147         const std::string &s = data.get_name();
 
  152         std::map<string,string> dsconf = 
dsconf_;
 
  158         if (!data.get_deleted()) {
 
  161         typename uve_cmap::accessor a;
 
  165             if (
cmap_.find(a, s)) 
break;
 
  167                 if (
cmap_.insert(a, s)) 
break;
 
  171         typename uve_table_map::iterator imapentry = a->second.find(table);
 
  172         if (imapentry == a->second.end()) {
 
  173             std::auto_ptr<UVEMapEntry> ume(
new 
  175             T::_InitDerivedStats(ume->data, dsconf);
 
  176             send = T::UpdateUVE(data, ume->data, mono_usec, level);
 
  177             imapentry = a->second.insert(table, ume).first;
 
  182                 imapentry->second->data.set_deleted(
false);
 
  184             send = T::UpdateUVE(data, imapentry->second->data, mono_usec,
 
  186             imapentry->second->seqno = seqnum;
 
  188         if (data.get_deleted()) {
 
  189             a->second.erase(imapentry);
 
  190             if (a->second.empty()) 
cmap_.erase(a);
 
  205         typename uve_cmap::iterator git = 
cmap_.begin();
 
  206         while (git != 
cmap_.end()) {
 
  207             typename uve_cmap::accessor a;
 
  208             if (!
cmap_.find(a, git->first)) 
continue;
 
  209             typename uve_table_map::iterator uit = a->second.begin();
 
  210             while (uit != a->second.end()) {
 
  211                 SANDESH_LOG(INFO, __func__ << 
" Clearing " << uit->first <<
 
  212                     " val " << uit->second->data.log() << 
" proxy " <<
 
  214                     " seq " << uit->second->seqno);
 
  215                 uit->second->data.set_deleted(
true);
 
  216                 T::Send(uit->second->data, uit->second->level,
 
  234         std::map<std::string,std::string> dsnew = 
dsconf_;
 
  237         for (map<std::string,std::string>::const_iterator n_iter = dsconf.begin();
 
  238                 n_iter != dsconf.end(); n_iter++) {
 
  239             if (dsnew.find(n_iter->first) != dsnew.end()) {
 
  240                 SANDESH_LOG(INFO, __func__ << 
" Overide DSConf for " <<
 
  241                     n_iter->first << 
" , " << dsnew[n_iter->first] <<
 
  242                     " with " << n_iter->second);
 
  243                 dsnew[n_iter->first] = n_iter->second;
 
  245                 SANDESH_LOG(INFO, __func__ << 
" Cannot find DSConf for " <<
 
  246                     n_iter->first << 
" , " << n_iter->second);
 
  257         for (
typename uve_cmap::iterator git = 
cmap_.begin();
 
  258                 git != 
cmap_.end(); git++) {
 
  259             typename uve_cmap::accessor a;
 
  260             if (!
cmap_.find(a, git->first)) 
continue;
 
  261             for (
typename uve_table_map::iterator uit = a->second.begin();
 
  262                     uit != a->second.end(); uit++) {
 
  263                 SANDESH_LOG(INFO, __func__ << 
" Reset Derived Stats for " <<
 
  265                 T::_InitDerivedStats(uit->second->data, 
dsconf_);
 
  273             uint32_t seqno, uint32_t cycle,
 
  274             const std::string &ctx) {
 
  279         typename uve_cmap::iterator git = 
cmap_.begin();
 
  280         while (git != 
cmap_.end()) {
 
  281             typename uve_cmap::accessor a;
 
  282             if (!
cmap_.find(a, git->first)) 
continue;
 
  283             typename uve_table_map::iterator uit = a->second.begin();
 
  284             while (uit != a->second.end()) {
 
  285                 typename uve_table_map::iterator dit = a->second.end();
 
  286                 if (!table.empty() && uit->first != table) 
continue;
 
  287                 if ((seqno < uit->second->seqno) || (seqno == 0)) {
 
  289                         SANDESH_LOG(INFO, __func__ << 
" Syncing " << uit->first <<
 
  290                             " val " << uit->second->data.log() << 
" proxy " <<
 
  292                             " seq " << uit->second->seqno);
 
  294                     T::Send(uit->second->data, uit->second->level, st,
 
  295                             uit->second->seqno, cycle, ctx);
 
  297                         if ((cycle % TM) == 0) {
 
  298                             if (uit->second->data.get_deleted()) {
 
  306                                 uit->second->data.set_deleted(
true);
 
  313                 if (dit != a->second.end()) a->second.erase(dit);
 
  316             if (a->second.empty()) 
cmap_.erase(a);
 
  321     bool SendUVE(
const std::string& table, 
const std::string& name,
 
  322                  const std::string& ctx)
 const {
 
  324         typename uve_cmap::const_accessor a;
 
  325         if (
cmap_.find(a, name)) {
 
  326             for (
typename uve_table_map::const_iterator uve_entry = a->second.begin();
 
  327                     uve_entry != a->second.end(); uve_entry++) {
 
  328                 if (!table.empty() && uve_entry->first != table) 
continue;
 
  330                 T::Send(uve_entry->second->data, uve_entry->second->level,
 
  332                     uve_entry->second->seqno, 0, ctx);
 
  338     std::map<std::string, std::string> 
GetDSConf(
void)
 const {
 
  349 #define SANDESH_UVE_DEF(x,y,z,w) \ 
  350     static SandeshUVEPerTypeMapGroup<x, y, z, w> uvemap ## x(#y) 
  352 template<
typename T, 
typename U, 
int P, 
int TM>
 
  367         std::string native_name(std::string(
""));
 
  381         if (name == std::string(
"")){
 
  384         tbb::mutex::scoped_lock lock(
nmutex_);
 
  387             std::string native_name(name);
 
  395         tbb::mutex::scoped_lock lock(
nmutex_);
 
  396         std::vector<uve_emap *> nev;
 
  399             nev.push_back(uni->second);
 
  406         tbb::mutex::scoped_lock lock(
gmutex_);
 
  409             std::string kstring(proxy);
 
  411                 boost::assign::ptr_map_insert(*up)(idx);
 
  420         tbb::mutex::scoped_lock lock(
gmutex_);
 
  421         std::vector<uve_pmap *> pv;
 
  422         for (
typename uve_gmap::iterator ugi = 
group_map_.begin();
 
  424             pv.push_back(ugi->second);
 
  442             uint32_t seqno, uint32_t cycle,
 
  443             const std::string &ctx) {
 
  445         std::vector<uve_emap *> nev = 
GetNMaps();
 
  446         for (
size_t idx=0; idx<nev.size(); idx++) {
 
  447             count += nev[idx]->SyncUVE(table, st, seqno, cycle,ctx);
 
  450         std::vector<uve_pmap *> pv = 
GetGMaps();
 
  451         for (
size_t jdx=0; jdx<pv.size(); jdx++) {
 
  453                 count += pv[jdx]->at(idx).SyncUVE(table, st, seqno, cycle, ctx);
 
  463             const std::map<std::string,std::string> & dsconf) {
 
  469     bool SendUVE(
const std::string& table, 
const std::string& name,
 
  470             const std::string& ctx)
 const {
 
  472         std::vector<uve_emap *> nev =
 
  474         for (
size_t idx=0; idx<nev.size(); idx++) {
 
  475             if (nev[idx]->
SendUVE(table, name, ctx)) sent = 
true;
 
  478         std::vector<uve_pmap *> pv =
 
  480         for (
size_t jdx=0; jdx<pv.size(); jdx++) {
 
  482                 if (pv[jdx]->at(idx).
SendUVE(table, name, ctx)) sent = 
true;
 
  488     std::map<std::string, std::string> 
GetDSConf(
void)
 const {
 
  494         if (partition == -1) {
 
  496             return ne->
UpdateUVE(data, seqnum, mono_usec, level);
 
  501             return pp->at(partition).UpdateUVE(data, seqnum, mono_usec, level);
 
  506     uint32_t 
ClearUVEs(
const std::string& proxy, 
int partition) {
 
  507         if (partition != -1) {
 
  508             tbb::mutex::scoped_lock lock(
gmutex_);
 
  509             typename uve_gmap::iterator gi = 
group_map_.find(proxy);
 
  512                 return gi->second->at(partition).ClearUVEs();
 
std::size_t hash_value(BgpAttr const &attr)
 
boost::ptr_map< int, uve_emap > uve_pmap
 
uve_nmap native_group_map_
 
boost::ptr_map< string, uve_pmap > uve_gmap
 
string GetNMapUVEname(U &data)
 
SandeshUVEPerTypeMapGroup(char const *u_name)
 
uint32_t ClearUVEs(const std::string &proxy, int partition)
 
std::vector< uve_emap * > GetNMaps(void)
 
bool UpdateUVE(U &data, uint32_t seqnum, uint64_t mono_usec, int partition, SandeshLevel::type level)
 
std::vector< uve_pmap * > GetGMaps(void)
 
uint32_t SyncUVE(const std::string &table, SandeshUVE::SendType st, uint32_t seqno, uint32_t cycle, const std::string &ctx)
 
uve_emap * GetNMap(const std::string &name)
 
bool SendUVE(const std::string &table, const std::string &name, const std::string &ctx) const
 
boost::ptr_map< string, uve_emap > uve_nmap
 
uint32_t TypeSeq(void) const
 
std::map< std::string, std::string > GetDSConf(void) const
 
int GetTimeout(void) const
 
uve_pmap * GetGMap(const std::string &proxy)
 
bool InitDerivedStats(const std::map< std::string, std::string > &dsconf)
 
SandeshUVEPerTypeMapImpl< T, U, P, TM > uve_emap
 
bool InitDerivedStats(const std::map< std::string, std::string > &dsconf)
 
uint32_t SyncUVE(const std::string &table, SandeshUVE::SendType st, uint32_t seqno, uint32_t cycle, const std::string &ctx)
 
tbb::concurrent_hash_map< std::string, uve_table_map, HashCompare > uve_cmap
 
std::map< std::string, std::string > GetDSConf(void) const
 
SandeshUVEPerTypeMapImpl()
 
bool UpdateUVE(U &data, uint32_t seqnum, uint64_t mono_usec, SandeshLevel::type level)
 
std::map< std::string, std::string > dsconf_
 
bool SendUVE(const std::string &table, const std::string &name, const std::string &ctx) const
 
boost::ptr_map< std::string, UVEMapEntry > uve_table_map
 
virtual bool InitDerivedStats(const std::map< std::string, std::string > &dsconf)=0
 
virtual int GetTimeout(void) const =0
 
virtual uint32_t ClearUVEs(const std::string &proxy, int partition)=0
 
virtual ~SandeshUVEPerTypeMap()
 
virtual uint32_t TypeSeq() const =0
 
virtual bool SendUVE(const std::string &table, const std::string &name, const std::string &ctx) const =0
 
virtual std::map< std::string, std::string > GetDSConf(void) const =0
 
virtual uint32_t SyncUVE(const std::string &table, SandeshUVE::SendType st, uint32_t seqno, uint32_t cycle, const std::string &ctx)=0
 
static uve_global_map::const_iterator Begin()
 
static bool InitDerivedStats(const std::map< std::string, ds_conf_elem > &)
 
static uve_global_map * map_
 
std::map< std::string, std::string > ds_conf_elem
 
static uve_global_map * GetMap()
 
std::pair< int, SandeshUVEPerTypeMap * > uve_global_elem
 
std::map< std::string, uve_global_elem > uve_global_map
 
static const uve_global_elem TypeMap(const std::string &s)
 
static void RegisterType(const std::string &s, SandeshUVEPerTypeMap *tmap, int period)
 
static const int kProxyPartitions
 
static uve_global_map::const_iterator End()
 
static void SyncAllMaps(const std::map< std::string, uint32_t > &, bool periodic=false)
 
static void SyncIntrospect(std::string tname, std::string table, std::string key)
 
static uint32_t Clear(const std::string &proxy, int partition)
 
#define SANDESH_LOG(_Level, _Msg)
 
void failure(const char *fmt,...)
 
static std::string get(const T &s)
 
static size_t hash(const std::string &key)
 
static bool equal(const std::string &key1, const std::string &key2)
 
UVEMapEntry(const std::string &table, uint32_t seqnum, SandeshLevel::type level)
 
static uint64_t ClockMonotonicUsec()