query_bench.cc 6.06 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>
36
#include <auth/query.h>
Jerry's avatar
Jerry committed
37

Michal Vaner's avatar
Michal Vaner committed
38
#include <asiolink/asiolink.h>
JINMEI Tatuya's avatar
JINMEI Tatuya committed
39 40 41

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

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

Michal Vaner's avatar
Michal Vaner committed
53 54 55 56 57 58 59 60 61 62
// 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
63 64 65 66 67 68 69
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:
70
    QueryBenchMark(const int cache_slots, const char* const datasrc_file,
Michal Vaner's avatar
Michal Vaner committed
71 72
                   const BenchQueries& queries, MessagePtr query_message,
                   OutputBufferPtr buffer) :
73
        server_(new AuthSrv(cache_slots >= 0 ? true : false, xfrout_client)),
JINMEI Tatuya's avatar
JINMEI Tatuya committed
74 75
        queries_(queries),
        query_message_(query_message),
Michal Vaner's avatar
Michal Vaner committed
76
        buffer_(buffer),
JINMEI Tatuya's avatar
JINMEI Tatuya committed
77 78 79 80 81
        dummy_socket(IOSocket::getDummyUDPSocket()),
        dummy_endpoint(IOEndpointPtr(IOEndpoint::create(IPPROTO_UDP,
                                                        IOAddress("192.0.2.1"),
                                                        5300)))
    {
82
        if (cache_slots >= 0) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
83 84 85 86 87 88 89 90
            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
91
        DummyServer server;
JINMEI Tatuya's avatar
JINMEI Tatuya committed
92 93 94
        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
95 96 97
            query_message_->clear(Message::PARSE);
            server_->processMessage(io_message, query_message_, buffer_,
                &server);
JINMEI Tatuya's avatar
JINMEI Tatuya committed
98 99 100 101 102 103 104
        }

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

JINMEI Tatuya's avatar
JINMEI Tatuya committed
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 157 158 159
}

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
160 161
    OutputBufferPtr buffer(new OutputBuffer(4096));
    MessagePtr message(new Message(Message::PARSE));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
162 163 164 165 166 167 168

    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;

169 170 171 172
    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
173
                                             buffer));
174

JINMEI Tatuya's avatar
JINMEI Tatuya committed
175 176 177 178
    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
179
                                             queries, message, buffer));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
180 181 182 183 184

    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
185
                                             queries, message, buffer));
JINMEI Tatuya's avatar
JINMEI Tatuya committed
186 187 188

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

    return (0);
}