2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 21:45:37 +00:00

copy from the experimental branch

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac241@2140 e5f2f494-b856-4b98-b285-d166d9295462
This commit is contained in:
JINMEI Tatuya
2010-06-17 01:38:16 +00:00
parent e171bd88b1
commit d586dfbc28
2 changed files with 242 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
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

View File

@@ -0,0 +1,235 @@
// 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 <cassert>
#include <stdint.h>
#include <iostream>
#include <bench/benchmark.h>
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
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 <typename T>
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 <typename T>
const uint8_t BufferBenchMark<T>::data_a[] = { 192, 0, 2, 1 };
template <typename T>
const uint8_t BufferBenchMark<T>::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<BufferBenchMark<OutputBuffer> >::setUp() {
cout << "Benchmark for write operations using libdns OutputBuffer and "
<< (target_.isUsingWriteData() ? "writeData:" :
"explicit loop:") << endl;
}
template <>
void
BenchMark<BufferBenchMark<OutputBuffer> >::tearDown() {
assert(target_.checkData());
}
template <>
void
BenchMark<BufferBenchMark<ArrayOutputBuffer> >::setUp() {
cout << "Benchmark for write operations using plain old array and "
<< (target_.isUsingWriteData() ? "writeData:" :
"explicit loop:") << endl;
}
template <>
void
BenchMark<BufferBenchMark<ArrayOutputBuffer> >::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<OutputBuffer> buffer_bench(dns_buffer, true);
BenchMark<BufferBenchMark<OutputBuffer> > bench1(iteration, buffer_bench);
bench1.run();
ArrayOutputBuffer array_buffer(4096);
BufferBenchMark<ArrayOutputBuffer> array_bench(array_buffer, true);
BenchMark<BufferBenchMark<ArrayOutputBuffer> > bench2(iteration,
array_bench);
bench2.run();
BufferBenchMark<OutputBuffer> buffer_bench2(dns_buffer, false);
BenchMark<BufferBenchMark<OutputBuffer> > bench3(iteration, buffer_bench2);
bench3.run();
BufferBenchMark<ArrayOutputBuffer> array_bench2(array_buffer, false);
BenchMark<BufferBenchMark<ArrayOutputBuffer> > bench4(iteration,
array_bench2);
bench4.run();
return (0);
}