Commit b4bbfceb authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2098] added a simple micro benchmark test for rendering TreeNodeRRsets.

parent 43243f32
......@@ -9,9 +9,12 @@ endif
CLEANFILES = *.gcno *.gcda
noinst_PROGRAMS = rdata_reader_bench
noinst_PROGRAMS = rdata_reader_bench rrset_render_bench
rdata_reader_bench_SOURCES = rdata_reader_bench.cc
rdata_reader_bench_LDADD = $(top_builddir)/src/lib/datasrc/memory/libdatasrc_memory.la
rdata_reader_bench_LDADD += $(top_builddir)/src/lib/dns/libb10-dns++.la
rrset_render_bench_SOURCES = rrset_render_bench.cc
rrset_render_bench_LDADD = $(top_builddir)/src/lib/datasrc/memory/libdatasrc_memory.la
rrset_render_bench_LDADD += $(top_builddir)/src/lib/dns/libb10-dns++.la
// Copyright (C) 2012 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.
#include <bench/benchmark.h>
#include <util/buffer.h>
#include <util/memory_segment_local.h>
#include <dns/name.h>
#include <dns/messagerenderer.h>
#include <dns/rrset.h>
#include <dns/rrclass.h>
#include <dns/masterload.h>
#include <datasrc/memory/rdata_serialization.h>
#include <datasrc/memory/rdataset.h>
#include <datasrc/memory/treenode_rrset.h>
#include <datasrc/memory/zone_data.h>
#include <boost/bind.hpp>
#include <cassert>
#include <vector>
#include <sstream>
#include <unistd.h>
using std::vector;
using namespace isc::bench;
using namespace isc::datasrc::memory;
using namespace isc::dns;
namespace {
// A simple benchmark just repeating rendering a given set of RRsets.
class RRsetRenderBenchMark {
public:
RRsetRenderBenchMark(const vector<ConstRRsetPtr>& rrsets,
MessageRenderer& renderer) :
rrsets_(rrsets), renderer_(renderer)
{}
unsigned int run() {
renderer_.clear();
vector<ConstRRsetPtr>::const_iterator it;
const vector<ConstRRsetPtr>::const_iterator it_end = rrsets_.end();
for (it = rrsets_.begin(); it != it_end; ++it) {
(*it)->toWire(renderer_);
}
return (1);
}
private:
const vector<ConstRRsetPtr>& rrsets_;
MessageRenderer& renderer_;
};
// Builtin benchmark data. This is a list of RDATA (of RRs) in a response
// from a root server for the query for "www.example.com" (as of this
// implementation). We use a real world example to make the case practical.
const char* const delegation_rrsets_txt =
// AUTHORITY SECTION (NS)
"com. 172800 IN NS a.gtld-servers.net.\n"
"com. 172800 IN NS b.gtld-servers.net.\n"
"com. 172800 IN NS c.gtld-servers.net.\n"
"com. 172800 IN NS d.gtld-servers.net.\n"
"com. 172800 IN NS e.gtld-servers.net.\n"
"com. 172800 IN NS f.gtld-servers.net.\n"
"com. 172800 IN NS g.gtld-servers.net.\n"
"com. 172800 IN NS h.gtld-servers.net.\n"
"com. 172800 IN NS i.gtld-servers.net.\n"
"com. 172800 IN NS j.gtld-servers.net.\n"
"com. 172800 IN NS k.gtld-servers.net.\n"
"com. 172800 IN NS l.gtld-servers.net.\n"
"com. 172800 IN NS m.gtld-servers.net.\n"
// AUTHORITY SECTION (DS)
"com. 86400 IN DS 30909 8 2 "
"E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766\n"
// AUTHORITY SECTION (RRSIG for DS)
"com. 86400 IN RRSIG DS 8 1 86400 20120822000000 20120814230000 50398 . "
"lcIpLRq4s91Fh1FihDXiDvVMMRqgy2jjlpiP4Y6sSjIrLue6Boi7xraj"
"Ouka34ubpl4KuIcopWe99LI/7Npvq0MYr9DaqfnX9dTW6Vc2C7/hKSsz"
"POYjraZZA3SCApgfNVzq+AscYlShi56f1vm7DQWw1eh1wHLdatidrQwNyDo=\n"
// ADDITIONAL SECTION
"a.gtld-servers.net. 172800 IN A 192.5.6.30\n"
"b.gtld-servers.net. 172800 IN A 192.33.14.30\n"
"c.gtld-servers.net. 172800 IN A 192.26.92.30\n"
"d.gtld-servers.net. 172800 IN A 192.31.80.30\n"
"e.gtld-servers.net. 172800 IN A 192.12.94.30\n"
"f.gtld-servers.net. 172800 IN A 192.35.51.30\n"
"g.gtld-servers.net. 172800 IN A 192.42.93.30\n"
"h.gtld-servers.net. 172800 IN A 192.54.112.30\n"
"i.gtld-servers.net. 172800 IN A 192.43.172.30\n"
"j.gtld-servers.net. 172800 IN A 192.48.79.30\n"
"k.gtld-servers.net. 172800 IN A 192.52.178.30\n"
"l.gtld-servers.net. 172800 IN A 192.41.162.30\n"
"m.gtld-servers.net. 172800 IN A 192.55.83.30\n"
"a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30\n"
"b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30";
// Likewise, it's a response from a root server for www.example.notexistent.
// An example that involves a few more RRSIGs.
const char* const nxdomain_rrsets_txt =
// AUTHORITY SECTION (NS)
". 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2012082901 1800 900 604800 86400\n"
". 86400 IN RRSIG SOA 8 0 86400 20120905000000 20120828230000 50398 . Wj6NgkA2TyJug9XfWYG/Cjh4d1JI99/Dv9S1TClbrhLdeMI4s9BEcBSA xdlPJN6L4uaupcYeEyRWGx3p0iq7VWFyjL4xy/+jXpUoHCgj0NlWa6eu C2litcnfcumTI97XJ5iod3ET+6vWnhwZQHDnz1fj4FuS8PPEJJ+Oy3M5 mcM=\n"
". 86400 IN NSEC ac. NS SOA RRSIG NSEC DNSKEY\n"
". 86400 IN RRSIG NSEC 8 0 86400 20120905000000 20120828230000 50398 . f8FEG1HzQtn/shZCdDgkB7TIpHAmH2hGlp5RubczukzD8XI3EGMVNoaf 2cUNPLpyhoBQkO1Rz+hANzI6Jkqq8PzhiQnLcW+y2Wl/BU2SaBQ2Otb2 5+VOOXux1veKaCZsRRU1VJnTUYguDayAgcS7BtB/rc7ez4nokkK98MA9 zcw=\n"
"no. 86400 IN NSEC np. NS RRSIG NSEC\n"
"no. 86400 IN RRSIG NSEC 8 1 86400 20120905000000 20120828230000 50398 . Z/E4hb6MMSpueGGjGoCWwnN2uKsQf88HPS1gbwVHBEhR+5eSn0BGqExs fQsjYL47SF/6pwMXjzmXCt8NPXXf9ImY/93GUuFL6j5OuL2MDIxt24MS u6hfxxiYTn+zF0dM8cn+UK5n1VEBB5JVJXf7FOr3OmaRLMD33Gl6yZJ/ l1E=";
void
usage() {
std::cerr << "Usage: rrset_render_bench [-n iterations]" << std::endl;
exit (1);
}
// Helper callback for masterLoad() used in main() to build test data.
void
setRRset(vector<ConstRRsetPtr>* rrsets, ConstRRsetPtr rrset) {
rrsets->push_back(rrset);
}
void
buildZone(isc::util::MemorySegmentLocal& mem_sgmt,
ZoneData* zone_data, const vector<ConstRRsetPtr>& rrsets,
vector<ConstRRsetPtr>& rrsets_build)
{
RdataEncoder encoder;
for (vector<ConstRRsetPtr>::const_iterator it = rrsets.begin();
it != rrsets.end();
++it)
{
ConstRRsetPtr rrset = *it;
ZoneNode* node;
zone_data->insertName(mem_sgmt, rrset->getName(), &node);
// For simplicity, we assume that if the current RRset has a next
// one that is of type RRSIG, that RRSIG should be associated with
// the current RRset (which should be the case for our test data).
ConstRRsetPtr sig_rrset;
if ((it + 1) != rrsets.end() &&
(*(it + 1))->getType() == RRType::RRSIG()) {
sig_rrset = *(++it);
}
RdataSet* rdataset =
RdataSet::create(mem_sgmt, encoder, rrset, sig_rrset);
rdataset->next = node->getData();
node->setData(rdataset);
rrsets_build.push_back(
ConstRRsetPtr(new TreeNodeRRset(rrset->getClass(), node, rdataset,
true)));
}
}
}
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;
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc != 0) {
usage();
}
// Build test data. rrsets will consist of a list of RRsets corresponding
// to the text defined above.
vector<ConstRRsetPtr> delegation_rrsets;
std::stringstream rrsets_stream(delegation_rrsets_txt);
masterLoad(rrsets_stream, Name::ROOT_NAME(), RRClass::IN(),
boost::bind(setRRset, &delegation_rrsets, _1));
vector<ConstRRsetPtr> nxdomain_rrsets;
std::stringstream rrsets_stream2(nxdomain_rrsets_txt);
masterLoad(rrsets_stream2, Name::ROOT_NAME(), RRClass::IN(),
boost::bind(setRRset, &nxdomain_rrsets, _1));
// Build in-memory zone using RRsets constructed above, storing
// the same set of RRsets as TreeNodeRRsets in separate vectors.
// This code below is not 100% exception safe (for simplicity), but at
// least it shouldn't leak memory in normal cases.
isc::util::MemorySegmentLocal mem_sgmt;
ZoneData* zone_data = ZoneData::create(mem_sgmt, Name::ROOT_NAME());
vector<ConstRRsetPtr> delegation_treenode_rrsets;
buildZone(mem_sgmt, zone_data, delegation_rrsets,
delegation_treenode_rrsets);
vector<ConstRRsetPtr> nxdomain_treenode_rrsets;
buildZone(mem_sgmt, zone_data, nxdomain_rrsets,
nxdomain_treenode_rrsets);
// The benchmark test uses a message renderer. Create it now and keep
// using it throughout the test.
isc::util::OutputBuffer buffer(4096); // 4096 should be sufficiently large
MessageRenderer renderer;
renderer.setBuffer(&buffer);
std::cout << "Benchmark for rendering basic RRsets (delegation)"
<< std::endl;
BenchMark<RRsetRenderBenchMark>(iteration,
RRsetRenderBenchMark(delegation_rrsets,
renderer));
std::cout << "Benchmark for rendering tree node RRsets (delegation)"
<< std::endl;
BenchMark<RRsetRenderBenchMark>(iteration,
RRsetRenderBenchMark(
delegation_treenode_rrsets, renderer));
std::cout << "Benchmark for rendering basic RRsets (nxdomain)"
<< std::endl;
BenchMark<RRsetRenderBenchMark>(iteration,
RRsetRenderBenchMark(nxdomain_rrsets,
renderer));
std::cout << "Benchmark for rendering tree node RRsets (nxdomain)"
<< std::endl;
BenchMark<RRsetRenderBenchMark>(iteration,
RRsetRenderBenchMark(
nxdomain_treenode_rrsets, renderer));
// Cleanup, and memory leak check
ZoneData::destroy(mem_sgmt, zone_data, RRClass::IN());
assert(mem_sgmt.allMemoryDeallocated());
return (0);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment