stats_mgr.h 31.2 KB
 Marcin Siodelski committed Jul 10, 2012 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #ifndef __STATS_MGR_H #define __STATS_MGR_H  Marcin Siodelski committed Jul 11, 2012 18 #include  Marcin Siodelski committed Jul 10, 2012 19 20 21 22 23 #include #include #include #include  Marcin Siodelski committed Jul 12, 2012 24 #include  Marcin Siodelski committed Jul 10, 2012 25 26 #include #include  Marcin Siodelski committed Jul 12, 2012 27 #include  Marcin Siodelski committed Jul 10, 2012 28 #include  Marcin Siodelski committed Jul 10, 2012 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54  #include namespace isc { namespace perfdhcp { /// \brief Statistics Manager /// /// This class template is a storage for various performance statistics /// collected during performance tests execution with perfdhcp tool. /// /// Statistics Manager holds lists of sent and received packets and /// groups them into exchanges. For example: DHCPDISCOVER message and /// corresponding DHCPOFFER messages belong to one exchange, DHCPREQUEST /// and corresponding DHCPACK message belong to another exchange etc. /// In order to update statistics for a particular exchange type, client /// class passes sent and received packets. Internally, Statistics Manager /// tries to match transaction id of received packet with sent packet /// stored on the list of sent packets. When packets are matched the /// round trip time can be calculated. /// /// \tparam T class representing DHCPv4 or DHCPv6 packet. template class StatsMgr : public boost::noncopyable { public:  Marcin Siodelski committed Jul 19, 2012 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116  /// \brief Custom Counter /// /// This class represents custom statistics counters. Client class /// may create unlimited number of counters. Such counters are /// being stored in map in Statistics Manager and access using /// unique string key. class CustomCounter { public: /// \brief Constructor. /// /// This constructor sets counter name. This name is used in /// log file to report value of each counter. /// /// \param name name of the counter used in log file. CustomCounter(const std::string& name) : counter_(0), name_(name) { }; /// \brief Increment operator. const CustomCounter& operator++() { ++counter_; return *this; } /// \brief Increment operator. const CustomCounter& operator++(int) { CustomCounter& this_counter(*this); operator++(); return this_counter; } /// \brief Return counter value. /// /// Method returns counter value. /// /// \return counter value. uint64_t getValue() const { return counter_; } /// \brief Return counter name. /// /// Method returns counter name. /// /// \return counter name. const std::string& getName() const { return name_; } private: /// \brief Default constructor. /// /// Default constrcutor is private because we don't want client /// class to call it because we want client class to specify /// counter's name. CustomCounter() { }; uint64_t counter_; ///< Counter's value. std::string name_; ///< Counter's name. }; typedef typename boost::shared_ptr CustomCounterPtr;  Marcin Siodelski committed Jul 10, 2012 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134  /// DHCP packet exchange types. enum ExchangeType { XCHG_DO, ///< DHCPv4 DISCOVER-OFFER XCHG_RA, ///< DHCPv4 REQUEST-ACK XCHG_SA, ///< DHCPv6 SOLICIT-ADVERTISE XCHG_RR ///< DHCPv6 REQUEST-REPLY }; /// \brief Exchange Statistics. /// /// This class collects statistics for exchanges. Parent class /// may define number of different packet exchanges like: /// DHCPv4 DISCOVER-OFFER, DHCPv6 SOLICIT-ADVERTISE etc. Performance /// statistics will be collected for each of those separately in /// corresponding instance of ExchangeStats. class ExchangeStats { public:  Marcin Siodelski committed Jul 12, 2012 135 136 137 138  static uint32_t transid_hash(boost::shared_ptr packet) { return packet->getTransid() & 1023; }  Marcin Siodelski committed Jul 10, 2012 139 140 141 142 143 144 145 146 147  /// \brief List of packets (sent or received). /// /// List of packets based on multi index container allows efficient /// search of packets based on their sequence (order in which they /// were inserted) as well as based on packet transaction id. typedef boost::multi_index_container< boost::shared_ptr, boost::multi_index::indexed_by< boost::multi_index::sequenced<>,  Marcin Siodelski committed Jul 12, 2012 148  boost::multi_index::hashed_non_unique<  Marcin Siodelski committed Jul 12, 2012 149  boost::multi_index::global_fun<  150 151 152  boost::shared_ptr, uint32_t, &ExchangeStats::transid_hash  Marcin Siodelski committed Jul 12, 2012 153  >  Marcin Siodelski committed Jul 10, 2012 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169  > > > PktList; /// Packet list iterator for sequencial access to elements. typedef typename PktList::iterator PktListIterator; /// Packet list index to search packets using transaction id. typedef typename PktList::template nth_index<1>::type PktListTransidIndex; /// Packet list iterator to access packets using transaction id. typedef typename PktListTransidIndex::iterator PktListTransidIterator; /// \brief Constructor /// /// \param xchg_type exchange type ExchangeStats(const ExchangeType xchg_type)  Marcin Siodelski committed Jul 11, 2012 170 171 172 173 174  : xchg_type_(xchg_type), min_delay_(std::numeric_limits::max()), max_delay_(0.), sum_delay_(0.), orphans_(0),  Marcin Siodelski committed Jul 12, 2012 175 176 177  square_sum_delay_(0.), ordered_lookups_(0), unordered_lookup_size_sum_(0),  178 179 180  unordered_lookups_(0), sent_packets_num_(0), rcvd_packets_num_(0) {  Marcin Siodelski committed Jul 10, 2012 181 182 183 184 185 186 187  sent_packets_cache_ = sent_packets_.begin(); } /// \brief Add new packet to list of sent packets. /// /// Method adds new packet to list of sent packets. ///  Marcin Siodelski committed Jul 12, 2012 188  /// \param packet packet object to be added.  Marcin Siodelski committed Jul 10, 2012 189  void appendSent(const boost::shared_ptr packet) {  190  ++sent_packets_num_;  Marcin Siodelski committed Jul 10, 2012 191 192 193  sent_packets_.template get<0>().push_back(packet); }  Marcin Siodelski committed Jul 12, 2012 194 195 196 197 198 199  /// \brief Add new packet to list of received packets. /// /// Method adds new packet to list of received packets. /// /// \param packet packet object to be added. void appendRcvd(const boost::shared_ptr packet) {  200  ++rcvd_packets_num_;  Marcin Siodelski committed Jul 12, 2012 201 202 203  rcvd_packets_.template get<0>().push_back(packet); }  204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248  /// \brief Update delay counters. /// /// Method updates delay counters based on timestamps of /// sent and received packets. /// /// \param sent_packet sent packet /// \param rcvd_packet received packet /// \throw isc::Unexpected if failed to calculate timestamps void updateDelays(const boost::shared_ptr sent_packet, const boost::shared_ptr rcvd_packet) { boost::posix_time::ptime sent_time = sent_packet->getTimestamp(); boost::posix_time::ptime rcvd_time = rcvd_packet->getTimestamp(); if (sent_time.is_not_a_date_time() || rcvd_time.is_not_a_date_time()) { isc_throw(Unexpected, "Timestamp must be set for sent and " "received packet to measure RTT"); } boost::posix_time::time_period period(sent_time, rcvd_time); // We don't bother calculating deltas in nanoseconds. It is much // more convenient to use seconds instead because we are going to // sum them up. double delta = static_cast(period.length().total_nanoseconds()) / 1e9; if (delta < 0) { isc_throw(Unexpected, "Sent packet's timestamp must not be " "greater than received packet's timestamp"); } // Record the minimum delay between sent and received packets. if (delta < min_delay_) { min_delay_ = delta; } // Record the maximum delay between sent and received packets. if (delta > max_delay_) { max_delay_ = delta; } // Update delay sum and square sum. That will be used to calculate // mean delays. sum_delay_ += delta; square_sum_delay_ += delta * delta; }  Marcin Siodelski committed Jul 10, 2012 249 250 251 252 253 254 255 256 257 258 259 260  /// \brief Find packet on the list of sent packets. /// /// Method finds packet with specified transaction id on the list /// of sent packets. It is used to match received packet with /// corresponding sent packet. /// Since packets from the server most often come in the same order /// as they were sent by client, this method will first check if /// next sent packet matches. If it doesn't, function will search /// the packet using indexing by transaction id. This reduces /// packet search time significantly. /// /// \param transid transaction id of the packet to search  Marcin Siodelski committed Jul 11, 2012 261 262  /// \return packet having specified transaction or NULL if packet /// not found  Marcin Siodelski committed Jul 10, 2012 263 264  boost::shared_ptr findSent(const uint32_t transid) { if (sent_packets_.size() == 0) {  265 266 267 268  // List of sent packets is empty so there is no sense // to continue looking fo the packet. It also means // that the received packet we got has no corresponding // sent packet so orphans counter has to be updated.  Marcin Siodelski committed Jul 11, 2012 269 270  ++orphans_; return boost::shared_ptr();  Marcin Siodelski committed Jul 10, 2012 271  } else if (sent_packets_cache_ == sent_packets_.end()) {  272 273 274  // Even if there are still many unmatched packets on the // list we might hit the end of it because of unordered // lookups. The next logical step is to reset cache.  Marcin Siodelski committed Jul 10, 2012 275 276 277  sent_packets_cache_ = sent_packets_.begin(); }  278 279  // With this variable we will be signalling success or failure // to find the packet.  Marcin Siodelski committed Jul 10, 2012 280  bool packet_found = false;  281 282 283 284 285 286  // Most likely responses are sent from the server in the same // order as client's requests to the server. We are caching // next sent packet and first try to match with it the next // incoming packet. We are successful if there is no // packet drop or out of order packets sent. This is actually // the fastest way to look for packets.  Marcin Siodelski committed Jul 10, 2012 287  if ((*sent_packets_cache_)->getTransid() == transid) {  Marcin Siodelski committed Jul 12, 2012 288  ++ordered_lookups_;  Marcin Siodelski committed Jul 10, 2012 289 290  packet_found = true; } else {  291 292 293 294  // If we are here, it means that we were unable to match the // next incoming packet with next sent packet so we need to // take a little more expensive approach to look packets using // alternative index (transaction id & 1023).  Marcin Siodelski committed Jul 10, 2012 295  PktListTransidIndex& idx = sent_packets_.template get<1>();  296 297 298 299 300 301  // Packets are grouped using trasaction id masking with value // of 1023. For instance, packets with transaction id equal to // 1, 1024 ... will belong to the same group (a.k.a. bucket). // When using alternative index we don't find the packet but // bucket of packets and need to iterate through the bucket // to find the one that has desired transaction id.  Marcin Siodelski committed Jul 12, 2012 302  std::pair p =  Marcin Siodelski committed Jul 12, 2012 303  idx.equal_range(transid & 1023);  304 305 306 307 308  // We want to keep statistics of unordered lookups to make // sure that there is a right balance before number of // unordered lookups and ordered lookups. If number of unordered // lookups is high it may mean that many packets are lost or // sent out of order.  Marcin Siodelski committed Jul 12, 2012 309  ++unordered_lookups_;  310 311 312  // We also want to keep the mean value of the bucket. The lower // bucket size the better. If bucket sizes appear to big we // might want to increase number of buckets.  Marcin Siodelski committed Jul 12, 2012 313 314 315 316 317 318 319 320 321  unordered_lookup_size_sum_ += std::distance(p.first, p.second); for (PktListTransidIterator it = p.first; it != p.second; ++it) { if ((*it)->getTransid() == transid) { packet_found = true; sent_packets_cache_ = sent_packets_.template project<0>(it); break; }  Marcin Siodelski committed Jul 10, 2012 322 323 324 325  } } if (!packet_found) {  326 327  // If we are here, it means that both ordered lookup and // unordered lookup failed. Searched packet is not on the list.  Marcin Siodelski committed Jul 11, 2012 328 329  ++orphans_; return boost::shared_ptr();  Marcin Siodelski committed Jul 10, 2012 330 331 332  } boost::shared_ptr sent_packet(*sent_packets_cache_);  333 334 335 336  // If packet was found, we assume it will be never searched // again. We want to delete this packet from the list to // improve performance of future searches. sent_packets_cache_ = eraseSent(sent_packets_cache_);  Marcin Siodelski committed Jul 10, 2012 337 338 339  return sent_packet; }  Marcin Siodelski committed Jul 10, 2012 340 341 342 343 344  /// \brief Return minumum delay between sent and received packet. /// /// Method returns minimum delay between sent and received packet. /// /// \return minimum delay between packets.  Marcin Siodelski committed Jul 10, 2012 345  double getMinDelay() const { return min_delay_; }  Marcin Siodelski committed Jul 10, 2012 346 347 348 349 350 351  /// \brief Return maxmimum delay between sent and received packet. /// /// Method returns maximum delay between sent and received packet. /// /// \return maximum delay between packets.  Marcin Siodelski committed Jul 10, 2012 352  double getMaxDelay() const { return max_delay_; }  Marcin Siodelski committed Jul 10, 2012 353 354 355 356 357 358  /// \brief Return sum of delays between sent and received packets. /// /// Method returns sum of delays between sent and received packets. /// /// \return sum of delays between sent and received packets.  Marcin Siodelski committed Jul 10, 2012 359  double getSumDelay() const { return sum_delay_; }  Marcin Siodelski committed Jul 10, 2012 360 361 362 363 364 365 366 367  /// \brief Return square sum of delays between sent and received /// packets. /// /// Method returns square sum of delays between sent and received /// packets. /// /// \return square sum of delays between sent and received packets.  Marcin Siodelski committed Jul 10, 2012 368  double getSquareSumDelay() const { return square_sum_delay_; }  Marcin Siodelski committed Jul 11, 2012 369 370 371 372 373 374 375 376 377  /// \brief Return number of orphant packets. /// /// Method returns number of received packets that had no matching /// sent packet. It is possible that such packet was late or not /// for us. /// /// \return number of orphant received packets. uint64_t getOrphans() const { return orphans_; }  Marcin Siodelski committed Jul 12, 2012 378 379 380 381 382 383 384 385 386  /// \brief Return average unordered lookup set size. /// /// Method returns average unordered lookup set size. /// This value is changes every time \findSet function uses /// unordered packet lookup using transaction id. /// /// \return average unordered lookup set size. double getAvgUnorderedLookupSetSize() const {  387 388 389  if (unordered_lookups_ == 0) { return 0.; }  Marcin Siodelski committed Jul 12, 2012 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413  return static_cast(unordered_lookup_size_sum_) / static_cast(unordered_lookups_); } /// \brief Return number of unordered sent packets lookups /// /// Method returns number of unordered sent packet lookups. /// Unordered lookup is used when received packet was sent /// out of order by server - transaction id of received /// packet does not match transaction id of next sent packet. /// /// \return number of unordered lookups. uint64_t getUnorderedLookups() const { return unordered_lookups_; } /// \brief Return number of ordered sent packets lookups /// /// Method returns number of ordered sent packet lookups. /// Ordered lookup is used when packets are received in the /// same order as they were sent to the server. /// If packets are skipped or received out of order, lookup /// function will use unordered lookup (with hash table). /// /// \return number of ordered lookups. uint64_t getOrderedLookups() const { return ordered_lookups_; }  414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432  /// \brief Return total number of sent packets /// /// Method returns total number of sent packets. /// /// \return number of sent packets. uint64_t getSentPacketsNum() const { return sent_packets_num_; } /// \brief Return total number of received packets /// /// Method returns total number of received packets. /// /// \return number of received packets. uint64_t getRcvdPacketsNum() const { return rcvd_packets_num_; }  Marcin Siodelski committed Jul 10, 2012 433 434 435 436  private: /// \brief Private default constructor. ///  Marcin Siodelski committed Jul 10, 2012 437  /// Default constructor is private because we want the client  Marcin Siodelski committed Jul 10, 2012 438 439 440  /// class to specify exchange type explicitely. ExchangeStats();  441 442 443 444 445 446 447 448 449 450 451 452  /// \brief Erase packet from the list of sent packets. /// /// Method erases packet from the list of sent packets. /// /// \param it iterator pointing to packet to be erased. /// \return iterator pointing to packet following erased /// packet or sent_packets_.end() if packet not found. PktListIterator eraseSent(const PktListIterator it) { return sent_packets_.template get<0>().erase(it); }  Marcin Siodelski committed Jul 10, 2012 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470  ExchangeType xchg_type_; ///< Packet exchange type. PktList sent_packets_; ///< List of sent packets. /// Iterator pointing to the packet on sent list which will most /// likely match next received packet. This is based on the /// assumption that server responds in order to incoming packets. PktListIterator sent_packets_cache_; PktList rcvd_packets_; ///< List of received packets. double min_delay_; ///< Minimum delay between sent ///< and received packets. double max_delay_; ///< Maximum delay between sent ///< and received packets. double sum_delay_; ///< Sum of delays between sent ///< and received packets. double square_sum_delay_; ///< Square sum of delays between ///< sent and recived packets.  Marcin Siodelski committed Jul 11, 2012 471 472  uint64_t orphans_; ///< Number of orphant received packets.  Marcin Siodelski committed Jul 12, 2012 473 474 475 476 477 478 479 480 481 482 483 484 485  /// Sum of unordered lookup sets. Needed to calculate mean size of /// lookup set. It is desired that number of unordered lookups is /// minimal for performance reasons. Tracking number of lookups and /// mean size of the lookup set should give idea of packets serach /// complexity. uint64_t unordered_lookup_size_sum_; uint64_t unordered_lookups_; ///< Number of unordered sent packets ///< lookups. uint64_t ordered_lookups_; ///< Number of ordered sent packets ///< lookups.  486 487  uint64_t sent_packets_num_; ///< Total number of sent packets. uint64_t rcvd_packets_num_; ///< Total number of received packets.  Marcin Siodelski committed Jul 10, 2012 488 489 490 491 492 493 494  }; /// Pointer to ExchangeStats. typedef boost::shared_ptr ExchangeStatsPtr; /// Map containing all specified exchange types. typedef typename std::map ExchangesMap; /// Iterator poiting to \ref ExchangesMap  Marcin Siodelski committed Jul 11, 2012 495  typedef typename ExchangesMap::const_iterator ExchangesMapIterator;  Marcin Siodelski committed Jul 19, 2012 496 497 498 499 500 501 502 503 504 505  /// Map containing custom counters. typedef typename std::map CustomCountersMap; /// Iterator for \ref CustomCountersMap. typedef typename CustomCountersMap::iterator CustomCountersMapIterator; /// \brief Constructor. StatsMgr() : exchanges_(), custom_counters_() { }  Marcin Siodelski committed Jul 10, 2012 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521  /// \brief Specify new exchange type. /// /// This method creates new \ref ExchangeStats object that will /// collect statistics data from packets exchange of the specified /// type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if exchange of specified type exists. void addExchangeStats(const ExchangeType xchg_type) { if (exchanges_.find(xchg_type) != exchanges_.end()) { isc_throw(BadValue, "Exchange of specified type already added."); } exchanges_[xchg_type] = ExchangeStatsPtr(new ExchangeStats(xchg_type)); }  Marcin Siodelski committed Jul 19, 2012 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564  /// \brief Add named custom uint64 counter. /// /// Method creates new named counter and stores in counter's map under /// key specified here as short_name. /// /// \param short_name key to use to access counter in the map. /// \param long_name name of the counter presented in the log file. void addCustomCounter(const std::string& short_name, const std::string& long_name) { if (custom_counters_.find(short_name) != custom_counters_.end()) { isc_throw(BadValue, "Custom counter " << short_name << " already added."); } custom_counters_[short_name] = CustomCounterPtr(new CustomCounter(long_name)); } /// \brief Return specified counter. /// /// Method returns specified counter. /// /// \param counter_key key poiting to the counter in the counters map. /// \return pointer to specified counter object. CustomCounterPtr getCounter(const std::string& counter_key) { CustomCountersMapIterator it = custom_counters_.find(counter_key); if (it == custom_counters_.end()) { isc_throw(BadValue, "Custom counter " << counter_key << "does not exist"); } return it->second; } /// \brief Increment specified counter. /// /// Increement counter value by one. /// /// \param counter_key key poitinh to the counter in the counters map. /// \return pointer to specified counter after incrementation. const CustomCounter& IncrementCounter(const std::string& counter_key) { CustomCounterPtr counter = getCounter(counter_key); return ++(*counter); }  Marcin Siodelski committed Jul 10, 2012 565 566 567 568 569 570 571 572 573 574 575  /// \brief Adds new packet to the sent packets list. /// /// Method adds new packet to the sent packets list. /// Packets are added to the list sequentially and /// most often read sequentially. /// /// \param xchg_type exchange type. /// \param packet packet to be added to the list /// \throw isc::BadValue if invalid exchange type specified. void passSentPacket(const ExchangeType xchg_type, const boost::shared_ptr packet) {  Marcin Siodelski committed Jul 11, 2012 576 577  ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); xchg_stats->appendSent(packet);  Marcin Siodelski committed Jul 10, 2012 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593  } /// \brief Add new received packet and match with sent packet. /// /// Method adds new packet to the list of received packets. It /// also searches for corresponding packet on the list of sent /// packets. When packets are matched the statistics counters /// are updated accordingly for the particular exchange type. /// /// \param xchg_type exchange type. /// \param packet received packet /// \throw isc::BadValue if invalid exchange type specified. /// \throw isc::Unexpected if corresponding packet was not /// found on the list of sent packets. void passRcvdPacket(const ExchangeType xchg_type, const boost::shared_ptr packet) {  Marcin Siodelski committed Jul 11, 2012 594 595 596 597 598 599  ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); boost::shared_ptr sent_packet = xchg_stats->findSent(packet->getTransid()); if (sent_packet) { xchg_stats->updateDelays(sent_packet, packet);  Marcin Siodelski committed Jul 12, 2012 600  xchg_stats->appendRcvd(packet);  Marcin Siodelski committed Jul 11, 2012 601 602 603  } }  604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656  /// \brief Return minumum delay between sent and received packet. /// /// Method returns minimum delay between sent and received packet /// for specified exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return minimum delay between packets. double getMinDelay(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getMinDelay(); } /// \brief Return maxmimum delay between sent and received packet. /// /// Method returns maximum delay between sent and received packet /// for specified exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return maximum delay between packets. double getMaxDelay(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getMaxDelay(); } /// \brief Return sum of delays between sent and received packets. /// /// Method returns sum of delays between sent and received packets /// for specified exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return sum of delays between sent and received packets. double getSumDelay(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getSumDelay(); } /// \brief Return square sum of delays between sent and received /// packets. /// /// Method returns square sum of delays between sent and received /// packets for specified exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return square sum of delays between sent and received packets. double getSquareSumDelay(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getSquareSumDelay(); }  Marcin Siodelski committed Jul 11, 2012 657 658 659 660 661 662 663 664 665 666 667 668  /// \brief Return number of orphant packets. /// /// Method returns number of orphant packets for specified /// exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return number of orphant packets so far. uint64_t getOrphans(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getOrphans(); }  Marcin Siodelski committed Jul 12, 2012 669 670 671 672 673 674 675 676  /// \brief Return average unordered lookup set size. /// /// Method returns average unordered lookup set size. /// This value is changes every time \findSet function uses /// unordered packet lookup using transaction id. /// /// \param xchg_type exchange type.  677  /// \throw isc::BadValue if invalid exchange type specified.  Marcin Siodelski committed Jul 12, 2012 678 679 680 681 682 683 684 685 686 687 688 689 690  /// \return average unordered lookup set size. double getAvgUnorderedLookupSetSize(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getAvgUnorderedLookupSetSize(); } /// \brief Return number of unordered sent packets lookups /// /// Method returns number of unordered sent packet lookups. /// Unordered lookup is used when received packet was sent /// out of order by server - transaction id of received /// packet does not match transaction id of next sent packet. ///  691 692  /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified.  Marcin Siodelski committed Jul 12, 2012 693 694 695 696 697 698 699 700 701 702 703 704 705 706  /// \return number of unordered lookups. uint64_t getUnorderedLookups(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getUnorderedLookups(); } /// \brief Return number of ordered sent packets lookups /// /// Method returns number of ordered sent packet lookups. /// Ordered lookup is used when packets are received in the /// same order as they were sent to the server. /// If packets are skipped or received out of order, lookup /// function will use unordered lookup (with hash table). ///  707 708  /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified.  Marcin Siodelski committed Jul 12, 2012 709 710 711 712 713 714  /// \return number of ordered lookups. uint64_t getOrderedLookups(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getOrderedLookups(); }  715 716 717 718 719 720 721 722 723 724 725 726  /// \brief Return total number of sent packets /// /// Method returns total number of sent packets for specified /// exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return number of sent packets. uint64_t getSentPacketsNum(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getSentPacketsNum(); }  Marcin Siodelski committed Jul 11, 2012 727   728 729 730 731 732 733 734 735 736 737 738 739  /// \brief Return total number of received packets /// /// Method returns total number of received packets for specified /// exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return number of received packets. uint64_t getRcvdPacketsNum(const ExchangeType xchg_type) const { ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type); return xchg_stats->getRcvdPacketsNum(); }  Marcin Siodelski committed Jul 19, 2012 740   741 private:  Marcin Siodelski committed Jul 11, 2012 742 743 744 745 746 747 748 749  /// \brief Return exchange stats object for given exchange type /// /// Method returns exchange stats object for given exchange type. /// /// \param xchg_type exchange type. /// \throw isc::BadValue if invalid exchange type specified. /// \return exchange stats object. ExchangeStatsPtr getExchangeStats(const ExchangeType xchg_type) const {  Marcin Siodelski committed Jul 10, 2012 750 751 752 753  ExchangesMapIterator it = exchanges_.find(xchg_type); if (it == exchanges_.end()) { isc_throw(BadValue, "Packets exchange not specified"); }  Marcin Siodelski committed Jul 10, 2012 754  ExchangeStatsPtr xchg_stats = it->second;  Marcin Siodelski committed Jul 11, 2012 755  return xchg_stats;  Marcin Siodelski committed Jul 10, 2012 756 757  }  Marcin Siodelski committed Jul 19, 2012 758 759  ExchangesMap exchanges_; ///< Map of exchange types. CustomCountersMap custom_counters_; ///< Map with custom counters.  Marcin Siodelski committed Jul 10, 2012 760 761 762 763 764 765 }; } // namespace perfdhcp } // namespace isc #endif // __STATS_MGR_H