doc: dhcp-perf-guide.html dhcp-perf-guide.pdf
-mysql_ubench.o: mysql_ubench.cc mysql_ubench.h
+mysql_ubench.o: mysql_ubench.cc mysql_ubench.h benchmark.h
$(CXX) $< -c $(CFLAGS) $(MYSQL_CFLAGS)
benchmark.o: benchmark.cc benchmark.h
mysql_ubench: mysql_ubench.o benchmark.o
$(CXX) $< benchmark.o -o mysql_ubench $(CFLAGS) $(MYSQL_CFLAGS) $(LDFLAGS) $(MYSQL_LDFLAGS)
-sqlite_ubench.o: sqlite_ubench.cc sqlite_ubench.h
+sqlite_ubench.o: sqlite_ubench.cc sqlite_ubench.h benchmark.h
$(CXX) $< -c $(CFLAGS) $(SQLLITE_CFLAGS)
sqlite_ubench: sqlite_ubench.o benchmark.o
$(CXX) $< benchmark.o -o sqlite_ubench $(CFLAGS) $(SQLITE_CFLAGS) $(LDFLAGS) $(SQLITE_LDFLAGS)
-memfile_ubench.o: memfile_ubench.cc memfile_ubench.h
+memfile_ubench.o: memfile_ubench.cc memfile_ubench.h benchmark.h
$(CXX) $< -c $(CFLAGS) $(MEMFILE_CFLAGS)
memfile_ubench: memfile_ubench.o benchmark.o
#include <iostream>
#include <stdlib.h>
#include <string.h>
+#include <boost/lexical_cast.hpp>
#include "benchmark.h"
using namespace std;
const std::string& host /* = "" */,
const std::string& user /* = "" */,
const std::string& pass /* = "" */)
- :Num_(iterations), Sync_(sync), Verbose_(verbose),
- Hostname_(host), User_(user), Passwd_(pass), DBName_(dbname)
+ :num_(iterations), sync_(sync), verbose_(verbose),
+ hostname_(host), user_(user), passwd_(pass), dbname_(dbname)
{
- memset(ts, 0, sizeof(ts));
+ /// @todo: convert this to user-configurable parameter
+ hitratio_ = 0.9f;
+ memset(ts_, 0, sizeof(ts_));
}
void uBenchmark::usage() {
case 'h':
usage();
case 'm':
- Hostname_ = string(optarg);
+ hostname_ = string(optarg);
break;
case 'u':
- User_ = string(optarg);
+ user_ = string(optarg);
break;
case 'p':
- Passwd_ = string(optarg);
+ passwd_ = string(optarg);
break;
case 'f':
- DBName_ = string(optarg);
+ dbname_ = string(optarg);
break;
case 'n':
- Num_ = strtol(optarg, NULL, 10);
- if (Num_ <= 0) {
+ try {
+ num_ = boost::lexical_cast<int>(optarg);
+ } catch (const boost::bad_lexical_cast &) {
cerr << "Failed to iterations (-n option)." << endl;
usage();
}
break;
case 's':
- if (!strcasecmp(optarg, "yes") || !strcmp(optarg, "1")) {
- Sync_ = true;
- } else {
- Sync_ = false;
- }
+ sync_ = !strcasecmp(optarg, "yes") || !strcmp(optarg, "1");
break;
case 'v':
- if (!strcasecmp(optarg, "yes") || !strcmp(optarg, "1")) {
- Verbose_ = true;
- } else {
- Verbose_ = false;
- }
+ verbose_ = !strcasecmp(optarg, "yes") || !strcmp(optarg, "1");
break;
- case ':':
default:
usage();
}
int uBenchmark::run() {
cout << "Starting test. Parameters:" << endl
- << "Number of iterations : " << Num_ << endl
- << "Sync/async : " << (Sync_ ? "sync" : "async") << endl
- << "Verbose : " << (Verbose_ ? "verbose" : "quiet") << endl
- << "Database name : " << DBName_ << endl
- << "MySQL hostname : " << Hostname_ << endl
- << "MySQL username : " << User_ << endl
- << "MySQL password : " << Passwd_ << endl << endl;
+ << "Number of iterations : " << num_ << endl
+ << "Sync/async : " << (sync_ ? "sync" : "async") << endl
+ << "Verbose : " << (verbose_ ? "verbose" : "quiet") << endl
+ << "Database name : " << dbname_ << endl
+ << "MySQL hostname : " << hostname_ << endl
+ << "MySQL username : " << user_ << endl
+ << "MySQL password : " << passwd_ << endl << endl;
srandom(time(NULL));
try {
connect();
- clock_gettime(CLOCK_REALTIME, &ts[0]);
+ clock_gettime(CLOCK_REALTIME, &ts_[0]);
createLease4Test();
- clock_gettime(CLOCK_REALTIME, &ts[1]);
+ clock_gettime(CLOCK_REALTIME, &ts_[1]);
searchLease4Test();
- clock_gettime(CLOCK_REALTIME, &ts[2]);
+ clock_gettime(CLOCK_REALTIME, &ts_[2]);
updateLease4Test();
- clock_gettime(CLOCK_REALTIME, &ts[3]);
+ clock_gettime(CLOCK_REALTIME, &ts_[3]);
deleteLease4Test();
- clock_gettime(CLOCK_REALTIME, &ts[4]);
+ clock_gettime(CLOCK_REALTIME, &ts_[4]);
disconnect();
return (-1);
}
- print_clock("Create leases4", Num_, ts[0], ts[1]);
- print_clock("Search leases4", Num_, ts[1], ts[2]);
- print_clock("Update leases4", Num_, ts[2], ts[3]);
- print_clock("Delete leases4", Num_, ts[3], ts[4]);
+ print_clock("Create leases4", num_, ts_[0], ts_[1]);
+ print_clock("Search leases4", num_, ts_[1], ts_[2]);
+ print_clock("Update leases4", num_, ts_[2], ts_[3]);
+ print_clock("Delete leases4", num_, ts_[3], ts_[4]);
return (0);
}
void usage();
/// Number of operations (e.g. insert lease num times)
- uint32_t Num_;
+ uint32_t num_;
/// Synchronous or asynchonous mode?
- bool Sync_;
+ bool sync_;
/// Should the test print out extra information?
- bool Verbose_;
+ bool verbose_;
// 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
+ 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
+
+ /// @brief hit ratio for search test (must be between 0.0 and 1.0)
+ ///
+ /// This parameter is used in seatch. The formula causes the search
+ /// to find something a lease in 90% cases of hit ratio is 0.9.
+ ///
+ float hitratio_;
/// 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)
- struct timespec ts[5];
+ struct timespec ts_[5];
};
#endif
Lease4Ptr memfile_LeaseMgr::getLease(uint32_t addr) {
leaseIt x = ip4Hash_.find(addr);
- if (x != ip4Hash_.end())
+ if (x != ip4Hash_.end()) {
return x->second; // found
+ }
// not found
return Lease4Ptr();
uint32_t num_iterations,
bool sync,
bool verbose)
- :uBenchmark(num_iterations, filename, sync, verbose),
- Filename_(filename) {
-
+ :uBenchmark(num_iterations, filename, sync, verbose) {
}
void memfile_uBenchmark::connect() {
try {
- LeaseMgr_ = new memfile_LeaseMgr(Filename_, Sync_);
+ leaseMgr_ = new memfile_LeaseMgr(dbname_, sync_);
} catch (const std::string& e) {
failure(e.c_str());
}
}
void memfile_uBenchmark::disconnect() {
- delete LeaseMgr_;
- LeaseMgr_ = NULL;
+ delete leaseMgr_;
+ leaseMgr_ = NULL;
}
void memfile_uBenchmark::createLease4Test() {
- if (!LeaseMgr_) {
+ if (!leaseMgr_) {
throw "No LeaseMgr instantiated.";
}
}
vector<uint8_t> client_id(client_id_tmp, client_id_tmp + 19);
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
cltt++;
lease->fqdn_fwd = fqdn_fwd;
lease->fqdn_rev = fqdn_rev;
- if (!LeaseMgr_->addLease(lease)) {
+ if (!leaseMgr_->addLease(lease)) {
failure("addLease() failed");
} else {
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
};
}
void memfile_uBenchmark::searchLease4Test() {
- if (!LeaseMgr_) {
+ if (!leaseMgr_) {
throw "No LeaseMgr instantiated.";
}
printf("RETRIEVE: ");
- for (uint32_t i = 0; i < Num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % int(Num_ / hitRatio);
+ for (uint32_t i = 0; i < num_; i++) {
+ uint32_t x = BASE_ADDR4 + random() % int(num_ / hitRatio);
- Lease4Ptr lease = LeaseMgr_->getLease(x);
- if (Verbose_) {
+ Lease4Ptr lease = leaseMgr_->getLease(x);
+ if (verbose_) {
if (lease) {
printf(".");
} else {
}
void memfile_uBenchmark::updateLease4Test() {
- if (!LeaseMgr_) {
+ if (!leaseMgr_) {
throw "No LeaseMgr instantiated.";
}
time_t cltt = time(NULL);
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % Num_;
+ uint32_t x = BASE_ADDR4 + random() % num_;
- Lease4Ptr lease = LeaseMgr_->updateLease(x, cltt);
+ Lease4Ptr lease = leaseMgr_->updateLease(x, cltt);
if (!lease) {
stringstream tmp;
tmp << "UPDATE failed for lease " << hex << x << dec;
failure(tmp.str().c_str());
}
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
}
void memfile_uBenchmark::deleteLease4Test() {
- if (!LeaseMgr_) {
+ if (!leaseMgr_) {
throw "No LeaseMgr instantiated.";
}
printf("DELETE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
uint32_t x = BASE_ADDR4 + i;
- if (!LeaseMgr_->deleteLease(x)) {
+ if (!leaseMgr_->deleteLease(x)) {
stringstream tmp;
tmp << "UPDATE failed for lease " << hex << x << dec;
failure(tmp.str().c_str());
}
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
protected:
/// Lease Manager (concrete backend implementation, based on STL maps)
- memfile_LeaseMgr * LeaseMgr_;
-
- /// Name of the lease file.
- std::string Filename_;
+ memfile_LeaseMgr * leaseMgr_;
};
cout << "MySQL library init successful." << endl;
}
- if (!mysql_real_connect(Conn_, Hostname_.c_str(), User_.c_str(),
- Passwd_.c_str(), DBName_.c_str(), 0, NULL, 0)) {
+ if (!mysql_real_connect(Conn_, hostname_.c_str(), user_.c_str(),
+ passwd_.c_str(), dbname_.c_str(), 0, NULL, 0)) {
failure("connecting to MySQL server");
} else {
cout << "MySQL connection established." << endl;
}
q = "ALTER TABLE lease4 engine=";
- if (Sync_) {
+ if (sync_) {
q += "InnoDB";
} else {
q += "MyISAM";
client_id[i] = 33 + i;
}
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
stringstream cltt;
cltt << "2012-07-11 15:43:" << (i % 60);
// something failed.
failure("INSERT query");
} else {
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
};
throw "Not connected to MySQL server.";
}
- // this formula should roughly find something a lease in 90% cases
- float hitRatio = 0.9;
-
/* cout << "range=" << int(Num_ / hitRatio) << " minAddr=" << hex
<< BASE_ADDR4 << " maxAddr=" << BASE_ADDR4 + int(Num_ / hitRatio)
<< dec << endl; */
printf("RETRIEVE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % int(Num_ / hitRatio);
+ uint32_t x = BASE_ADDR4 + random() % int(num_ / hitratio_);
char query[2000];
sprintf(query, "SELECT lease_id,addr,hwaddr,client_id,valid_lft,"
}
mysql_free_result(result);
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
} else {
- if (Verbose_) {
+ if (verbose_) {
printf("x");
}
}
printf("UPDATE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % Num_;
+ uint32_t x = BASE_ADDR4 + random() % num_;
char query[2000];
sprintf(query, "UPDATE lease4 SET valid_lft=1002, cltt=now() WHERE addr=%d", x);
mysql_real_query(Conn_, query, strlen(query));
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
printf("DELETE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
uint32_t x = BASE_ADDR4 + i;
sprintf(query, "DELETE FROM lease4 WHERE addr=%d", x);
mysql_real_query(Conn_, query, strlen(query));
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
uint32_t num_iterations,
bool sync, bool verbose)
:uBenchmark(num_iterations, filename, sync, verbose),
- DB_(NULL) {
+ db_(NULL) {
}
void SQLite_uBenchmark::connect() {
- int result = sqlite3_open(DBName_.c_str(), &DB_);
+ int result = sqlite3_open(dbname_.c_str(), &db_);
if (result) {
- sqlite3_open(DBName_.c_str(), &DB_);
+ sqlite3_open(dbname_.c_str(), &db_);
failure("Failed to open DB file");
}
- sqlite3_exec(DB_, "DELETE FROM lease4", NULL, NULL, NULL);
+ sqlite3_exec(db_, "DELETE FROM lease4", NULL, NULL, NULL);
- if (Sync_) {
- sqlite3_exec(DB_, "PRAGMA synchronous = ON", NULL, NULL, NULL);
+ if (sync_) {
+ sqlite3_exec(db_, "PRAGMA synchronous = ON", NULL, NULL, NULL);
} else {
- sqlite3_exec(DB_, "PRAGMA synchronous = OFF", NULL, NULL, NULL);
+ sqlite3_exec(db_, "PRAGMA synchronous = OFF", NULL, NULL, NULL);
}
// see http://www.sqlite.org/pragma.html#pragma_journal_mode
// for detailed explanation. Available modes: DELETE, TRUNCATE,
// PERSIST, MEMORY, WAL, OFF
- sqlite3_exec(DB_, "PRAGMA journal_mode = OFF", NULL, NULL, NULL);
+ sqlite3_exec(db_, "PRAGMA journal_mode = OFF", NULL, NULL, NULL);
}
void SQLite_uBenchmark::disconnect() {
- if (DB_) {
- sqlite3_close(DB_);
- DB_ = NULL;
+ if (db_) {
+ sqlite3_close(db_);
+ db_ = NULL;
}
}
void SQLite_uBenchmark::createLease4Test() {
- if (!DB_) {
+ if (!db_) {
throw "SQLite connection is closed.";
}
// query formatting, let's get rid of it
client_id[127] = 0; // workaround
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
stringstream cltt;
cltt << "2012-07-11 15:43:" << (i % 60);
hostname.c_str(), (fqdn_fwd?"true":"false"), (fqdn_rev?"true":"false"));
// printf("QUERY=[%s]\n", query);
- int result = sqlite3_exec(DB_, query, NULL, 0, &errorMsg);
+ int result = sqlite3_exec(db_, query, NULL, 0, &errorMsg);
if (result != SQLITE_OK) {
stringstream tmp;
tmp << "INSERT error:" << errorMsg;
failure(tmp.str().c_str());
} else {
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
};
}
void SQLite_uBenchmark::searchLease4Test() {
- if (!DB_) {
+ if (!db_) {
throw "SQLite connection is closed.";
}
- // this formula should roughly find something a lease in 90% cases
- float hitRatio = 0.5;
-
printf("RETRIEVE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % int(Num_ / hitRatio);
+ uint32_t x = BASE_ADDR4 + random() % int(num_ / hitratio_);
char* errorMsg = NULL;
sprintf(query, "SELECT lease_id,addr,hwaddr,client_id,valid_lft,"
"cltt,pool_id,fixed,hostname,fqdn_fwd,fqdn_rev "
"FROM lease4 where addr=%d", x);
- int result = sqlite3_exec(DB_, query, search_callback, &cnt, &errorMsg);
+ int result = sqlite3_exec(db_, query, search_callback, &cnt, &errorMsg);
if (result != SQLITE_OK) {
stringstream tmp;
tmp << "SELECT failed: " << errorMsg;
}
if (cnt) {
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
} else {
- if (Verbose_) {
+ if (verbose_) {
printf("X");
}
}
}
void SQLite_uBenchmark::updateLease4Test() {
- if (!DB_) {
+ if (!db_) {
throw "SQLite connection is closed.";
}
printf("UPDATE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
- uint32_t x = BASE_ADDR4 + random() % Num_;
+ uint32_t x = BASE_ADDR4 + random() % num_;
char* errorMsg = NULL;
char query[2000];
sprintf(query, "UPDATE lease4 SET valid_lft=1002, cltt='now' WHERE addr=%d", x);
- int result = sqlite3_exec(DB_, query, NULL /* no callback here*/, 0, &errorMsg);
+ int result = sqlite3_exec(db_, query, NULL /* no callback here*/, 0, &errorMsg);
if (result != SQLITE_OK) {
stringstream tmp;
tmp << "UPDATE error:" << errorMsg;
failure(tmp.str().c_str());
}
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
}
void SQLite_uBenchmark::deleteLease4Test() {
- if (!DB_) {
+ if (!db_) {
throw "SQLite connection is closed.";
}
printf("DELETE: ");
- for (uint32_t i = 0; i < Num_; i++) {
+ for (uint32_t i = 0; i < num_; i++) {
uint32_t x = BASE_ADDR4 + i;
char* errorMsg = NULL;
char query[2000];
sprintf(query, "DELETE FROM lease4 WHERE addr=%d", x);
- int result = sqlite3_exec(DB_, query, NULL /* no callback here*/, 0, &errorMsg);
+ int result = sqlite3_exec(db_, query, NULL /* no callback here*/, 0, &errorMsg);
if (result != SQLITE_OK) {
stringstream tmp;
tmp << "DELETE error:" << errorMsg;
failure(tmp.str().c_str());
}
- if (Verbose_) {
+ if (verbose_) {
printf(".");
}
}
protected:
/// Handle to SQLite database connection.
- sqlite3 *DB_;
+ sqlite3 *db_;
};