BIND 10 trac2040, updated. 2ebd8cf46447c014945cbc5059671ee72c316b30 [2040] All benchmark classes are now documented.
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Aug 20 13:41:09 UTC 2012
The branch, trac2040 has been updated
via 2ebd8cf46447c014945cbc5059671ee72c316b30 (commit)
via 55aadc83821f7fd33fc93265f47f978895d4f0d4 (commit)
from 3c23e2fd8ecc4cf1f52f40d929c4846b7b243b4f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2ebd8cf46447c014945cbc5059671ee72c316b30
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Mon Aug 20 15:40:37 2012 +0200
[2040] All benchmark classes are now documented.
commit 55aadc83821f7fd33fc93265f47f978895d4f0d4
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Mon Aug 20 13:52:05 2012 +0200
[2040] Benchmark.cc is now properly documented.
-----------------------------------------------------------------------
Summary of changes:
tests/tools/dhcp-ubench/benchmark.cc | 4 +-
tests/tools/dhcp-ubench/benchmark.h | 150 +++++++++++++++++++++++++++--
tests/tools/dhcp-ubench/memfile_ubench.cc | 67 +++++++++++--
tests/tools/dhcp-ubench/memfile_ubench.h | 74 +++++++++++---
tests/tools/dhcp-ubench/mysql_ubench.h | 50 ++++++++++
tests/tools/dhcp-ubench/sqlite_ubench.cc | 4 -
tests/tools/dhcp-ubench/sqlite_ubench.h | 40 +++++++-
7 files changed, 350 insertions(+), 39 deletions(-)
-----------------------------------------------------------------------
diff --git a/tests/tools/dhcp-ubench/benchmark.cc b/tests/tools/dhcp-ubench/benchmark.cc
index 663d158..09eeea7 100644
--- a/tests/tools/dhcp-ubench/benchmark.cc
+++ b/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) {
diff --git a/tests/tools/dhcp-ubench/benchmark.h b/tests/tools/dhcp-ubench/benchmark.h
index 09713f3..d051047 100644
--- a/tests/tools/dhcp-ubench/benchmark.h
+++ b/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];
};
diff --git a/tests/tools/dhcp-ubench/memfile_ubench.cc b/tests/tools/dhcp-ubench/memfile_ubench.cc
index 7bb47ae..39f952a 100644
--- a/tests/tools/dhcp-ubench/memfile_ubench.cc
+++ b/tests/tools/dhcp-ubench/memfile_ubench.cc
@@ -20,26 +20,81 @@
using namespace std;
+/// @brief In-memory + lease file database implementation
+///
+/// This is a simplified in-memory database that mimics ISC DHCP4 implementation.
+/// It uses STL and boost: std::map for storage, boost::shared ptr for memory
+/// management. It does use C file operations (fopen, fwrite, etc.), because
+/// C++ streams does not offer any easy way to flush their contents, like
+/// fflush() and fsync() does.
+///
+/// IPv4 address is used as a key in the hash.
class memfile_LeaseMgr {
public:
-typedef std::map<uint32_t /* addr */, Lease4Ptr /* lease info */> IPv4Hash;
-typedef std::map<uint32_t, Lease4Ptr>::iterator leaseIt;
+
+ /// A hash table for Lease4 leases.
+ typedef std::map<uint32_t /* addr */, Lease4Ptr /* lease info */> IPv4Hash;
+
+ /// An iterator for Lease4 hash table.
+ typedef std::map<uint32_t, Lease4Ptr>::iterator leaseIt;
+
+ /// @brief The sole memfile lease manager constructor
+ ///
+ /// @param filename name of the lease file (will be overwritten)
+ /// @param sync should operations be
memfile_LeaseMgr(const std::string& filename, bool sync);
+
+ /// @brief Destructor (closes file)
~memfile_LeaseMgr();
+
+ /// @brief adds a lease to the hash
+ ///
+ /// @param lease lease to be added
bool addLease(Lease4Ptr lease);
+
+ /// @brief returns existing lease
+ ///
+ /// @param addr address of the searched lease
+ ///
+ /// @return smart pointer to the lease (or NULL if lease is not found)
Lease4Ptr getLease(uint32_t addr);
+
+ /// @brief Simplified lease update.
+ ///
+ /// Searches for a lease and then updates its client last transmission
+ /// time. Writes new lease content to lease file (and calls fflush()/fsync(),
+ /// if synchronous operation is enabled).
+ ///
+ /// @param addr IPv4 address
+ /// @param new_cltt New client last transmission time
+ ///
+ /// @return pointer to the updated lease (or NULL)
Lease4Ptr updateLease(uint32_t addr, uint32_t new_cltt);
+
+ /// @brief Deletes a lease.
+ ///
+ /// @param addr IPv4 address of the lease to be deleted.
+ ///
+ /// @return true if deletion was successful, false if no such lease exists
bool deleteLease(uint32_t addr);
protected:
+ /// @brief Writes updated lease to a file.
+ ///
+ /// @param lease lease to be written
void writeLease(Lease4Ptr lease);
+ /// Name of the lease file.
std::string Filename_;
- bool Sync_; // should we do flush after each operation?
- // we have to use fe
+ /// should we do flush after each operation?
+ bool Sync_;
+
+ /// File handle to the open lease file.
FILE * File_;
+
+ /// Hash table for IPv4 leases
IPv4Hash ip4Hash_;
};
@@ -132,10 +187,6 @@ memfile_uBenchmark::memfile_uBenchmark(const string& filename,
}
-void memfile_uBenchmark::failure(const char* operation) {
- throw string(operation);
-}
-
void memfile_uBenchmark::connect() {
try {
LeaseMgr_ = new memfile_LeaseMgr(Filename_, Sync_);
diff --git a/tests/tools/dhcp-ubench/memfile_ubench.h b/tests/tools/dhcp-ubench/memfile_ubench.h
index 45d93ac..250949f 100644
--- a/tests/tools/dhcp-ubench/memfile_ubench.h
+++ b/tests/tools/dhcp-ubench/memfile_ubench.h
@@ -18,43 +18,89 @@
#include <boost/shared_ptr.hpp>
#include "benchmark.h"
+/// @brief Structure of the Lease4 that is kept in memory
struct Lease4 {
- uint32_t addr;
- std::vector<uint8_t> hwaddr;
- std::vector<uint8_t> client_id;
- uint32_t valid_lft;
- uint32_t recycle_time;
- time_t cltt;
- uint32_t pool_id;
- bool fixed;
- std::string hostname;
- bool fqdn_fwd;
- bool fqdn_rev;
- std::string options;
- std::string comments;
+ uint32_t addr; /// IPv4 address
+ std::vector<uint8_t> hwaddr; /// hardware address
+ std::vector<uint8_t> client_id; /// client-identifier
+ uint32_t valid_lft; /// valid lifetime timestamp
+ uint32_t recycle_time; /// timer for keeping lease after expiration/release
+ /// (currently not used)
+ time_t cltt; /// client last transmission time
+ uint32_t pool_id; /// ID of the pool the lease belongs to
+ bool fixed; /// is this lease fixed?
+ std::string hostname; /// client hostname (may be empty)
+ bool fqdn_fwd; /// did we do AAAA update for this lease?
+ bool fqdn_rev; /// did we do PTR update for this lease?
+ std::string options; /// additional options stored with this lease
+ /// (currently not used)
+ std::string comments; /// comments on that lease
+ /// (currently not used)
};
+/// Pointer to a Lease4 structure
typedef boost::shared_ptr<Lease4> Lease4Ptr;
+/// an implementation of in-memory+file database
+/// The actual implementation is in memfile_ubench.cc
class memfile_LeaseMgr;
+/// @brief In-memory + file micro-benchmark.
+///
+/// That is a specific backend implementation. See \ref uBenchmark class for
+/// detailed explanation of its operations. This class uses custom in-memory
+/// pseudo-database and external write-only lease file. That approach simulates
+/// modernized model of ISC DHCP4. It uses standard STL maps together with
+/// shared_ptr from boost library. The "database" is implemented in the Lease
+/// Manager (see \ref LeaseMgr in memfile_ubench.cc). All lease changes are
+/// appended to the end of the file, speeding up the process.
class memfile_uBenchmark: public uBenchmark {
public:
+
+ /// @brief The sole memfile benchmark constructor.
+ ///
+ /// @param filename name of the write-only lease file
+ /// @param num_iterations number of iterations
+ /// @param sync should fsync() be called after every file write?
+ /// @param verbose would you like extra logging?
memfile_uBenchmark(const std::string& filename,
uint32_t num_iterations, bool sync, bool verbose);
+ /// @brief Prints backend info.
virtual void printInfo();
+
+ /// @brief Spawns lease manager that create empty lease file, initializes
+ /// empty STL maps.
virtual void connect();
+
+ /// @brief Delete lease manager that closes lease file.
virtual void disconnect();
+
+ /// @brief Creates new leases.
+ ///
+ /// See uBenchmark::createLease4Test() for detailed explanation.
virtual void createLease4Test();
+
+ /// @brief Searches for existing leases.
+ ///
+ /// See uBenchmark::searchLease4Test() for detailed explanation.
virtual void searchLease4Test();
+
+ /// @brief Updates existing leases.
+ ///
+ /// See uBenchmark::updateLease4Test() for detailed explanation.
virtual void updateLease4Test();
+
+ /// @brief Deletes existing leases.
+ ///
+ /// See uBenchmark::deleteLease4Test() for detailed explanation.
virtual void deleteLease4Test();
protected:
- void failure(const char* operation);
+ /// Lease Manager (concrete backend implementation, based on STL maps)
memfile_LeaseMgr * LeaseMgr_;
+ /// Name of the lease file.
std::string Filename_;
};
diff --git a/tests/tools/dhcp-ubench/mysql_ubench.h b/tests/tools/dhcp-ubench/mysql_ubench.h
index c2c33d4..9bba808 100644
--- a/tests/tools/dhcp-ubench/mysql_ubench.h
+++ b/tests/tools/dhcp-ubench/mysql_ubench.h
@@ -15,23 +15,73 @@
#include <string>
#include "benchmark.h"
+/// @brief MySQL micro-benchmark.
+///
+/// That is a specific backend implementation. See \ref uBenchmark class for
+/// detailed explanation of its operations. This class uses MySQL as database
+/// backend.
class MySQL_uBenchmark: public uBenchmark {
public:
+
+ /// @brief The sole MySQL micro-benchmark constructor
+ ///
+ /// To avoid influence of network performance, it is highly recommended
+ /// to run MySQL engine on the same host as benchmark. Thus hostname
+ /// is likely to be "localhost". Make sure that the selected database
+ /// is already created and that it follows expected schema. See mysql.schema
+ /// and isc-dhcp-perf-guide.html for details.
+ ///
+ /// Synchronous operation means using InnDB, async is MyISAM.
+ ///
+ /// @param hostname Name of the hostname to connect to
+ /// @param user usename used during MySQL connection
+ /// @param pass password used during MySQL connection
+ /// @param db name of the database to connect to
+ /// @param num_iterations number of iterations for basic operations
+ /// @param sync synchronous or asynchronous database writes
+ /// @param verbose should extra information be logged?
MySQL_uBenchmark(const std::string& hostname, const std::string& user,
const std::string& pass, const std::string& db,
uint32_t num_iterations, bool sync,
bool verbose);
+ /// @brief Prints MySQL version info.
virtual void printInfo();
+
+ /// @brief Opens connection to the MySQL database.
virtual void connect();
+
+ /// @brief Closes connection to the MySQL database.
virtual void disconnect();
+
+ /// @brief Creates new leases.
+ ///
+ /// See uBenchmark::createLease4Test() for detailed explanation.
virtual void createLease4Test();
+
+ /// @brief Searches for existing leases.
+ ///
+ /// See uBenchmark::searchLease4Test() for detailed explanation.
virtual void searchLease4Test();
+
+ /// @brief Updates existing leases.
+ ///
+ /// See uBenchmark::updateLease4Test() for detailed explanation.
virtual void updateLease4Test();
+
+ /// @brief Deletes existing leases.
+ ///
+ /// See uBenchmark::deleteLease4Test() for detailed explanation.
virtual void deleteLease4Test();
protected:
+ /// @brief Used to report any database failures.
+ ///
+ /// Compared to its base version in uBenchmark class, this one logs additional
+ /// MySQL specific information using mysql_errno() and mysql_error() functions.
+ /// The outcome is the same: exception is thrown.
void failure(const char* operation);
+ /// Handle to MySQL database connection.
MYSQL* Conn_;
};
diff --git a/tests/tools/dhcp-ubench/sqlite_ubench.cc b/tests/tools/dhcp-ubench/sqlite_ubench.cc
index 9974a3c..001762a 100644
--- a/tests/tools/dhcp-ubench/sqlite_ubench.cc
+++ b/tests/tools/dhcp-ubench/sqlite_ubench.cc
@@ -31,10 +31,6 @@ SQLite_uBenchmark::SQLite_uBenchmark(const string& filename,
}
-void SQLite_uBenchmark::failure(const char* operation) {
- throw string(operation);
-}
-
void SQLite_uBenchmark::connect() {
int result = sqlite3_open(DBName_.c_str(), &DB_);
if (result) {
diff --git a/tests/tools/dhcp-ubench/sqlite_ubench.h b/tests/tools/dhcp-ubench/sqlite_ubench.h
index 8ef0860..a066ec9 100644
--- a/tests/tools/dhcp-ubench/sqlite_ubench.h
+++ b/tests/tools/dhcp-ubench/sqlite_ubench.h
@@ -15,22 +15,60 @@
#include <string>
#include "benchmark.h"
+/// @brief SQLite benchmark
+///
+/// That is a specific backend implementation. See \ref uBenchmark class for
+/// detailed explanation of its operations. This class uses SQLite as DB backend.
class SQLite_uBenchmark: public uBenchmark {
public:
+
+ /// @brief The sole SQL benchmark constructor
+ ///
+ /// DB file must be present and appropriate database schema must
+ /// be used. See sqlite.schema script and isc-dhcp-perf-guide.html
+ /// for details.
+ ///
+ /// sync flag affects "PRAGMA synchronous" to be ON or OFF.
+ ///
+ /// @param filename name of the SQLite DB file. Must be present.
+ /// @param num_iterations number of iterations of basic lease operations
+ /// @param sync should the operations be synchronous or not?
+ /// @param verbose would you like extra details be logged?
SQLite_uBenchmark(const std::string& filename,
uint32_t num_iterations,
bool sync, bool verbose);
+ /// @brief Prints SQLite version info.
virtual void printInfo();
+
+ /// @brief Opens connection to the SQLite database.
virtual void connect();
+
+ /// @brief Closes connection to the SQLite database.
virtual void disconnect();
+
+ /// @brief Creates new leases.
+ ///
+ /// See uBenchmark::createLease4Test() for detailed explanation.
virtual void createLease4Test();
+
+ /// @brief Searches for existing leases.
+ ///
+ /// See uBenchmark::searchLease4Test() for detailed explanation.
virtual void searchLease4Test();
+
+ /// @brief Updates existing leases.
+ ///
+ /// See uBenchmark::updateLease4Test() for detailed explanation.
virtual void updateLease4Test();
+
+ /// @brief Deletes existing leases.
+ ///
+ /// See uBenchmark::deleteLease4Test() for detailed explanation.
virtual void deleteLease4Test();
protected:
- void failure(const char* operation);
+ /// Handle to SQLite database connection.
sqlite3 *DB_;
};
More information about the bind10-changes
mailing list