|
@@ -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];
|
|
|
};
|
|
|
|