summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Pavel <andrei.pavel@qualitance.com>2017-08-18 17:43:51 +0200
committerAndrei Pavel <andrei.pavel@qualitance.com>2017-08-18 17:44:05 +0200
commit29440ea06eaa1786242d38dc81be307312188787 (patch)
treeb4c4dc16482f6fadd9d6dba144aeb082ee441967
parentMerge branch 'cassandra-host-data-source' into cassandra-host-data-source-str... (diff)
downloadkea-29440ea06eaa1786242d38dc81be307312188787.tar.xz
kea-29440ea06eaa1786242d38dc81be307312188787.zip
Google Benchmark support
ReentrantSetUp* methods are needed because you can't control iteration count Usage: ./configure --with-benchmark OR ./configure --with-benchmark-source=/path/to/benchmark/src make cd src/lib/dhcpsrv/benchmarks ./run-benchmarks OR ./run-benchmarks --benchmark_filter="RegExP*"
-rw-r--r--.gitignore1
-rw-r--r--configure.ac127
-rw-r--r--ext/.gitignore3
-rw-r--r--ext/Makefile.am5
-rw-r--r--ext/benchmark/Makefile.am11
-rw-r--r--src/lib/dhcpsrv/Makefile.am2
-rw-r--r--src/lib/dhcpsrv/benchmarks/.gitignore2
-rw-r--r--src/lib/dhcpsrv/benchmarks/Makefile.am78
-rw-r--r--src/lib/dhcpsrv/benchmarks/cql_host_data_source_benchmark.cc176
-rw-r--r--src/lib/dhcpsrv/benchmarks/cql_lease_mgr_benchmark.cc192
-rw-r--r--src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.cc399
-rw-r--r--src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.h160
-rw-r--r--src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.cc259
-rw-r--r--src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h69
-rw-r--r--src/lib/dhcpsrv/benchmarks/mysql_host_data_source_benchmark.cc176
-rw-r--r--src/lib/dhcpsrv/benchmarks/mysql_lease_mgr_benchmark.cc192
-rw-r--r--src/lib/dhcpsrv/benchmarks/pgsql_host_data_source_benchmark.cc176
-rw-r--r--src/lib/dhcpsrv/benchmarks/pgsql_lease_mgr_benchmark.cc192
-rw-r--r--src/lib/dhcpsrv/benchmarks/run_benchmarks.cc32
-rw-r--r--src/lib/dhcpsrv/testutils/cql_schema.cc17
-rw-r--r--src/lib/dhcpsrv/testutils/mysql_schema.cc16
-rw-r--r--src/lib/dhcpsrv/testutils/pgsql_schema.cc18
22 files changed, 2275 insertions, 28 deletions
diff --git a/.gitignore b/.gitignore
index ea1f60bd51..9afda8d91e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,4 +45,3 @@ config.h.in~
/logger_lockfile
/report.info
-/ext/gtest/
diff --git a/configure.ac b/configure.ac
index 9ed9366c34..e9542bf23a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -588,6 +588,19 @@ if test "$lcov" != "no"; then
fi
AC_SUBST(USE_LCOV)
+enable_benchmark="no"
+BENCHMARK_INCLUDES=
+
+AC_ARG_WITH([benchmark-source],
+ [AS_HELP_STRING([--with-benchmark-source=PATH],
+ [location of the benchmark source])],
+ [enable_benchmark="yes" ; BENCHMARK_SOURCE="$withval"])
+
+AC_ARG_WITH([benchmark],
+ [AS_HELP_STRING([--with-benchmark=PATH],
+ [specify a path to benchmark header files (PATH/include) and library (PATH/lib)])],
+ [benchmark_path="$withval"; enable_benchmark="yes"], [benchmark_path="no"])
+
# Simplified, non-caching AC_CHECK_PROG
# Searches $PATH for the existence of argument 2,
# and sets the full path to the variable in argument 1.
@@ -1339,6 +1352,106 @@ AC_SUBST(GTEST_LDADD)
AC_SUBST(GTEST_SOURCE)
#
+# Check availability of benchmark.
+#
+BENCHMARK_LDFLAGS=
+BENCHMARK_LDADD=
+DISTCHECK_BENCHMARK_CONFIGURE_FLAG=
+BENCHMARK_VERSION="unknown"
+
+if test "x$enable_benchmark" = "xyes" ; then
+
+ DISTCHECK_BENCHMARK_CONFIGURE_FLAG="--with-benchmark=$benchmark_path"
+
+ if test -n "$with_benchmark_source" ; then
+
+ if test "x$BENCHMARK_SOURCE" = "xyes" ; then
+
+ AC_MSG_CHECKING([for benchmark source])
+ # If not specified, try some common paths.
+ BENCHMARK_SOURCE=
+ for d in /usr/src/benchmark /usr/local /usr/pkg /opt /opt/local ; do
+ if test -f $d/src/benchmark.cc; then
+ BENCHMARK_SOURCE=$d
+ AC_MSG_RESULT([$BENCHMARK_SOURCE])
+ break
+ fi
+ done
+ if test -z $BENCHMARK_SOURCE ; then
+ AC_MSG_ERROR([no benchmark source but it was selected])
+ fi
+ else
+ if test ! -d $BENCHMARK_SOURCE/src; then
+ BENCHMARK_SOURCE=$BENCHMARK_SOURCE/benchmark
+ fi
+ AC_CHECK_FILES([$BENCHMARK_SOURCE/src/benchmark.cc],
+ [have_benchmark_source=yes],
+ [AC_MSG_ERROR([no benchmark source at $BENCHMARK_SOURCE])])
+ fi
+ have_benchmark_source=yes
+ BENCHMARK_LDADD="\$(top_builddir)/ext/benchmark/libbenchmark.a"
+ DISTCHECK_BENCHMARK_CONFIGURE_FLAG="--with-benchmark-source=$BENCHMARK_SOURCE"
+ BENCHMARK_INCLUDES="-I$BENCHMARK_SOURCE \
+ -I$BENCHMARK_SOURCE/src \
+ -I$BENCHMARK_SOURCE/include \
+ -I$BENCHMARK_SOURCE/include/benchmark"
+ BENCHMARK_VERSION="$(basename $BENCHMARK_SOURCE)"
+ fi
+
+ if test "$benchmark_path" != "no" ; then
+ if test "$benchmark_path" != "yes"; then
+ BENCHMARK_PATHS=$benchmark_path
+ if test -x "${benchmark_path}/bin/benchmark-config" ; then
+ BENCHMARK_CONFIG="${benchmark_path}/bin/benchmark-config"
+ fi
+ else
+ AC_PATH_PROG([BENCHMARK_CONFIG], [benchmark-config])
+ fi
+ if test -x "${BENCHMARK_CONFIG}" ; then :
+ # using cppflags instead of cxxflags
+ BENCHMARK_INCLUDES=$(${BENCHMARK_CONFIG} --cppflags)
+ BENCHMARK_LDFLAGS=$(${BENCHMARK_CONFIG} --ldflags)
+ BENCHMARK_LDADD=$(${BENCHMARK_CONFIG} --libs)
+ BENCHMARK_VERSION=$(${BENCHMARK_CONFIG} --version)
+ BENCHMARK_FOUND="true"
+ else
+ AC_MSG_WARN([Unable to locate Google Benchmark benchmark-config.])
+ if test -z "${BENCHMARK_PATHS}" ; then
+ BENCHMARK_PATHS="/usr /usr/local"
+ fi
+ BENCHMARK_FOUND="false"
+ fi
+ if test "${BENCHMARK_FOUND}" != "true"; then
+ BENCHMARK_FOUND="false"
+ for dir in ${BENCHMARK_PATHS}; do
+ if test -f "$dir/include/benchmark/benchmark.h"; then
+ if ! test -f "$dir/lib/libbenchmark.a"; then
+ AC_MSG_WARN([Found Google Benchmark include but not the library in $dir.])
+ continue
+ fi
+ BENCHMARK_INCLUDES="-I$dir/include"
+ BENCHMARK_LDFLAGS="-L$dir/lib"
+ BENCHMARK_LDADD="$dir/lib/libbenchmark.a "
+ BENCHMARK_FOUND="true"
+ break
+ fi
+ done
+ fi
+ if test "${BENCHMARK_FOUND}" != "true"; then
+ AC_MSG_ERROR([Cannot find benchmark in: $BENCHMARK_PATHS])
+ fi
+
+ fi
+fi
+AM_CONDITIONAL(HAVE_BENCHMARK, test $enable_benchmark != "no")
+AM_CONDITIONAL(HAVE_BENCHMARK_SOURCE, test "X$have_benchmark_source" = "Xyes")
+AC_SUBST(DISTCHECK_BENCHMARK_CONFIGURE_FLAG)
+AC_SUBST(BENCHMARK_INCLUDES)
+AC_SUBST(BENCHMARK_LDFLAGS)
+AC_SUBST(BENCHMARK_LDADD)
+AC_SUBST(BENCHMARK_SOURCE)
+
+#
# Some Googletest versions bug with C++11 compilers
#
if test $enable_gtest != "no"; then
@@ -1578,6 +1691,7 @@ AC_CONFIG_FILES([Makefile
doc/version.ent
ext/Makefile
ext/coroutine/Makefile
+ ext/benchmark/Makefile
ext/gtest/Makefile
m4macros/Makefile
src/Makefile
@@ -1656,6 +1770,7 @@ AC_CONFIG_FILES([Makefile
src/lib/dhcp_ddns/Makefile
src/lib/dhcp_ddns/tests/Makefile
src/lib/dhcpsrv/Makefile
+ src/lib/dhcpsrv/benchmarks/Makefile
src/lib/dhcpsrv/tests/Makefile
src/lib/dhcpsrv/tests/test_libraries.h
src/lib/dhcpsrv/testutils/Makefile
@@ -1919,6 +2034,18 @@ GTest:
END
fi
+if test "$enable_benchmark" != "no"; then
+cat >> config.report << END
+
+Google Benchmark:
+ BENCHMARK_VERSION: ${BENCHMARK_VERSION}
+ BENCHMARK_INCLUDES: ${BENCHMARK_INCLUDES}
+ BENCHMARK_LDFLAGS: ${BENCHMARK_LDFLAGS}
+ BENCHMARK_LDADD: ${BENCHMARK_LDADD}
+ BENCHMARK_SOURCE: ${BENCHMARK_SOURCE}
+END
+fi
+
cat >> config.report << END
Developer:
diff --git a/ext/.gitignore b/ext/.gitignore
new file mode 100644
index 0000000000..7374b7c304
--- /dev/null
+++ b/ext/.gitignore
@@ -0,0 +1,3 @@
+/benchmark
+/gtest
+
diff --git a/ext/Makefile.am b/ext/Makefile.am
index 6cfbdee32f..9a2e830f58 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -3,3 +3,8 @@ SUBDIRS = coroutine
if HAVE_GTEST_SOURCE
SUBDIRS += gtest
endif
+
+if HAVE_BENCHMARK_SOURCE
+SUBDIRS += benchmark
+endif
+
diff --git a/ext/benchmark/Makefile.am b/ext/benchmark/Makefile.am
new file mode 100644
index 0000000000..1b69232217
--- /dev/null
+++ b/ext/benchmark/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = .
+
+CLEANFILES = benchmark.cc
+
+noinst_LIBRARIES = libbenchmark.a
+libbenchmark_a_CXXFLAGS = $(BENCHMARK_INCLUDES) $(AM_CXXFLAGS)
+nodist_libbenchmark_a_SOURCES = benchmark.cc
+
+benchmark.cc: $(BENCHMARK_SOURCE)/src/benchmark.cc
+ cp -p $(BENCHMARK_SOURCE)/src/benchmark.cc $@
+
diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am
index cdf92fe363..72f4a0d40a 100644
--- a/src/lib/dhcpsrv/Makefile.am
+++ b/src/lib/dhcpsrv/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = subdir-objects
-SUBDIRS = . testutils tests
+SUBDIRS = . testutils tests benchmarks
dhcp_data_dir = @localstatedir@/@PACKAGE@
kea_lfc_location = @prefix@/sbin/kea-lfc
diff --git a/src/lib/dhcpsrv/benchmarks/.gitignore b/src/lib/dhcpsrv/benchmarks/.gitignore
new file mode 100644
index 0000000000..f2f79655f8
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/.gitignore
@@ -0,0 +1,2 @@
+/run-benchmarks
+
diff --git a/src/lib/dhcpsrv/benchmarks/Makefile.am b/src/lib/dhcpsrv/benchmarks/Makefile.am
new file mode 100644
index 0000000000..fc0f23ccc3
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/Makefile.am
@@ -0,0 +1,78 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+BENCHMARKS=
+if HAVE_BENCHMARK
+
+BENCHMARKS += run-benchmarks
+
+run_benchmarks_SOURCES = run_benchmarks.cc
+run_benchmarks_SOURCES += generic_lease_mgr_benchmark.cc generic_lease_mgr_benchmark.h
+run_benchmarks_SOURCES += generic_host_data_source_benchmark.cc generic_host_data_source_benchmark.h
+
+if HAVE_MYSQL
+run_benchmarks_SOURCES += mysql_lease_mgr_benchmark.cc
+run_benchmarks_SOURCES += mysql_host_data_source_benchmark.cc
+endif
+
+if HAVE_PGSQL
+run_benchmarks_SOURCES += pgsql_lease_mgr_benchmark.cc
+run_benchmarks_SOURCES += pgsql_host_data_source_benchmark.cc
+endif
+
+if HAVE_CQL
+run_benchmarks_SOURCES += cql_lease_mgr_benchmark.cc
+run_benchmarks_SOURCES += cql_host_data_source_benchmark.cc
+endif
+
+run_benchmarks_CPPFLAGS = $(AM_CPPFLAGS) $(BENCHMARK_INCLUDES) -Wno-error=overloaded-virtual
+
+if HAVE_MYSQL
+run_benchmarks_CPPFLAGS += $(MYSQL_CPPFLAGS)
+endif
+
+if HAVE_PGSQL
+run_benchmarks_CPPFLAGS += $(PGSQL_CPPFLAGS)
+endif
+
+if HAVE_CQL
+run_benchmarks_CPPFLAGS += $(CQL_CPPFLAGS)
+endif
+
+run_benchmarks_CXXFLAGS = $(AM_CXXFLAGS)
+
+run_benchmarks_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(BENCHMARK_LDFLAGS)
+
+if HAVE_MYSQL
+run_benchmarks_LDFLAGS += $(MYSQL_LIBS)
+endif
+
+if HAVE_PGSQL
+run_benchmarks_LDFLAGS += $(PGSQL_LIBS)
+endif
+
+if HAVE_CQL
+run_benchmarks_LDFLAGS += $(CQL_LIBS)
+endif
+
+run_benchmarks_LDADD = $(BENCHMARK_LDADD)
+run_benchmarks_LDADD += $(LOG4CPLUS_LIBS)
+run_benchmarks_LDADD += $(CRYPTO_LIBS)
+run_benchmarks_LDADD += $(BOOST_LIBS)
+run_benchmarks_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+run_benchmarks_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+run_benchmarks_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+run_benchmarks_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
+endif
+
+noinst_PROGRAMS = $(BENCHMARKS)
diff --git a/src/lib/dhcpsrv/benchmarks/cql_host_data_source_benchmark.cc b/src/lib/dhcpsrv/benchmarks/cql_host_data_source_benchmark.cc
new file mode 100644
index 0000000000..0e42fd51ce
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/cql_host_data_source_benchmark.cc
@@ -0,0 +1,176 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_host_data_source_benchmark.h>
+#include <dhcpsrv/host_data_source_factory.h>
+#include <dhcpsrv/testutils/cql_schema.h>
+
+#include <iostream>
+
+using isc::dhcp::bench::GenericHostDataSourceBenchmark;
+using isc::dhcp::test::createCqlSchema;
+using isc::dhcp::test::destroyCqlSchema;
+using isc::dhcp::HostDataSourceFactory;
+using isc::dhcp::test::validCqlConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class CqlHostDataSourceBenchmark : public GenericHostDataSourceBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyCqlSchema(false, true);
+ createCqlSchema(false, true);
+ try {
+ HostDataSourceFactory::destroy();
+ HostDataSourceFactory::create(validCqlConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ hdsptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ HostDataSourceFactory::destroy();
+ destroyCqlSchema(false, true);
+ }
+};
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, insertHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp(state, host_count);
+ insertHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, updateHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ updateHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, getAll2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll2();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, getAll3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll3();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, getAll1)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll1();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get4_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get4_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get4_2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_2();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get6_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get6_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get6_2_subnetid_address)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_subnetid_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_prefix_prefixlen();
+ }
+}
+
+constexpr size_t MIN_HOST_COUNT = 512;
+constexpr size_t MAX_HOST_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, insertHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, updateHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, getAll2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, getAll3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, getAll1)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get4_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get4_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get4_2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get6_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get6_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get6_2_subnetid_address)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/cql_lease_mgr_benchmark.cc b/src/lib/dhcpsrv/benchmarks/cql_lease_mgr_benchmark.cc
new file mode 100644
index 0000000000..755678d02b
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/cql_lease_mgr_benchmark.cc
@@ -0,0 +1,192 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h>
+#include <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/cql_schema.h>
+
+using isc::dhcp::LeaseMgrFactory;
+using isc::dhcp::bench::GenericLeaseMgrBenchmark;
+using isc::dhcp::test::createCqlSchema;
+using isc::dhcp::test::destroyCqlSchema;
+using isc::dhcp::test::validCqlConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class CqlLeaseMgrBenchmark : public GenericLeaseMgrBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyCqlSchema(false, true);
+ createCqlSchema(false, true);
+ try {
+ LeaseMgrFactory::destroy();
+ LeaseMgrFactory::create(validCqlConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ lmptr_ = &(LeaseMgrFactory::instance());
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ lmptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ LeaseMgrFactory::destroy();
+ destroyCqlSchema(false, true);
+ }
+};
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, insertLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp4(state, lease_count);
+ insertLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, updateLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ updateLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease4_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease4_hwaddr)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease4_clientid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease4_clientid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getExpiredLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getExpiredLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, insertLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp6(state, lease_count);
+ insertLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, updateLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ updateLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease6_type_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease6_type_duid_iaid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_duid_iaid();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_type_duid_iaid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(CqlLeaseMgrBenchmark, getExpiredLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getExpiredLeases6();
+ }
+}
+
+constexpr size_t MIN_LEASE_COUNT = 512;
+constexpr size_t MAX_LEASE_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, insertLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, updateLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease4_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease4_hwaddr)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease4_clientid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease4_clientid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getExpiredLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, insertLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, updateLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease6_type_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease6_type_duid_iaid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(CqlLeaseMgrBenchmark, getExpiredLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.cc b/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.cc
new file mode 100644
index 0000000000..6d125fe871
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.cc
@@ -0,0 +1,399 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_host_data_source_benchmark.h>
+
+#include <asiolink/io_address.h>
+#include <dhcp/dhcp6.h>
+#include <dhcp/libdhcp++.h>
+#include <dhcp/option4_addrlst.h>
+#include <dhcp/option6_addrlst.h>
+#include <dhcp/option_int.h>
+#include <dhcp/option_string.h>
+#include <dhcp/option_vendor.h>
+#include <dhcpsrv/host_data_source_factory.h>
+#include <dhcpsrv/testutils/schema.h>
+
+using isc::asiolink::IOAddress;
+using std::cerr;
+using std::endl;
+
+namespace isc {
+namespace dhcp {
+namespace bench {
+
+GenericHostDataSourceBenchmark::GenericHostDataSourceBenchmark() : hdsptr_() {
+ LibDHCP::clearRuntimeOptionDefs();
+}
+
+GenericHostDataSourceBenchmark::~GenericHostDataSourceBenchmark() {
+ LibDHCP::clearRuntimeOptionDefs();
+ hdsptr_.reset();
+}
+
+void
+GenericHostDataSourceBenchmark::ReentrantSetUp(::benchmark::State& state,
+ size_t const& host_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareHosts(host_count);
+ state.ResumeTiming();
+}
+
+void
+GenericHostDataSourceBenchmark::ReentrantSetUpWithInserts(
+ ::benchmark::State& state, size_t const& host_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareHosts(host_count);
+ insertHosts();
+ state.ResumeTiming();
+}
+
+std::vector<uint8_t>
+GenericHostDataSourceBenchmark::generateHWAddr(const bool new_identifier) {
+ /// @todo: Consider moving this somewhere to lib/testutils.
+
+ // Let's use something that is easily printable. That's convenient
+ // if you need to enter MySQL queries by hand.
+ static uint8_t hwaddr[] = {65, 66, 67, 68, 69, 70};
+
+ if (new_identifier) {
+ // Increase the address for the next time we use it.
+ // This is primitive, but will work for 65k unique addresses.
+ hwaddr[sizeof(hwaddr) - 1]++;
+ if (hwaddr[sizeof(hwaddr) - 1] == 0) {
+ hwaddr[sizeof(hwaddr) - 2]++;
+ }
+ }
+ return std::vector<uint8_t>(hwaddr, hwaddr + sizeof(hwaddr));
+}
+
+std::vector<uint8_t>
+GenericHostDataSourceBenchmark::generateIdentifier(const bool new_identifier) {
+ /// @todo: Consider moving this somewhere to lib/testutils.
+
+ // Let's use something that is easily printable. That's convenient
+ // if you need to enter MySQL queries by hand.
+ static uint8_t ident[] = {65, 66, 67, 68, 69, 70, 71, 72, 73, 74};
+
+ if (new_identifier) {
+ // Increase the identifier for the next time we use it.
+ // This is primitive, but will work for 65k unique identifiers.
+ ident[sizeof(ident) - 1]++;
+ if (ident[sizeof(ident) - 1] == 0) {
+ ident[sizeof(ident) - 2]++;
+ }
+ }
+ return std::vector<uint8_t>(ident, ident + sizeof(ident));
+}
+
+HostPtr
+GenericHostDataSourceBenchmark::initializeHost4(
+ const std::string& address, const Host::IdentifierType& id) {
+ std::vector<uint8_t> ident;
+ if (id == Host::IDENT_HWADDR) {
+ ident = generateHWAddr();
+ } else {
+ ident = generateIdentifier();
+ }
+
+ // Let's create ever increasing subnet-ids. Let's keep those different,
+ // so subnet4 != subnet6. Useful for catching cases if the code confuses
+ // subnet4 with subnet6.
+ static SubnetID subnet4 = 0;
+ static SubnetID subnet6 = 100;
+ ++subnet4;
+ ++subnet6;
+
+ IOAddress addr(address);
+ HostPtr host(new Host(&ident[0], ident.size(), id, subnet4, subnet6, addr));
+
+ return host;
+}
+
+HostPtr
+GenericHostDataSourceBenchmark::initializeHost6(std::string address,
+ Host::IdentifierType identifier,
+ bool prefix,
+ bool new_identifier) {
+ std::vector<uint8_t> ident;
+ switch (identifier) {
+ case Host::IDENT_HWADDR:
+ ident = generateHWAddr(new_identifier);
+ break;
+ case Host::IDENT_DUID:
+ ident = generateIdentifier(new_identifier);
+ break;
+ default:
+ return HostPtr();
+ }
+
+ // Let's create ever increasing subnet-ids. Let's keep those different,
+ // so subnet4 != subnet6. Useful for catching cases if the code confuses
+ // subnet4 with subnet6.
+ static SubnetID subnet4 = 0;
+ static SubnetID subnet6 = 100;
+ subnet4++;
+ subnet6++;
+
+ HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4, subnet6,
+ IOAddress("0.0.0.0")));
+
+ if (!prefix) {
+ // Create IPv6 reservation (for an address)
+ IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress(address), 128);
+ host->addReservation(resv);
+ } else {
+ // Create IPv6 reservation for a /64 prefix
+ IPv6Resrv resv(IPv6Resrv::TYPE_PD, IOAddress(address), 64);
+ host->addReservation(resv);
+ }
+ return host;
+}
+
+OptionDescriptor
+GenericHostDataSourceBenchmark::createEmptyOption(
+ const Option::Universe& universe,
+ const uint16_t option_type,
+ const bool persist) const {
+ OptionPtr option(new Option(universe, option_type));
+ OptionDescriptor desc(option, persist);
+ return desc;
+}
+
+OptionDescriptor
+GenericHostDataSourceBenchmark::createVendorOption(
+ const Option::Universe& universe,
+ const bool persist,
+ const bool formatted,
+ const uint32_t vendor_id) const {
+ OptionVendorPtr option(new OptionVendor(universe, vendor_id));
+
+ std::ostringstream s;
+ if (formatted) {
+ // Vendor id comprises vendor-id field, for which we need to
+ // assign a value in the textual (formatted) format.
+ s << vendor_id;
+ }
+
+ OptionDescriptor desc(option, persist, s.str());
+ return desc;
+}
+
+void
+GenericHostDataSourceBenchmark::addTestOptions(
+ const HostPtr& host,
+ const bool formatted,
+ const AddedOptions& added_options) const {
+ OptionDefSpaceContainer defs;
+
+ if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
+ // Add DHCPv4 options.
+ CfgOptionPtr opts = host->getCfgOption4();
+ opts->add(createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
+ true, formatted, "my-boot-file"),
+ DHCP4_OPTION_SPACE);
+ opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
+ false, formatted, 64),
+ DHCP4_OPTION_SPACE);
+ opts->add(
+ createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
+ "vendor-encapsulated-options");
+ opts->add(createAddressOption<Option4AddrLst>(254, false, formatted,
+ "192.0.2.3"),
+ DHCP4_OPTION_SPACE);
+ opts->add(createEmptyOption(Option::V4, 1, true), "isc");
+ opts->add(createAddressOption<Option4AddrLst>(
+ 2, false, formatted, "10.0.0.5", "10.0.0.3", "10.0.3.4"),
+ "isc");
+
+ // Add definitions for DHCPv4 non-standard options.
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "vendor-encapsulated-1", 1, "uint32")),
+ "vendor-encapsulated-options");
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-254", 254, "ipv4-address", true)),
+ DHCP4_OPTION_SPACE);
+ defs.addItem(
+ OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
+ "isc");
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "isc-2", 2, "ipv4-address", true)),
+ "isc");
+ }
+
+ if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
+ // Add DHCPv6 options.
+ CfgOptionPtr opts = host->getCfgOption6();
+ opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL, true,
+ formatted, "my-boot-file"),
+ DHCP6_OPTION_SPACE);
+ opts->add(createOption<OptionUint32>(Option::V6,
+ D6O_INFORMATION_REFRESH_TIME,
+ false, formatted, 3600),
+ DHCP6_OPTION_SPACE);
+ opts->add(createVendorOption(Option::V6, false, formatted, 2495),
+ DHCP6_OPTION_SPACE);
+ opts->add(createAddressOption<Option6AddrLst>(1024, false, formatted,
+ "2001:db8:1::1"),
+ DHCP6_OPTION_SPACE);
+ opts->add(createEmptyOption(Option::V6, 1, true), "isc2");
+ opts->add(createAddressOption<Option6AddrLst>(
+ 2, false, formatted, "3000::1", "3000::2", "3000::3"),
+ "isc2");
+
+ // Add definitions for DHCPv6 non-standard options.
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-1024", 1024, "ipv6-address", true)),
+ DHCP6_OPTION_SPACE);
+ defs.addItem(
+ OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
+ "isc2");
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-2", 2, "ipv6-address", true)),
+ "isc2");
+ }
+
+ // Register created "runtime" option definitions. They will be used by a
+ // host data source to convert option data into the appropriate option
+ // classes when the options are retrieved.
+ LibDHCP::setRuntimeOptionDefs(defs);
+}
+
+void
+GenericHostDataSourceBenchmark::prepareHosts(size_t const& host_count) {
+ if (host_count > 0xfffdu) {
+ cerr << "host_count <= 0xfffd or change address generation in "
+ "GenericLeaseMgrBenchmark::prepareLeases6()"
+ << endl;
+ }
+ hosts_.clear();
+ for (size_t i = 0x0001u; i < 0x0001u + host_count; ++i) {
+ std::stringstream ss;
+ std::string n_host;
+ ss << std::hex << i;
+ ss >> n_host;
+
+ const std::string prefix = std::string("2001:db8::") + n_host;
+ HostPtr host = initializeHost6(prefix, Host::IDENT_HWADDR, false);
+ addTestOptions(host, false, DHCP4_AND_DHCP6);
+ hosts_.push_back(host);
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::insertHosts() {
+ for (HostPtr host : hosts_) {
+ hdsptr_->add(host);
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::updateHosts() {
+ for (HostPtr host : hosts_) {
+ hdsptr_->add(host);
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::getAll2() {
+ for (HostPtr host : hosts_) {
+ ConstHostCollection from_hds =
+ hdsptr_->getAll(host->getHWAddress(), host->getDuid());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::getAll3() {
+ for (HostPtr host : hosts_) {
+ std::vector<uint8_t> hwaddr = host->getIdentifier();
+ hdsptr_->getAll(host->getIdentifierType(), &hwaddr[0], hwaddr.size());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::getAll1() {
+ for (HostPtr host : hosts_) {
+ hdsptr_->getAll4(host->getIPv4Reservation());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get4_3() {
+ for (HostPtr host : hosts_) {
+ std::vector<uint8_t> hwaddr = host->getIdentifier();
+ hdsptr_->get4(host->getIPv4SubnetID(),
+ HWAddrPtr(new HWAddr(hwaddr, host->getIdentifierType())),
+ host->getDuid());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get4_4() {
+ for (HostPtr host : hosts_) {
+ std::vector<uint8_t> hwaddr = host->getIdentifier();
+ hdsptr_->get4(host->getIPv4SubnetID(), host->getIdentifierType(),
+ &hwaddr[0], hwaddr.size());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get4_2() {
+ for (HostPtr host : hosts_) {
+ hdsptr_->get4(host->getIPv4SubnetID(), host->getIPv4Reservation());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get6_3() {
+ for (HostPtr host : hosts_) {
+ hdsptr_->get6(host->getIPv6SubnetID(), host->getDuid(),
+ host->getHWAddress());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get6_4() {
+ for (HostPtr host : hosts_) {
+ std::vector<uint8_t> hwaddr = host->getIdentifier();
+ hdsptr_->get6(host->getIPv6SubnetID(), host->getIdentifierType(),
+ &hwaddr[0], hwaddr.size());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get6_2_subnetid_address() {
+ for (HostPtr host : hosts_) {
+ const IPv6ResrvRange range = host->getIPv6Reservations();
+ hdsptr_->get6(host->getIPv6SubnetID(), range.first->second.getPrefix());
+ }
+}
+
+void
+GenericHostDataSourceBenchmark::get6_2_prefix_prefixlen() {
+ for (HostPtr host : hosts_) {
+ const IPv6ResrvRange range = host->getIPv6Reservations();
+ hdsptr_->get6(range.first->second.getPrefix(),
+ range.first->second.getPrefixLen());
+ }
+}
+
+} // namespace bench
+} // namespace dhcp
+} // namespace isc
diff --git a/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.h b/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.h
new file mode 100644
index 0000000000..6612c75ec2
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.h
@@ -0,0 +1,160 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GENERIC_HOST_DATA_SOURCE_UNITTEST_H
+#define GENERIC_HOST_DATA_SOURCE_UNITTEST_H
+
+#include <benchmark/benchmark.h>
+
+#include <dhcpsrv/base_host_data_source.h>
+#include <dhcpsrv/host.h>
+
+namespace isc {
+namespace dhcp {
+namespace bench {
+
+class GenericHostDataSourceBenchmark : public ::benchmark::Fixture {
+public:
+ enum Universe { V4, V6 };
+ enum AddedOptions { DHCP4_ONLY, DHCP6_ONLY, DHCP4_AND_DHCP6 };
+
+ GenericHostDataSourceBenchmark();
+ virtual ~GenericHostDataSourceBenchmark();
+
+ HostPtr initializeHost4(const std::string& address,
+ const Host::IdentifierType& id);
+ HostPtr initializeHost6(std::string address,
+ Host::IdentifierType id,
+ bool prefix,
+ bool new_identifier = true);
+ std::vector<uint8_t> generateHWAddr(const bool new_identifier = true);
+ std::vector<uint8_t> generateIdentifier(const bool new_identifier = true);
+
+ OptionDescriptor createEmptyOption(const Option::Universe& universe,
+ const uint16_t option_type,
+ const bool persist) const;
+ template <typename OptionType, typename DataType>
+ OptionDescriptor createOption(const Option::Universe& universe,
+ const uint16_t option_type,
+ const bool persist,
+ const bool formatted,
+ const DataType& value) const {
+ boost::shared_ptr<OptionType> option(
+ new OptionType(universe, option_type, value));
+ std::ostringstream s;
+ if (formatted) {
+ // Using formatted option value. Convert option value to a
+ // textual format.
+ s << value;
+ }
+ OptionDescriptor desc(option, persist, s.str());
+ return desc;
+ }
+ template <typename OptionType, typename DataType>
+ OptionDescriptor createOption(const uint16_t option_type,
+ const bool persist,
+ const bool formatted,
+ const DataType& value) const {
+ boost::shared_ptr<OptionType> option(
+ new OptionType(option_type, value));
+
+ std::ostringstream s;
+ if (formatted) {
+ // Using formatted option value. Convert option value to a
+ // textual format.
+ s << value;
+ }
+
+ OptionDescriptor desc(option, persist, s.str());
+ return desc;
+ }
+ template <typename OptionType>
+ OptionDescriptor
+ createAddressOption(const uint16_t option_type,
+ const bool persist,
+ const bool formatted,
+ const std::string& address1 = "",
+ const std::string& address2 = "",
+ const std::string& address3 = "") const {
+ std::ostringstream s;
+ // First address.
+ typename OptionType::AddressContainer addresses;
+ if (!address1.empty()) {
+ addresses.push_back(asiolink::IOAddress(address1));
+ if (formatted) {
+ s << address1;
+ }
+ }
+ // Second address.
+ if (!address2.empty()) {
+ addresses.push_back(asiolink::IOAddress(address2));
+ if (formatted) {
+ if (s.tellp() != std::streampos(0)) {
+ s << ",";
+ }
+ s << address2;
+ }
+ }
+ // Third address.
+ if (!address3.empty()) {
+ addresses.push_back(asiolink::IOAddress(address3));
+ if (formatted) {
+ if (s.tellp() != std::streampos(0)) {
+ s << ",";
+ }
+ s << address3;
+ }
+ }
+
+ boost::shared_ptr<OptionType> option(
+ new OptionType(option_type, addresses));
+ OptionDescriptor desc(option, persist, s.str());
+ return desc;
+ }
+ OptionDescriptor createVendorOption(const Option::Universe& universe,
+ const bool persist,
+ const bool formatted,
+ const uint32_t vendor_id) const;
+ void addTestOptions(const HostPtr& host,
+ const bool formatted,
+ const AddedOptions& added_options) const;
+
+ void ReentrantSetUp(::benchmark::State& state, size_t const& host_count);
+ void ReentrantSetUpWithInserts(::benchmark::State& state,
+ size_t const& host_count);
+ void prepareHosts(size_t const& lease_count);
+ void insertHosts();
+ void updateHosts();
+ void getAll2();
+ void getAll3();
+ void getAll1();
+ void get4_3();
+ void get4_4();
+ void get4_2();
+ void get6_3();
+ void get6_4();
+ void get6_2_subnetid_address();
+ void get6_2_prefix_prefixlen();
+
+ HostDataSourcePtr hdsptr_;
+ HostCollection hosts_;
+};
+
+} // namespace bench
+} // namespace dhcp
+} // namespace isc
+
+#endif
diff --git a/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.cc b/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.cc
new file mode 100644
index 0000000000..6e85c57bb2
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.cc
@@ -0,0 +1,259 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h>
+
+#include <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/cql_schema.h>
+
+#include <chrono>
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+using isc::asiolink::IOAddress;
+using isc::dhcp::test::createCqlSchema;
+using isc::dhcp::test::destroyCqlSchema;
+using isc::dhcp::test::validCqlConnectionString;
+
+using std::chrono::duration;
+using std::chrono::duration_cast;
+using std::chrono::high_resolution_clock;
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::setprecision;
+using std::string;
+using std::stringstream;
+using std::to_string;
+using std::vector;
+
+namespace isc {
+namespace dhcp {
+namespace bench {
+
+GenericLeaseMgrBenchmark::GenericLeaseMgrBenchmark() : lmptr_(NULL) {
+}
+
+GenericLeaseMgrBenchmark::~GenericLeaseMgrBenchmark() {
+}
+
+void
+GenericLeaseMgrBenchmark::ReentrantSetUp4(::benchmark::State& state,
+ size_t const& lease_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareLeases4(lease_count);
+ state.ResumeTiming();
+}
+
+void
+GenericLeaseMgrBenchmark::ReentrantSetUpWithInserts4(
+ ::benchmark::State& state, size_t const& lease_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareLeases4(lease_count);
+ insertLeases4();
+ state.ResumeTiming();
+}
+
+void
+GenericLeaseMgrBenchmark::ReentrantSetUp6(::benchmark::State& state,
+ size_t const& lease_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareLeases6(lease_count);
+ state.ResumeTiming();
+}
+
+void
+GenericLeaseMgrBenchmark::ReentrantSetUpWithInserts6(
+ ::benchmark::State& state, size_t const& lease_count) {
+ state.PauseTiming();
+ SetUp(state);
+ prepareLeases6(lease_count);
+ insertLeases6();
+ state.ResumeTiming();
+}
+
+void
+GenericLeaseMgrBenchmark::prepareLeases4(size_t const& lease_count) {
+ leases4_.clear();
+ for (size_t i = 0x0001u; i < 0x0001u + lease_count; ++i) {
+ Lease4Ptr lease(new Lease4());
+ lease->addr_ = IOAddress(i);
+ lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, i), HTYPE_ETHER));
+ lease->client_id_ =
+ ClientIdPtr(new ClientId(vector<uint8_t>(8, 2 * i)));
+ lease->valid_lft_ = i;
+ lease->cltt_ = i;
+ lease->subnet_id_ = i;
+ lease->fqdn_rev_ = (i % 2) ? true : false;
+ lease->fqdn_fwd_ = (i % 2) ? true : false;
+ lease->hostname_ = to_string(i) + ".host.com";
+ leases4_.push_back(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::insertLeases4() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->addLease(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::updateLeases4() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->updateLease4(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease4_address() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->getLease4(lease->addr_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease4_hwaddr() {
+ for (Lease4Ptr const& lease : leases4_) {
+ const Lease4Collection collection = lmptr_->getLease4(*lease->hwaddr_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease4_hwaddr_subnetid() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->getLease4(*lease->hwaddr_, lease->subnet_id_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease4_clientid() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->getLease4(*lease->client_id_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease4_clientid_subnetid() {
+ for (Lease4Ptr const& lease : leases4_) {
+ lmptr_->getLease4(*lease->client_id_, lease->subnet_id_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getExpiredLeases4() {
+ Lease4Collection expired_leases;
+ lmptr_->getExpiredLeases4(expired_leases, leases4_.size());
+}
+
+/*
+ * Calls that aren't measured:
+ * * deleteLease(const Lease4Ptr& lease);
+ * * deleteLease(const Lease6Ptr& lease);
+ * * deleteExpiredReclaimedLeases4(const uint32_t secs);
+ */
+
+void
+GenericLeaseMgrBenchmark::prepareLeases6(size_t const& lease_count) {
+ if (lease_count > 0xfffdu) {
+ cerr << "lease_count <= 0xfffd or change address generation in "
+ "GenericLeaseMgrBenchmark::prepareLeases6()"
+ << endl;
+ }
+ leases6_.clear();
+ for (size_t i = 0x0001u; i < 0x0001u + lease_count; ++i) {
+ stringstream ss;
+ string n_lease;
+ ss << std::hex << i;
+ ss >> n_lease;
+ const string prefix = string("2001:db8::") + n_lease;
+ Lease6Ptr lease(new Lease6());
+ lease->addr_ = IOAddress(prefix);
+ lease->t1_ = i;
+ lease->t2_ = i;
+ lease->type_ = static_cast<Lease::Type>(i % 3); // NA, TA or PD
+ lease->prefixlen_ = i % 128;
+ lease->iaid_ = i;
+ lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, i)));
+ lease->preferred_lft_ = i;
+ lease->valid_lft_ = i;
+ lease->cltt_ = i;
+ lease->subnet_id_ = i;
+ lease->fqdn_fwd_ = (i % 2 == 0) ? true : false;
+ lease->fqdn_rev_ = (i % 2 == 0) ? true : false;
+ lease->hostname_ = n_lease + ".host.com";
+ leases6_.push_back(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::insertLeases6() {
+ for (Lease6Ptr const& lease : leases6_) {
+ lmptr_->addLease(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::updateLeases6() {
+ for (Lease6Ptr const& lease : leases6_) {
+ lmptr_->updateLease6(lease);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease6_type_address() {
+ for (Lease6Ptr const& lease : leases6_) {
+ lmptr_->getLease6(lease->type_, lease->addr_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease6_type_duid_iaid() {
+ for (Lease6Ptr const& lease : leases6_) {
+ lmptr_->getLeases6(lease->type_, *lease->duid_, lease->iaid_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getLease6_type_type_duid_iaid_subnetid() {
+ for (Lease6Ptr const& lease : leases6_) {
+ lmptr_->getLease6(lease->type_, *lease->duid_, lease->iaid_,
+ lease->subnet_id_);
+ }
+}
+
+void
+GenericLeaseMgrBenchmark::getExpiredLeases6() {
+ Lease6Collection expired_leases;
+ lmptr_->getExpiredLeases6(expired_leases, leases6_.size());
+}
+
+/*
+ * Calls that aren't measured:
+ * * deleteLease(const Lease4Ptr& lease);
+ * * deleteLease(const Lease6Ptr& lease);
+ * * deleteExpiredReclaimedLeases6(const uint32_t secs);
+ */
+
+} // namespace bench
+} // namespace dhcp
+} // namespace isc
diff --git a/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h b/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h
new file mode 100644
index 0000000000..05bd8134d9
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h
@@ -0,0 +1,69 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef GENERIC_LEASE_MGR_BENCHMARK_H
+#define GENERIC_LEASE_MGR_BENCHMARK_H
+
+#include <benchmark/benchmark.h>
+
+#include <dhcpsrv/lease_mgr.h>
+
+namespace isc {
+namespace dhcp {
+namespace bench {
+
+class GenericLeaseMgrBenchmark : public benchmark::Fixture {
+public:
+ enum Universe { V4, V6 };
+
+ GenericLeaseMgrBenchmark();
+ virtual ~GenericLeaseMgrBenchmark();
+
+ void ReentrantSetUp4(::benchmark::State& state, size_t const& lease_count);
+ void ReentrantSetUpWithInserts4(::benchmark::State& state,
+ size_t const& lease_count);
+ void ReentrantSetUp6(::benchmark::State& state, size_t const& lease_count);
+ void ReentrantSetUpWithInserts6(::benchmark::State& state,
+ size_t const& lease_count);
+ void prepareLeases4(size_t const& lease_count);
+
+ void insertLeases4();
+ void updateLeases4();
+ void getLease4_address();
+ void getLease4_hwaddr();
+ void getLease4_hwaddr_subnetid();
+ void getLease4_clientid();
+ void getLease4_clientid_subnetid();
+ void getExpiredLeases4();
+
+ void prepareLeases6(size_t const& lease_count);
+ void insertLeases6();
+ void updateLeases6();
+ void getLease6_type_address();
+ void getLease6_type_duid_iaid();
+ void getLease6_type_type_duid_iaid_subnetid();
+ void getExpiredLeases6();
+
+ LeaseMgr* lmptr_;
+ Lease4Collection leases4_;
+ Lease6Collection leases6_;
+};
+
+} // namespace bench
+} // namespace dhcp
+} // namespace isc
+
+#endif
diff --git a/src/lib/dhcpsrv/benchmarks/mysql_host_data_source_benchmark.cc b/src/lib/dhcpsrv/benchmarks/mysql_host_data_source_benchmark.cc
new file mode 100644
index 0000000000..b7ae7c56fe
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/mysql_host_data_source_benchmark.cc
@@ -0,0 +1,176 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_host_data_source_benchmark.h>
+#include <dhcpsrv/host_data_source_factory.h>
+#include <dhcpsrv/testutils/mysql_schema.h>
+
+#include <iostream>
+
+using isc::dhcp::bench::GenericHostDataSourceBenchmark;
+using isc::dhcp::test::createMySQLSchema;
+using isc::dhcp::test::destroyMySQLSchema;
+using isc::dhcp::HostDataSourceFactory;
+using isc::dhcp::test::validMySQLConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class MySqlHostDataSourceBenchmark : public GenericHostDataSourceBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyMySQLSchema(false);
+ createMySQLSchema(false);
+ try {
+ HostDataSourceFactory::destroy();
+ HostDataSourceFactory::create(validMySQLConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ hdsptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ HostDataSourceFactory::destroy();
+ destroyMySQLSchema(false);
+ }
+};
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, insertHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp(state, host_count);
+ insertHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, updateHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ updateHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, getAll2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll2();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, getAll3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll3();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, getAll1)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll1();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get4_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get4_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get4_2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_2();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get6_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get6_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get6_2_subnetid_address)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_subnetid_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_prefix_prefixlen();
+ }
+}
+
+constexpr size_t MIN_HOST_COUNT = 512;
+constexpr size_t MAX_HOST_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, insertHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, updateHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, getAll2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, getAll3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, getAll1)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get4_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get4_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get4_2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get6_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get6_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get6_2_subnetid_address)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/mysql_lease_mgr_benchmark.cc b/src/lib/dhcpsrv/benchmarks/mysql_lease_mgr_benchmark.cc
new file mode 100644
index 0000000000..bd02bdae54
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/mysql_lease_mgr_benchmark.cc
@@ -0,0 +1,192 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h>
+#include <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/mysql_schema.h>
+
+using isc::dhcp::LeaseMgrFactory;
+using isc::dhcp::bench::GenericLeaseMgrBenchmark;
+using isc::dhcp::test::createMySQLSchema;
+using isc::dhcp::test::destroyMySQLSchema;
+using isc::dhcp::test::validMySQLConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class MySqlLeaseMgrBenchmark : public GenericLeaseMgrBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyMySQLSchema(false);
+ createMySQLSchema(false);
+ try {
+ LeaseMgrFactory::destroy();
+ LeaseMgrFactory::create(validMySQLConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ lmptr_ = &(LeaseMgrFactory::instance());
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ lmptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ LeaseMgrFactory::destroy();
+ destroyMySQLSchema(false);
+ }
+};
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, insertLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp4(state, lease_count);
+ insertLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, updateLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ updateLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease4_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease4_hwaddr)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease4_clientid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease4_clientid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getExpiredLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getExpiredLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, insertLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp6(state, lease_count);
+ insertLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, updateLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ updateLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease6_type_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease6_type_duid_iaid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_duid_iaid();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_type_duid_iaid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(MySqlLeaseMgrBenchmark, getExpiredLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getExpiredLeases6();
+ }
+}
+
+constexpr size_t MIN_LEASE_COUNT = 512;
+constexpr size_t MAX_LEASE_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, insertLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, updateLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease4_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease4_hwaddr)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease4_clientid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease4_clientid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getExpiredLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, insertLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, updateLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease6_type_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease6_type_duid_iaid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(MySqlLeaseMgrBenchmark, getExpiredLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/pgsql_host_data_source_benchmark.cc b/src/lib/dhcpsrv/benchmarks/pgsql_host_data_source_benchmark.cc
new file mode 100644
index 0000000000..589479724b
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/pgsql_host_data_source_benchmark.cc
@@ -0,0 +1,176 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_host_data_source_benchmark.h>
+#include <dhcpsrv/host_data_source_factory.h>
+#include <dhcpsrv/testutils/pgsql_schema.h>
+
+#include <iostream>
+
+using isc::dhcp::bench::GenericHostDataSourceBenchmark;
+using isc::dhcp::test::createPgSQLSchema;
+using isc::dhcp::test::destroyPgSQLSchema;
+using isc::dhcp::HostDataSourceFactory;
+using isc::dhcp::test::validPgSQLConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class PgSqlHostDataSourceBenchmark : public GenericHostDataSourceBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyPgSQLSchema(false);
+ createPgSQLSchema(false);
+ try {
+ HostDataSourceFactory::destroy();
+ HostDataSourceFactory::create(validPgSQLConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ hdsptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ HostDataSourceFactory::destroy();
+ destroyPgSQLSchema(false);
+ }
+};
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, insertHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp(state, host_count);
+ insertHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, updateHosts)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ updateHosts();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, getAll2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll2();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, getAll3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll3();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, getAll1)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ getAll1();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get4_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get4_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get4_2)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get4_2();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get6_3)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_3();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get6_4)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_4();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get6_2_subnetid_address)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_subnetid_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)(benchmark::State& state) {
+ const size_t host_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts(state, host_count);
+ get6_2_prefix_prefixlen();
+ }
+}
+
+constexpr size_t MIN_HOST_COUNT = 512;
+constexpr size_t MAX_HOST_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, insertHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, updateHosts)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, getAll2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, getAll3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, getAll1)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get4_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get4_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get4_2)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get6_3)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get6_4)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get6_2_subnetid_address)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlHostDataSourceBenchmark, get6_2_prefix_prefixlen)->Range(MIN_HOST_COUNT, MAX_HOST_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/pgsql_lease_mgr_benchmark.cc b/src/lib/dhcpsrv/benchmarks/pgsql_lease_mgr_benchmark.cc
new file mode 100644
index 0000000000..542a87f310
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/pgsql_lease_mgr_benchmark.cc
@@ -0,0 +1,192 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h>
+#include <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/pgsql_schema.h>
+
+using isc::dhcp::LeaseMgrFactory;
+using isc::dhcp::bench::GenericLeaseMgrBenchmark;
+using isc::dhcp::test::createPgSQLSchema;
+using isc::dhcp::test::destroyPgSQLSchema;
+using isc::dhcp::test::validPgSQLConnectionString;
+using std::cerr;
+using std::endl;
+
+namespace {
+
+class PgSqlLeaseMgrBenchmark : public GenericLeaseMgrBenchmark {
+public:
+ void SetUp(::benchmark::State const&) override {
+ destroyPgSQLSchema(false);
+ createPgSQLSchema(false);
+ try {
+ LeaseMgrFactory::destroy();
+ LeaseMgrFactory::create(validPgSQLConnectionString());
+ } catch (...) {
+ cerr << "ERROR: unable to open database" << endl;
+ throw;
+ }
+ lmptr_ = &(LeaseMgrFactory::instance());
+ }
+
+ void TearDown(::benchmark::State const&) override {
+ try {
+ lmptr_->rollback();
+ } catch (...) {
+ cerr << "WARNING: rollback has failed, this is expected if database"
+ " is opened in read-only mode, continuing..."
+ << endl;
+ }
+ LeaseMgrFactory::destroy();
+ destroyPgSQLSchema(false);
+ }
+};
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, insertLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp4(state, lease_count);
+ insertLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, updateLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ updateLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease4_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease4_hwaddr)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_hwaddr_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease4_clientid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease4_clientid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getLease4_clientid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getExpiredLeases4)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts4(state, lease_count);
+ getExpiredLeases4();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, insertLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUp6(state, lease_count);
+ insertLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, updateLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ updateLeases6();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease6_type_address)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_address();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease6_type_duid_iaid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_duid_iaid();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getLease6_type_type_duid_iaid_subnetid();
+ }
+}
+
+BENCHMARK_DEFINE_F(PgSqlLeaseMgrBenchmark, getExpiredLeases6)(benchmark::State& state) {
+ const size_t lease_count = state.range(0);
+ while (state.KeepRunning()) {
+ ReentrantSetUpWithInserts6(state, lease_count);
+ getExpiredLeases6();
+ }
+}
+
+constexpr size_t MIN_LEASE_COUNT = 512;
+constexpr size_t MAX_LEASE_COUNT = 0xfffd;
+constexpr benchmark::TimeUnit UNIT = benchmark::kMicrosecond;
+
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, insertLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, updateLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease4_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease4_hwaddr)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease4_hwaddr_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease4_clientid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease4_clientid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getExpiredLeases4)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, insertLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, updateLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease6_type_address)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease6_type_duid_iaid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getLease6_type_type_duid_iaid_subnetid)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+BENCHMARK_REGISTER_F(PgSqlLeaseMgrBenchmark, getExpiredLeases6)->Range(MIN_LEASE_COUNT, MAX_LEASE_COUNT)->Unit(UNIT);
+
+} // namespace
diff --git a/src/lib/dhcpsrv/benchmarks/run_benchmarks.cc b/src/lib/dhcpsrv/benchmarks/run_benchmarks.cc
new file mode 100644
index 0000000000..6ec19d2491
--- /dev/null
+++ b/src/lib/dhcpsrv/benchmarks/run_benchmarks.cc
@@ -0,0 +1,32 @@
+// Copyright (C) 2017 Deutsche Telekom AG.
+//
+// Authors: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <config.h>
+
+#include <benchmark/benchmark.h>
+#include <log/logger_support.h>
+
+class Initializer {
+public:
+ Initializer() {
+ isc::log::initLogger();
+ }
+};
+
+Initializer initializer;
+
+BENCHMARK_MAIN()
+
diff --git a/src/lib/dhcpsrv/testutils/cql_schema.cc b/src/lib/dhcpsrv/testutils/cql_schema.cc
index 8a4468e39e..abd7c19859 100644
--- a/src/lib/dhcpsrv/testutils/cql_schema.cc
+++ b/src/lib/dhcpsrv/testutils/cql_schema.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,21 +13,18 @@
#include <stdlib.h>
-#include <gtest/gtest.h>
-
#include <fstream>
+#include <iostream>
#include <sstream>
#include <string>
-using namespace std;
-
namespace isc {
namespace dhcp {
namespace test {
const char* CQL_VALID_TYPE = "type=cql";
-string
+std::string
validCqlConnectionString() {
return (connectionString(CQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER,
VALID_PASSWORD));
@@ -36,7 +33,7 @@ validCqlConnectionString() {
bool
softWipeEnabled() {
const char* const env = getenv("KEA_TEST_CASSANDRA_WIPE");
- if (env && (string(env) == string("soft"))) {
+ if (env && (std::string(env) == std::string("soft"))) {
return (true);
}
@@ -79,8 +76,10 @@ runCqlScript(const std::string& path,
cmd << script_name;
- int retval = ::system(cmd.str().c_str());
- ASSERT_EQ(0, retval) << "runCqlSchema failed:" << cmd.str();
+ int32_t retval = ::system(cmd.str().c_str());
+ if (retval) {
+ std::cerr << "runCqlSchema failed:" << cmd.str() << std::endl;
+ }
}
} // namespace test
diff --git a/src/lib/dhcpsrv/testutils/mysql_schema.cc b/src/lib/dhcpsrv/testutils/mysql_schema.cc
index a216e4f49e..6b1225bfb7 100644
--- a/src/lib/dhcpsrv/testutils/mysql_schema.cc
+++ b/src/lib/dhcpsrv/testutils/mysql_schema.cc
@@ -9,9 +9,9 @@
#include <mysql.h>
#include <dhcpsrv/mysql_connection.h>
#include <dhcpsrv/testutils/mysql_schema.h>
-#include <gtest/gtest.h>
#include <fstream>
+#include <iostream>
#include <sstream>
#include <stdlib.h>
@@ -34,8 +34,7 @@ void destroyMySQLSchema(bool show_err) {
}
void createMySQLSchema(bool show_err) {
- runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_create.mysql",
- show_err);
+ runMySQLScript(DATABASE_SCRIPTS_DIR, "mysql/dhcpdb_create.mysql", show_err);
}
void runMySQLScript(const std::string& path, const std::string& script_name,
@@ -53,10 +52,11 @@ void runMySQLScript(const std::string& path, const std::string& script_name,
cmd << script_name;
int retval = ::system(cmd.str().c_str());
- ASSERT_EQ(0, retval) << "runMySQLSchema failed:" << cmd.str();
+ if (retval) {
+ std::cerr << "runMySQLSchema failed:" << cmd.str() << std::endl;
+ }
}
-
-};
-};
-};
+} // namespace test
+} // namespace dhcp
+} // namespace isc
diff --git a/src/lib/dhcpsrv/testutils/pgsql_schema.cc b/src/lib/dhcpsrv/testutils/pgsql_schema.cc
index 319fafd5ba..fc7d1c3d35 100644
--- a/src/lib/dhcpsrv/testutils/pgsql_schema.cc
+++ b/src/lib/dhcpsrv/testutils/pgsql_schema.cc
@@ -8,10 +8,10 @@
#include <string>
#include <dhcpsrv/testutils/pgsql_schema.h>
-#include <gtest/gtest.h>
#include <libpq-fe.h>
#include <fstream>
+#include <iostream>
#include <sstream>
#include <stdlib.h>
@@ -30,13 +30,11 @@ validPgSQLConnectionString() {
}
void destroyPgSQLSchema(bool show_err) {
- runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_drop.pgsql",
- show_err);
+ runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_drop.pgsql", show_err);
}
void createPgSQLSchema(bool show_err) {
- runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_create.pgsql",
- show_err);
+ runPgSQLScript(DATABASE_SCRIPTS_DIR, "pgsql/dhcpdb_create.pgsql", show_err);
}
void runPgSQLScript(const std::string& path, const std::string& script_name,
@@ -56,9 +54,11 @@ void runPgSQLScript(const std::string& path, const std::string& script_name,
}
int retval = ::system(cmd.str().c_str());
- ASSERT_EQ(0, retval) << "runPgSQLSchema failed:" << cmd.str();
+ if (retval) {
+ std::cerr << "runPgSQLSchema failed:" << cmd.str() << std::endl;
+ }
}
-};
-};
-};
+} // namespace test
+} // namespace dhcp
+} // namespace isc