]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
Google Benchmark support
authorAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 15:43:51 +0000 (18:43 +0300)
committerAndrei Pavel <andrei.pavel@qualitance.com>
Fri, 18 Aug 2017 15:44:05 +0000 (18:44 +0300)
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*"

22 files changed:
.gitignore
configure.ac
ext/.gitignore [new file with mode: 0644]
ext/Makefile.am
ext/benchmark/Makefile.am [new file with mode: 0644]
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/benchmarks/.gitignore [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/Makefile.am [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/cql_host_data_source_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/cql_lease_mgr_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/generic_host_data_source_benchmark.h [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/generic_lease_mgr_benchmark.h [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/mysql_host_data_source_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/mysql_lease_mgr_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/pgsql_host_data_source_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/pgsql_lease_mgr_benchmark.cc [new file with mode: 0644]
src/lib/dhcpsrv/benchmarks/run_benchmarks.cc [new file with mode: 0644]
src/lib/dhcpsrv/testutils/cql_schema.cc
src/lib/dhcpsrv/testutils/mysql_schema.cc
src/lib/dhcpsrv/testutils/pgsql_schema.cc

index ea1f60bd515f49f5d878a15b8dc427a44bc4bace..9afda8d91e523a1cff64e9de9995bfd059835bc0 100644 (file)
@@ -45,4 +45,3 @@ config.h.in~
 /logger_lockfile
 /report.info
 
-/ext/gtest/
index 9ed9366c341aea705eb2a9ddac2c71936b9c2c91..e9542bf23aa89bf709081d5e6c3f997a0fb2d642 100644 (file)
@@ -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.
@@ -1338,6 +1351,106 @@ AC_SUBST(GTEST_LDFLAGS)
 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
 #
@@ -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 (file)
index 0000000..7374b7c
--- /dev/null
@@ -0,0 +1,3 @@
+/benchmark
+/gtest
+
index 6cfbdee32f7d5667525e4c0f7a60f88a0319ff22..9a2e830f58f89449aeb36b13fa8e6b47e2d93d52 100644 (file)
@@ -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 (file)
index 0000000..1b69232
--- /dev/null
@@ -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 $@
+
index cdf92fe3634456def52806ffd95d71d1006ade80..72f4a0d40a093361999b6137a38e80957be2e43b 100644 (file)
@@ -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 (file)
index 0000000..f2f7965
--- /dev/null
@@ -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 (file)
index 0000000..fc0f23c
--- /dev/null
@@ -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 (file)
index 0000000..0e42fd5
--- /dev/null
@@ -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 (file)
index 0000000..755678d
--- /dev/null
@@ -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 (file)
index 0000000..6d125fe
--- /dev/null
@@ -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 (file)
index 0000000..6612c75
--- /dev/null
@@ -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 (file)
index 0000000..6e85c57
--- /dev/null
@@ -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 (file)
index 0000000..05bd813
--- /dev/null
@@ -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 (file)
index 0000000..b7ae7c5
--- /dev/null
@@ -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 (file)
index 0000000..bd02bda
--- /dev/null
@@ -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 (file)
index 0000000..5894797
--- /dev/null
@@ -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 (file)
index 0000000..542a87f
--- /dev/null
@@ -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 (file)
index 0000000..6ec19d2
--- /dev/null
@@ -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()
+
index 8a4468e39eb08f822fc97476f7ae6716bb67c119..abd7c198593e11fde0a74b6601fe80a2c3a91dd7 100644 (file)
@@ -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
 
 #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
index a216e4f49e4600b870800989b8d2d07dee4bad2d..6b1225bfb7746f3bad3fde68b528602fb58eec51 100644 (file)
@@ -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
index 319fafd5ba0a1e757a2d93b1ad89b98ff60b1a27..fc7d1c3d3518d4cf3ff981b6394ceebf77683fe2 100644 (file)
@@ -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