Parcourir la source

[2040] Benchmark.cc is now properly documented.

Tomek Mrugalski il y a 12 ans
Parent
commit
55aadc8382
2 fichiers modifiés avec 142 ajouts et 12 suppressions
  1. 1 3
      tests/tools/dhcp-ubench/benchmark.cc
  2. 141 9
      tests/tools/dhcp-ubench/benchmark.h

+ 1 - 3
tests/tools/dhcp-ubench/benchmark.cc

@@ -49,7 +49,7 @@ void uBenchmark::usage() {
     exit(EXIT_FAILURE);
 }
 
-bool uBenchmark::parseCmdline(int argc, char* const argv[]) {
+void uBenchmark::parseCmdline(int argc, char* const argv[]) {
     int ch;
 
     while ((ch = getopt(argc, argv, "hm:u:p:f:n:s:v:")) != -1) {
@@ -94,8 +94,6 @@ bool uBenchmark::parseCmdline(int argc, char* const argv[]) {
             usage();
         }
     }
-
-    return true;
 }
 
 void uBenchmark::failure(const char* operation) {

+ 141 - 9
tests/tools/dhcp-ubench/benchmark.h

@@ -18,47 +18,179 @@
 #ifndef BENCHMARK_H
 #define BENCHMARK_H
 
+/// @brief Micro-benchmark base class.
+///
+/// This class represents an abstract DHCP database backend benchmark.
+/// It is not intended to be used directly, but serves as a common
+/// denominator for specific backend benchmarks that are derived from
+/// it. Currently there are at least 3 benchmarks implemented that
+/// take advantage of it:
+/// - MySQL (MySQL_uBenchmark)
+/// - SQLite (SQLite_uBenchmark)
+/// - memfile (memfile_uBenchmark)
 class uBenchmark {
 public:
+
+    /// @brief the sole constructor, used by all derivated benchmarks
+    ///
+    /// @param iterations number of iterations of each step (insert, search,
+    ///                   update, delete)
+    /// @param dbname name of the database (that is backend-specific, either
+    ///               filename or DB name)
+    /// @param sync sync or async test mode
+    /// @param verbose should extra logging be enabled?
+    /// @param host some backends (currently only MySQL) need this (optional)
+    /// @param username some backends (currently only MySQL) need this (optional)
+    /// @param pass some backends (currently only MySQL) need this (optional)
     uBenchmark(uint32_t iterations, const std::string& dbname,
                bool sync, bool verbose,
                const std::string& host = "",
                const std::string& username = "",
                const std::string& pass = "");
 
+    /// @brief Prints version information about specific backend.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void printInfo() = 0;
+
+    /// @brief Opens a connection to the database.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void connect() = 0;
+
+    /// @brief Closes connection to the database.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void disconnect() = 0;
+
+    /// @brief Benchmarks IPv4 address lease creation.
+    ///
+    /// That benchmark method will be called first.
+    /// It is expected to create specific number of leases,
+    /// as specified by \ref Num_ parameter. Following
+    /// methods (searchLease4Test(), updateLease4Test(),
+    /// and deleteLease4Test()) assume that lease creation
+    /// is successful. The benchmark is expected to create leases
+    /// starting from BASE_ADDR4 and ending on BASE_ADDR4 + Num_.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void createLease4Test() = 0;
+
+    /// @brief Benchmarks IPv4 address lease search.
+    ///
+    /// This is the second benchmark in a series of four.
+    /// It is called after createLease4Test(), so it expects that the
+    /// database is populated with at least \ref Num_ leases.
+    /// It repeats search for a lease Num_ times.
+    ///
+    /// The algorithm randomly picks a lease with HitRatio_ (typically 90%)
+    /// chance of finding a lease. During typical DHCP operation the server
+    /// sometimes wants to check if specific lease is assigned or not and the
+    /// lease is sometimes not present (e.g. when randomly trying to pick a new
+    /// lease for a new client or doing confirm). Although rather unlikely,
+    /// cases when searching for non-existing leases may be more costly,
+    /// thus should be modelled.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void searchLease4Test() = 0;
+
+    /// @brief Benchmarks IPv4 address lease update.
+    ///
+    /// This is the third benchmark in a series of four.
+    /// It is called after createLease4Test(), so it expects that the
+    /// database is populated with at least \ref Num_ leases.
+    ///
+    /// In a normal DHCP operation, search and update operations are used
+    /// together, but for the benchmarking purposes they are executed
+    /// separately here. Once a lease is found, it is being updated. Typically
+    /// the update is just changing lease expiration timers, so that is what
+    /// the test does. It exploits the fact that there are Num_ leases
+    /// in the database, so it picks randomly an address from
+    /// BASE_ADDR4 ... BASE_ADDR4+Num_ range and has a guarantee for the lease
+    /// to be present.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void updateLease4Test() = 0;
+
+    /// @brief Benchmarks IPv4 address lease removal.
+    ///
+    /// This is the last benchmark in a series of four.
+    /// It is called after createLease4Test(), so it expects that the
+    /// database is populated with at least \ref Num_ leases.
+    ///
+    /// It is expected to iteratively delete all Num_ leases from
+    /// the database.
+    ///
+    /// The implementation is provided by the DB-specific class.
     virtual void deleteLease4Test() = 0;
 
+    /// @brief Utility function for reporting errors.
+    ///
+    /// Benchmarks should call that function when something goes wrong.
+    /// details of the problem must be passed as a parameter. As the benchmark
+    /// is not designed to recover from errors, reporting an error aborts
+    /// benchmark execution.
+    ///
+    /// @param operation description of the operation that caused failure
     virtual void failure(const char* operation);
 
+    /// @brief Prints elapsed time of a specific operation
+    ///
+    /// This method prints out elapsed time of a specific benchmark, together
+    /// with additional statistics.
+    ///
+    /// @param operation name of the operation (usually create, search, update, delete)
+    /// @param num number or iterations (used for statistics)
+    /// @param before timestamp before execution
+    /// @param after timestamp after execution
     void print_clock(const std::string& operation, uint32_t num,
                      const struct timespec& before,
                      const struct timespec& after);
 
+    /// @brief Main benchmark execution routine
+    ///
+    /// This method calls create, search, update and delete benchmarks
+    /// and measures appropriate timestamps in ts_ table.
+    ///
+    /// @return 0 if the run was successful, negative value if detected errors
     int run();
 
-    bool parseCmdline(int args, char* const argv[]);
+    /// @brief parses command-line parameters
+    ///
+    /// This method parses command-line parameters and sets up appropriate
+    /// values. It is ok to pass argc, argv from main() here.
+    ///
+    /// This method may not return if -h (help) was specified or invalid
+    /// arguments are passed. Appropriate error and help will be displayed
+    /// and the program will terminate.
+    ///
+    /// @param argc number of arguments
+    /// @param argv array to the arguments
+    void parseCmdline(int argc, char* const argv[]);
 
 protected:
+    /// @brief prints out command-line help (list of parameters + version)
     void usage();
 
-    uint32_t Num_; // number of operations (e.g. insert lease num times)
+    /// Number of operations (e.g. insert lease num times)
+    uint32_t Num_;
 
-    bool Sync_;  // synchronous or asynchonous mode?
+    /// Synchronous or asynchonous mode?
+    bool Sync_;
+
+    /// Should the test print out extra information?
     bool Verbose_;
-    std::string Hostname_;// used by MySQL only
-    std::string User_;    // used by MySQL only
-    std::string Passwd_;  // used by MySQL only
-    std::string DBName_;  // used by MySQL, SQLite and memfile
 
-    const static uint32_t BASE_ADDR4 = 0x01000000; // let's start from 1.0.0.0 address
+    // DB parameters
+    std::string Hostname_; // used by MySQL only
+    std::string User_;     // used by MySQL only
+    std::string Passwd_;   // used by MySQL only
+    std::string DBName_;   // used by MySQL, SQLite and memfile
+
+    /// benchmarks must generate the leases starting from 1.0.0.0 address
+    const static uint32_t BASE_ADDR4 = 0x01000000;
 
-    // five timestamps (1 at the beginning and 4 after each step)
+    /// five timestamps (1 at the beginning and 4 after each step)
     struct timespec ts[5];
 };