query_bench.cc 6.01 KB
Newer Older
JINMEI Tatuya's avatar
JINMEI Tatuya committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// 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 <stdlib.h>

#include <iostream>
#include <vector>

#include <boost/shared_ptr.hpp>

#include <bench/benchmark.h>
#include <bench/benchmark_util.h>

#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/question.h>
#include <dns/rrclass.h>

#include <xfr/xfrout_client.h>

#include <auth/auth_srv.h>
Michal Vaner's avatar
Michal Vaner committed
36
#include <asiolink/asiolink.h>
JINMEI Tatuya's avatar
JINMEI Tatuya committed
37 38 39

using namespace std;
using namespace isc;
40
using namespace isc::data;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
41 42 43
using namespace isc::dns;
using namespace isc::xfr;
using namespace isc::bench;
Michal Vaner's avatar
Michal Vaner committed
44
using namespace asiolink;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
45 46 47 48 49

namespace {
// Commonly used constant:
XfroutClient xfrout_client("dummy_path"); // path doesn't matter

Michal Vaner's avatar
Michal Vaner committed
50 51 52 53 54 55 56 57 58 59
// Just something to pass as the server to resume
class DummyServer : public DNSServer {
    public:
        virtual void operator()(asio::error_code, size_t) { }
        virtual void resume(const bool) { }
        virtual DNSServer* clone() {
            return new DummyServer(*this);
        }
};

JINMEI Tatuya's avatar
JINMEI Tatuya committed
60 61 62 63 64 65 66
class QueryBenchMark {
private:
    // Maintain dynamically generated objects via shared pointers because
    // QueryBenchMark objects will be copied.
    typedef boost::shared_ptr<AuthSrv> AuthSrvPtr;
    typedef boost::shared_ptr<const IOEndpoint> IOEndpointPtr;
public:
67
    QueryBenchMark(const int cache_slots, const char* const datasrc_file,
Michal Vaner's avatar
Michal Vaner committed
68 69
                   const BenchQueries& queries, MessagePtr query_message,
                   OutputBufferPtr buffer) :
70
        server_(new AuthSrv(cache_slots >= 0 ? true : false, xfrout_client)),
JINMEI Tatuya's avatar
JINMEI Tatuya committed
71 72
        queries_(queries),
        query_message_(query_message),
Michal Vaner's avatar
Michal Vaner committed
73
        buffer_(buffer),
JINMEI Tatuya's avatar
JINMEI Tatuya committed
74 75 76 77 78
        dummy_socket(IOSocket::getDummyUDPSocket()),
        dummy_endpoint(IOEndpointPtr(IOEndpoint::create(IPPROTO_UDP,
                                                        IOAddress("192.0.2.1"),
                                                        5300)))
    {
79
        if (cache_slots >= 0) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
80 81 82 83 84 85 86 87
            server_->setCacheSlots(cache_slots);
        }
        server_->updateConfig(Element::fromJSON("{\"database_file\": \"" +
                                                string(datasrc_file) + "\"}"));
    }
    unsigned int run() {
        BenchQueries::const_iterator query;
        const BenchQueries::const_iterator query_end = queries_.end();
Michal Vaner's avatar
Michal Vaner committed
88
        DummyServer server;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
89 90 91
        for (query = queries_.begin(); query != query_end; ++query) {
            IOMessage io_message(&(*query)[0], (*query).size(), dummy_socket,
                                 *dummy_endpoint);
Michal Vaner's avatar
Michal Vaner committed
92 93 94
            query_message_->clear(Message::PARSE);
            server_->processMessage(io_message, query_message_, buffer_,
                &server);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
95 96 97 98 99 100 101
        }

        return (queries_.size());
    }
private:
    AuthSrvPtr server_;
    const BenchQueries& queries_;
Michal Vaner's avatar
Michal Vaner committed
102 103
    MessagePtr query_message_;
    OutputBufferPtr buffer_;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
104 105 106
    IOSocket& dummy_socket;
    IOEndpointPtr dummy_endpoint;
};
Michal Vaner's avatar
Michal Vaner committed
107

JINMEI Tatuya's avatar
JINMEI Tatuya committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
}

namespace isc {
namespace bench {
template<>
void
BenchMark<QueryBenchMark>::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] datasrc_file 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 < 2) {
        usage();
    }
    const char* const datasrc_file = argv[0];
    const char* const query_data_file = argv[1];

    BenchQueries queries;
    loadQueryData(query_data_file, queries, RRClass::IN());
Michal Vaner's avatar
Michal Vaner committed
157 158
    OutputBufferPtr buffer(new OutputBuffer(4096));
    MessagePtr message(new Message(Message::PARSE));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
159 160 161 162 163 164 165

    cout << "Parameters:" << endl;
    cout << "  Iterations: " << iteration << endl;
    cout << "  Data Source: " << datasrc_file << endl;
    cout << "  Query data: file=" << query_data_file << " (" << queries.size()
         << " queries)" << endl << endl;

166 167 168 169
    cout << "Benchmark enabling Hot Spot Cache with unlimited slots "
         << endl;
    BenchMark<QueryBenchMark>(iteration,
                              QueryBenchMark(0, datasrc_file, queries, message,
Michal Vaner's avatar
Michal Vaner committed
170
                                             buffer));
171

JINMEI Tatuya's avatar
JINMEI Tatuya committed
172 173 174 175
    cout << "Benchmark enabling Hot Spot Cache with 10*#queries slots "
         << endl;
    BenchMark<QueryBenchMark>(iteration,
                              QueryBenchMark(10 * queries.size(), datasrc_file,
Michal Vaner's avatar
Michal Vaner committed
176
                                             queries, message, buffer));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
177 178 179 180 181

    cout << "Benchmark enabling Hot Spot Cache with #queries/2 slots "
         << endl;
    BenchMark<QueryBenchMark>(iteration,
                              QueryBenchMark(queries.size() / 2, datasrc_file,
Michal Vaner's avatar
Michal Vaner committed
182
                                             queries, message, buffer));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
183 184 185

    cout << "Benchmark disabling Hot Spot Cache" << endl;
    BenchMark<QueryBenchMark>(iteration,
186
                              QueryBenchMark(-1, datasrc_file, queries,
Michal Vaner's avatar
Michal Vaner committed
187
                                             message, buffer));    
JINMEI Tatuya's avatar
JINMEI Tatuya committed
188 189 190

    return (0);
}