diff --git a/doc/Doxyfile b/doc/Doxyfile index 02cbf27368..46db55c383 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -568,7 +568,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions +INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/bench # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am deleted file mode 100644 index 4cf3fb75ec..0000000000 --- a/src/bin/auth/benchmarks/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib -AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin - -CLEANFILES = *.gcno *.gcda - -noinst_PROGRAMS = query_bench -if HAVE_BOOST_SYSTEM -noinst_PROGRAMS += netio_bench -endif -query_bench_SOURCES = query_bench.cc -query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc -query_bench_SOURCES += ../normalquestion.h ../normalquestion.cc -query_bench_SOURCES += ../rbt_datasrc.h ../rbt_datasrc.cc -query_bench_SOURCES += ../loadzone.h ../loadzone.cc - -query_bench_LDADD = $(top_builddir)/src/lib/dns/libdns.la -query_bench_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la -query_bench_LDADD += $(top_builddir)/src/lib/bench/libbench.la -query_bench_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la -query_bench_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la -query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.a -query_bench_LDADD += $(SQLITE_LIBS) -if HAVE_BOOST_SYSTEM -query_bench_LDFLAGS = $(AM_LDFLAGS) $(BOOST_LDFLAGS) -query_bench_LDADD += $(BOOST_SYSTEM_LIB) -endif - -if HAVE_BOOST_SYSTEM -netio_bench_SOURCES = netio_bench.cc -netio_bench_LDFLAGS = $(AM_LDFLAGS) $(BOOST_LDFLAGS) -netio_bench_LDADD = $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a -netio_bench_LDADD += $(BOOST_SYSTEM_LIB) -endif diff --git a/src/bin/auth/benchmarks/netio_bench.cc b/src/bin/auth/benchmarks/netio_bench.cc deleted file mode 100644 index 0ccc75a5f4..0000000000 --- a/src/bin/auth/benchmarks/netio_bench.cc +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -// $Id$ - -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include - -using namespace std; -using namespace isc; -using namespace isc::bench; - -using namespace boost::asio; -using ip::udp; -namespace { -class NativeSocketBenchMark { -public: - NativeSocketBenchMark(const int af, const char* const portstr, - const size_t packet_size) : - fd_(-1), packet_size_(packet_size), s_data_(packet_size), - r_data_(packet_size) - { - struct addrinfo hints; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - int error = getaddrinfo(af == AF_INET6 ? "::1" : "127.0.0.1", - portstr, &hints, &res_); - if (error) { - isc_throw(Exception, "getaddrinfo failed: " << gai_strerror(error)); - } - // XXX: for brevity the following part is intentionally exception - // unsafe. - fd_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol); - if (fd_ < 0) { - isc_throw(Exception, "failed to open test socket: " - << strerror(errno)); - } - if (bind(fd_, res_->ai_addr, res_->ai_addrlen) != 0) { - isc_throw(Exception, "failed to bind test socket: " - << strerror(errno)); - } - maxfd_ = fd_ + 1; - FD_ZERO(&readfds_); - FD_SET(fd_, &readfds_); - } - ~NativeSocketBenchMark() { - if (fd_ >= 0) { - close(fd_); - } - freeaddrinfo(res_); - } - void closeSocket() { - if (fd_ >= 0) { - close(fd_); - } - fd_ = -1; - } - unsigned int run() { - const int cc_s = sendto(fd_, &s_data_[0], s_data_.size(), 0, - res_->ai_addr, res_->ai_addrlen); - if (cc_s != packet_size_) { - isc_throw(Exception, "sendto failed, return value=" << cc_s); - } - fd_set readfds = readfds_; - const int n = select(maxfd_, &readfds, NULL, NULL, NULL); - if (n != 1 || !FD_ISSET(fd_, &readfds)) { - isc_throw(Exception, "unexpected result from select, return value=" - << n); - } - - struct sockaddr* from = reinterpret_cast(&ss_); - socklen_t from_len = sizeof(ss_); - r_data_.clear(); - const int cc_r = recvfrom(fd_, &r_data_[0], r_data_.capacity(), 0, from, - &from_len); - if (cc_r != packet_size_) { - isc_throw(Exception, "recvfrom failed, return value=" << cc_r); - } - - return (1); - } -private: - int fd_; - int maxfd_; - const size_t packet_size_; - struct addrinfo* res_; - vector s_data_; - vector r_data_; - fd_set readfds_; - struct sockaddr_storage ss_; -}; - -class ASIOBenchMark { -public: - ASIOBenchMark(io_service& io_service, const int af, const uint16_t portnum, - const size_t packet_size) : - packet_size_(packet_size), - io_service_(io_service), - socket_(io_service, af == AF_INET6 ? udp::v6() : udp::v4()), - s_data_(packet_size), r_data_(packet_size), - endpoint_(af == AF_INET6 ? udp::v6() : udp::v4(), portnum) - { - endpoint_.address(ip::address::from_string( - af == AF_INET6 ? "::1" : "127.0.0.1")); - socket_.bind(endpoint_); - } - unsigned int run() { - isc_throw(Exception, "test is performed for a base class"); - } - void cleanup() { - socket_.close(); - io_service_.reset(); - } -protected: - const size_t packet_size_; - io_service& io_service_; - udp::socket socket_; - vector s_data_; - vector r_data_; - udp::endpoint endpoint_; - udp::endpoint sender_endpoint_; - boost::system::error_code serror_; -}; - -class ASIOSyncBenchMark : public ASIOBenchMark { -public: - ASIOSyncBenchMark(io_service& io_service, const int af, - const uint16_t portnum, const size_t packet_size) : - ASIOBenchMark(io_service, af, portnum, packet_size), - fd_(socket_.native()), maxfd_(fd_ + 1) - { - FD_ZERO(&readfds_); - FD_SET(fd_, &readfds_); - } - unsigned int run() { - const size_t cc_s = socket_.send_to( - boost::asio::buffer(&s_data_[0], s_data_.size()), - endpoint_, 0, serror_); - if (cc_s != packet_size_ || serror_) { - isc_throw(Exception, "asio::send_to failed, return value=" - << cc_s); - } - - // add the overhead of select for fair comparison - fd_set readfds = readfds_; - const int n = select(maxfd_, &readfds, NULL, NULL, NULL); - if (n != 1 || !FD_ISSET(fd_, &readfds)) { - isc_throw(Exception, "unexpected result from select, return value=" - << n); - } - - r_data_.clear(); - const size_t cc_r = socket_.receive_from( - boost::asio::buffer(&r_data_[0], r_data_.capacity()), - sender_endpoint_); - if (cc_r != packet_size_) { - isc_throw(Exception, "asio::receive_from failed, return value=" - << cc_r); - } - - return (1); - } -private: - const int fd_; - const int maxfd_; - fd_set readfds_; -}; - -class ASIOAsyncBenchMark : public ASIOBenchMark { -public: - ASIOAsyncBenchMark(io_service& io_service, const int af, - const uint16_t portnum, const size_t packet_size, - const unsigned int iteration, const bool async_send) : - ASIOBenchMark(io_service, af, portnum, packet_size), - iteration_(iteration), n_received_(0), async_send_(async_send) - {} - unsigned int run() { - if (!async_send_) { - startReceive(); - } - sendTo(); - io_service_.run(); - return (iteration_); - } -private: - void sendTo() { - if (async_send_) { - socket_.async_send_to( - boost::asio::buffer(&s_data_[0], s_data_.size()), - endpoint_, - boost::bind(&ASIOAsyncBenchMark::sendCompleted, this, - placeholders::error, - placeholders::bytes_transferred)); - } else { - const size_t cc_s = socket_.send_to( - boost::asio::buffer(&s_data_[0], s_data_.size()), - endpoint_, 0, serror_); - if (cc_s != packet_size_ || serror_) { - isc_throw(Exception, "asio::send_to failed, return value=" - << cc_s); - } - } - } - void handleReceive(const boost::system::error_code& error, - size_t bytes_recvd) - { - if (error || bytes_recvd != packet_size_) { - isc_throw(Exception, "asio::asyncronous receive failed: " - << error << ", #received=" << bytes_recvd); - } - if (++n_received_ == iteration_) { - io_service_.stop(); - } else { - sendTo(); - if (!async_send_) { - startReceive(); - } - } - } - void startReceive() { - socket_.async_receive_from( - boost::asio::buffer(&r_data_[0], r_data_.capacity()), - sender_endpoint_, - boost::bind(&ASIOAsyncBenchMark::handleReceive, this, - placeholders::error, - placeholders::bytes_transferred)); - } - void sendCompleted(const boost::system::error_code& error UNUSED_PARAM, - size_t bytes_sent UNUSED_PARAM) - { - // ignore possible errors and just keep receiving. - startReceive(); - } -private: - const unsigned int iteration_; - unsigned int n_received_; - const bool async_send_; -}; -} - -namespace isc { -namespace bench { -template<> -void -BenchMark::tearDown() { - target_.closeSocket(); -} - -template<> -void -BenchMark::tearDown() { - target_.cleanup(); -} - -template<> -void -BenchMark::tearDown() { - target_.cleanup(); -} -} -} - -namespace { -const int DEFAULT_PACKET_SIZE = 250; // arbitrary choice -const int DEFAULT_ITERATION = 10000; -const char* const DEFAULT_PORTSTR = "53530"; - -void -usage() { - cerr << "Usage: netio_bench [-n iterations] [-p port] [-s packet_size]" - << endl; - exit (1); -} -} - -int -main(int argc, char* argv[]) { - int ch; - int iteration = DEFAULT_ITERATION; - int packet_size = DEFAULT_PACKET_SIZE; - - const char* portstr = DEFAULT_PORTSTR; - - while ((ch = getopt(argc, argv, "n:p:s:")) != -1) { - switch (ch) { - case 'n': - iteration = atoi(optarg); - break; - case 'p': - portstr = optarg; - break; - case 's': - packet_size = atoi(optarg); - break; - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - if (argc > 0) { - usage(); - } - - boost::asio::io_service io_service; - const uint16_t portnum = static_cast(atoi(portstr)); - - cout << "Socket I/O benchmark using native socket API (IPv4)" << endl; - NativeSocketBenchMark io_bench1(AF_INET, portstr, packet_size); - BenchMark bench1(iteration, io_bench1); - bench1.run(); - - cout << "Socket I/O benchmark using native socket API (IPv6)" << endl; - NativeSocketBenchMark io_bench2(AF_INET6, portstr, packet_size); - BenchMark bench2(iteration, io_bench2); - bench2.run(); - - cout << "ASIO benchmark using synchronous I/O (IPv4)" << endl; - ASIOSyncBenchMark io_bench3(io_service, AF_INET, portnum, packet_size); - BenchMark bench3(iteration, io_bench3); - bench3.run(); - - cout << "ASIO benchmark using synchronous I/O (IPv6)" << endl; - ASIOSyncBenchMark io_bench4(io_service, AF_INET6, portnum, packet_size); - BenchMark bench4(iteration, io_bench4); - bench4.run(); - - cout << "ASIO benchmark using asynchronous receive I/O (IPv4)" << endl; - ASIOAsyncBenchMark io_bench5(io_service, AF_INET, portnum, packet_size, - iteration, false); - BenchMark bench5(1, io_bench5); - bench5.run(); - - cout << "ASIO benchmark using asynchronous receive I/O (IPv6)" << endl; - ASIOAsyncBenchMark io_bench6(io_service, AF_INET6, portnum, packet_size, - iteration, false); - BenchMark bench6(1, io_bench6); - bench6.run(); - - cout << "ASIO benchmark using asynchronous send/receive I/O (IPv4)" << endl; - ASIOAsyncBenchMark io_bench7(io_service, AF_INET, portnum, packet_size, - iteration, true); - BenchMark bench7(1, io_bench7); - bench7.run(); - - cout << "ASIO benchmark using asynchronous send/receive I/O (IPv6)" << endl; - ASIOAsyncBenchMark io_bench8(io_service, AF_INET6, portnum, packet_size, - iteration, true); - BenchMark bench8(1, io_bench8); - bench8.run(); - - return (0); -} diff --git a/src/bin/auth/benchmarks/query_bench.cc b/src/bin/auth/benchmarks/query_bench.cc deleted file mode 100644 index 1f6d94cbeb..0000000000 --- a/src/bin/auth/benchmarks/query_bench.cc +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -// $Id$ - -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace std; -using namespace isc; -using namespace isc::dns; -using namespace isc::bench; - -namespace { -class QueryBenchMark { -public: - QueryBenchMark(AuthSrv& server, const BenchQueries& queries, - MessageRenderer* renderer, const bool need_to_write) : - server_(server), queries_(queries), query_message_(Message::PARSE), - renderer_(renderer), null_fd_(-1), need_to_write_(need_to_write) - { - null_fd_ = open("/dev/null", O_RDWR); - if (null_fd_ < 0) { - isc_throw(Exception, "failed to open output file"); - } - } - ~QueryBenchMark() { - if (null_fd_ >= 0) { - close(null_fd_); - } - } - unsigned int run() { - BenchQueries::const_iterator query; - const BenchQueries::const_iterator query_end = queries_.end(); - for (query = queries_.begin(); query != query_end; ++query) { - InputBuffer buffer(&(*query)[0], (*query).size()); - query_message_.clear(Message::PARSE); - renderer_->clear(); - server_.processMessage(buffer, query_message_, *renderer_, true); - if (need_to_write_) { - write(null_fd_, renderer_->getData(), renderer_->getLength()); - } - } - - return (queries_.size()); - } -private: - AuthSrv& server_; - const BenchQueries& queries_; - Message query_message_; - MessageRenderer* renderer_; - int null_fd_; - const bool need_to_write_; -}; -} - -namespace isc { -namespace bench { -template<> -void -BenchMark::printResult() const { - cout.precision(6); - cout << "Processed " << getIteration() << " queries in " - << fixed << getDuration() << "s"; - cout.precision(2); - cout << " (" << fixed << getIterationPerSecond() << "qps)" << endl; -} -} -} - -namespace { -void -usage() { - cerr << "Usage: query_bench [-n iterations] zone_file " - "zone_origin query_datafile" << endl; - exit (1); -} -} - -int -main(int argc, char* argv[]) { - int ch; - int iteration = 1; - while ((ch = getopt(argc, argv, "n:")) != -1) { - switch (ch) { - case 'n': - iteration = atoi(optarg); - break; - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - if (argc < 3) { - usage(); - } - const char* const zone_file = argv[0]; - const char* const origin = argv[1]; - const char* const query_data_file = argv[2]; - - // Prepare the database - RbtDataSrc* datasrc = new RbtDataSrc(Name(origin)); - loadZoneFile(zone_file, datasrc); - - // Load queries - BenchQueries queries; - loadQueryData(query_data_file, queries, RRClass::IN()); - - // Create server object. - // The current experimental implementation depends on some environment - // variables, so we configure them before constructing a new server. - setenv("ZONEFILE", zone_file, 1); - setenv("DBORIGIN", origin, 1); - AuthSrv* auth_server = new AuthSrv; - - // Create different types of message renderer - CompressOffsetTable offset_table_; - OutputBuffer buffer(4096); - MessageRenderer standard_renderer(buffer, &offset_table_); - MessageRenderer optimized_renderer(4096, &offset_table_); - - // Perform benchmark test and dump the result - cout << "Query processing benchmark with standard renderer, " - "no write to device " << endl; - QueryBenchMark query_bench1(*auth_server, queries, &standard_renderer, - false); - BenchMark bench1(iteration, query_bench1); - bench1.run(); - - cout << "Query processing benchmark with standard renderer, " - "write to device " << endl; - QueryBenchMark query_bench2(*auth_server, queries, &standard_renderer, - true); - BenchMark bench2(iteration, query_bench2); - bench2.run(); - - cout << "Query processing benchmark with optimized renderer, " - "no write to device " << endl; - QueryBenchMark query_bench3(*auth_server, queries, &optimized_renderer, - false); - BenchMark bench3(iteration, query_bench3); - bench3.run(); - - cout << "Query processing benchmark with optimized renderer, " - "write to device " << endl; - QueryBenchMark query_bench4(*auth_server, queries, &optimized_renderer, - true); - BenchMark bench4(iteration, query_bench4); - bench4.run(); - - delete auth_server; - - return (0); -} diff --git a/src/lib/dns/benchmarks/Makefile.am b/src/lib/dns/benchmarks/Makefile.am deleted file mode 100644 index d643dd9784..0000000000 --- a/src/lib/dns/benchmarks/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib - -CLEANFILES = *.gcno *.gcda - -noinst_PROGRAMS = buffer_bench -buffer_bench_SOURCES = buffer_bench.cc -buffer_bench_LDADD = $(top_builddir)/src/lib/exceptions/libexceptions.la diff --git a/src/lib/dns/benchmarks/buffer_bench.cc b/src/lib/dns/benchmarks/buffer_bench.cc deleted file mode 100644 index eb750d5b44..0000000000 --- a/src/lib/dns/benchmarks/buffer_bench.cc +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -// $Id$ - -#include -#include - -#include - -#include - -#include - -#include - -using namespace std; -using namespace isc; -using namespace isc::dns; -using namespace isc::bench; - -namespace { -// A simplified buffer implementation using plain old array for comparison -// (omitting some validations for brevity) -class ArrayOutputBuffer { -public: - ArrayOutputBuffer(size_t n) : limit_(n) { - data_ = new uint8_t[n]; - } - ~ArrayOutputBuffer() { - delete[] data_; - } - void clear() { index_ = 0; } - void writeUint8(const uint8_t data) { - if (index_ + 1 > limit_) { - isc_throw(InvalidBufferPosition, "write beyond the end of buffer"); - } - data_[index_] = data; - ++index_; - } - void writeUint16(const uint16_t data) { - if (index_ + 2 > limit_) { - isc_throw(InvalidBufferPosition, "write beyond the end of buffer"); - } - const uint8_t net_data[2] = { (data & 0xff00U) >> 8, data & 0x00ffU }; - memcpy(&data_[index_], net_data, 2); - index_ += 2; - } - void writeUint32(const uint32_t data) { - if (index_ + 4 > limit_) { - isc_throw(InvalidBufferPosition, "write beyond the end of buffer"); - } - const uint8_t net_data[4] = { (data & 0xff000000) >> 24, - (data & 0x00ff0000) >> 16, - (data & 0x0000ff00) >> 8, - data & 0x000000ff }; - memcpy(&data_[index_], net_data, 4); - index_ += 4; - } - void writeData(const void *data, const size_t len) { - if (len > limit_ || index_ > (limit_ - len)) { - isc_throw(InvalidBufferPosition, "write beyond the end of buffer"); - } - memcpy(&data_[index_], data, len); - index_ += len; - } - size_t getLength() const { return (index_); } - const void* getData() const { return (data_); } -private: - const size_t limit_; - size_t index_; - uint8_t* data_; -}; - -const uint8_t check_data[] = { - 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 192, 0, 2, 1, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 }; - -template -class BufferBenchMark { -public: - BufferBenchMark(T& buffer, const bool use_writedata) : - buffer_(buffer), use_writedata_(use_writedata) {} - ~BufferBenchMark() {} - unsigned int run() { - // This test emulates writing 20 RR-like objects into the given buffer. - buffer_.clear(); - for (int i = 0; i < 20; ++i) { - buffer_.writeUint16(rrtype_val_); - buffer_.writeUint16(rrclass_val_); - buffer_.writeUint32(rrttl_val_); - - const uint8_t* data; - size_t datalen; - if ((i % 2) == 0) { - data = data_a; - datalen = sizeof(data_a); - } else { - data = data_aaaa; - datalen = sizeof(data_aaaa); - } - if (use_writedata_) { - buffer_.writeData(data, datalen); - } else { - for (int j = 0; j < datalen; ++j) { - buffer_.writeUint8(data[j]); - } - } - } - return (1); - } - bool checkData() const { - if (buffer_.getLength() < sizeof(check_data)) { - isc_throw(Exception, "written buffer is too short: " << - buffer_.getLength()); - } - if (memcmp(buffer_.getData(), check_data, sizeof(check_data)) != 0) { - isc_throw(Exception, "data mismatch"); - } - return (true); - } - bool isUsingWriteData() const { return (use_writedata_); } -private: - static const uint16_t rrtype_val_ = 1; - static const uint16_t rrclass_val_ = 1; - static const uint32_t rrttl_val_ = 3600; - static const uint8_t data_a[4]; - static const uint8_t data_aaaa[16]; - T& buffer_; - const bool use_writedata_; -}; - -template -const uint8_t BufferBenchMark::data_a[] = { 192, 0, 2, 1 }; - -template -const uint8_t BufferBenchMark::data_aaaa[] = { - 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 }; -} - -namespace isc { -namespace bench { -template <> -void -BenchMark >::setUp() { - cout << "Benchmark for write operations using libdns OutputBuffer and " - << (target_.isUsingWriteData() ? "writeData:" : - "explicit loop:") << endl; -} - -template <> -void -BenchMark >::tearDown() { - assert(target_.checkData()); -} - -template <> -void -BenchMark >::setUp() { - cout << "Benchmark for write operations using plain old array and " - << (target_.isUsingWriteData() ? "writeData:" : - "explicit loop:") << endl; -} - -template <> -void -BenchMark >::tearDown() { - assert(target_.checkData()); -} -} -} - -namespace { -void -usage() { - cerr << "Usage: buffer_bench [-n iterations]" << endl; - exit (1); -} -} - -int -main(int argc, char* argv[]) { - int ch; - int iteration = 100000; - while ((ch = getopt(argc, argv, "n:")) != -1) { - switch (ch) { - case 'n': - iteration = atoi(optarg); - break; - case '?': - default: - usage(); - } - } - argc -= optind; - if (argc > 0) { - usage(); - } - - OutputBuffer dns_buffer(4096); - BufferBenchMark buffer_bench(dns_buffer, true); - BenchMark > bench1(iteration, buffer_bench); - bench1.run(); - - ArrayOutputBuffer array_buffer(4096); - BufferBenchMark array_bench(array_buffer, true); - BenchMark > bench2(iteration, - array_bench); - bench2.run(); - - BufferBenchMark buffer_bench2(dns_buffer, false); - BenchMark > bench3(iteration, buffer_bench2); - bench3.run(); - - BufferBenchMark array_bench2(array_buffer, false); - BenchMark > bench4(iteration, - array_bench2); - bench4.run(); - - return (0); -}