Line data Source code
1 : /* 2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. 3 : * Copyright Contributors to the OpenSDN project 4 : */ 5 : 6 : #include "stat_walker.h" 7 : #include "viz_message.h" 8 : 9 : using std::string; 10 : using std::vector; 11 : using std::make_pair; 12 : 13 : void 14 0 : StatWalker::Push(const std::string& name, 15 : const TagMap& tags, 16 : const DbHandler::AttribMap& attribs) { 17 : 18 0 : string prename(""); 19 0 : for (vector<StatNode>::const_iterator ni = nodes_.begin(); 20 0 : ni != nodes_.end(); ni++) { 21 0 : const StatNode& ancestor = *ni; 22 0 : if (!prename.empty()) { 23 0 : prename.append("."); 24 : } 25 0 : prename.append(ancestor.name); 26 : } 27 : 28 0 : StatNode sn; 29 0 : sn.name = name; 30 : 31 0 : if (!prename.empty()) { 32 0 : prename.append("."); 33 : } 34 0 : prename.append(sn.name); 35 : 36 : // For both tag names and attribute names, we need to convert 37 : // from local name to fully-qualified name 38 0 : for (TagMap::const_iterator ti = tags.begin(); 39 0 : ti != tags.end(); ti++) { 40 0 : std::string tname; 41 : 42 0 : VIZD_ASSERT(ti->first.find('.') == string::npos); 43 0 : tname = prename + "." + ti->first; 44 : 45 : // For prefixes, the tag prefix name is already fully-qualified 46 0 : sn.tags.insert(make_pair(tname, ti->second)); 47 0 : } 48 0 : for (DbHandler::AttribMap::const_iterator ai = attribs.begin(); 49 0 : ai != attribs.end(); ai++) { 50 0 : std::string aname; 51 : 52 0 : VIZD_ASSERT(ai->first.find('.') == string::npos); 53 0 : aname = prename + "." + ai->first; 54 0 : sn.attribs.insert(make_pair(aname, ai->second)); 55 0 : } 56 0 : nodes_.push_back(sn); 57 0 : } 58 : 59 : void 60 0 : StatWalker::FillTag(DbHandler::TagMap *attribs_tag, 61 : const std::pair<const std::string, TagVal>* ti) { 62 0 : DbHandler::Var pval, sval; 63 0 : std::string pname, sname; 64 0 : if (ti->second.prefix.second.type == DbHandler::INVALID) { 65 : // There is no prefix supplied 66 0 : pname = ti->first; 67 0 : pval = ti->second.val; 68 : } else { 69 : // Use the prefix 70 0 : pname = ti->second.prefix.first; 71 0 : pval = ti->second.prefix.second; 72 0 : sname = ti->first; 73 0 : sval = ti->second.val; 74 : } 75 : 76 0 : DbHandler::TagMap::iterator di = attribs_tag->find(pname); 77 0 : if (di == attribs_tag->end()) { 78 : // This 1st level tag is absent 79 0 : DbHandler::AttribMap amap; 80 0 : if (sval.type != DbHandler::INVALID) { 81 0 : amap.insert(make_pair(sname, sval)); 82 : } 83 0 : attribs_tag->insert(make_pair(pname, make_pair(pval, amap))); 84 0 : } else { 85 : // The 1st level tag is already present 86 : // Add the 2nd level tag if needed 87 0 : DbHandler::AttribMap &amap = di->second.second; 88 0 : if (sval.type != DbHandler::INVALID) { 89 0 : if (amap.find(sname) == amap.end()) { 90 0 : amap.insert(make_pair(sname, sval)); 91 : } 92 : } 93 : } 94 0 : } 95 : 96 : 97 : void 98 0 : StatWalker::Pop(void) { 99 0 : VIZD_ASSERT(!nodes_.empty()); 100 0 : DbHandler::AttribMap attribs = nodes_.back().attribs; 101 0 : DbHandler::TagMap attribs_tag; 102 : 103 0 : for (TagMap::const_iterator ti = top_tags_.begin(); 104 0 : ti != top_tags_.end(); ti++) { 105 0 : FillTag(&attribs_tag, &(*ti)); 106 : } 107 : 108 0 : string prename(""); 109 0 : for (vector<StatNode>::const_iterator ni = nodes_.begin(); 110 0 : ni != nodes_.end(); ni++) { 111 : 112 0 : const StatNode& ancestor = *ni; 113 0 : if (!prename.empty()) { 114 0 : prename.append("."); 115 : } 116 0 : prename.append(ancestor.name); 117 : 118 0 : for (TagMap::const_iterator ti = ancestor.tags.begin(); 119 0 : ti != ancestor.tags.end(); ti++) { 120 0 : FillTag(&attribs_tag, &(*ti)); 121 : } 122 : } 123 : 124 : // Take the final tags and also insert them as attribs 125 : // We may get duplicates ; the last value read will get used 126 0 : for (DbHandler::TagMap::const_iterator fi = attribs_tag.begin(); 127 0 : fi != attribs_tag.end(); fi++) { 128 0 : attribs.insert(make_pair(fi->first, fi->second.first)); 129 0 : attribs.insert(fi->second.second.begin(), fi->second.second.end()); 130 : } 131 0 : fn_(timestamp_, stat_name_, prename, attribs_tag, attribs); 132 0 : nodes_.pop_back(); 133 0 : } 134 : 135 0 : StatWalker::~StatWalker() { 136 0 : VIZD_ASSERT(nodes_.empty()); 137 0 : }