[svn] commit: r2077 - in /experiments/jinmei-onmemdb/src: bin/auth/benchmarks/query_bench.cc lib/dns/benchmarks/buffer_bench.cc lib/dns/messagerenderer.cc lib/dns/messagerenderer.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Jun 6 05:59:22 UTC 2010
Author: jinmei
Date: Sun Jun 6 05:59:22 2010
New Revision: 2077
Log:
further optimization: use internal buffer for rendering instead of vector-based output buffer.
Modified:
experiments/jinmei-onmemdb/src/bin/auth/benchmarks/query_bench.cc
experiments/jinmei-onmemdb/src/lib/dns/benchmarks/buffer_bench.cc
experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc
experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h
Modified: experiments/jinmei-onmemdb/src/bin/auth/benchmarks/query_bench.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/benchmarks/query_bench.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/benchmarks/query_bench.cc Sun Jun 6 05:59:22 2010
@@ -43,12 +43,10 @@
namespace {
class QueryBenchMark {
public:
- QueryBenchMark(AuthSrv& server, const BenchQueries& queries) :
+ QueryBenchMark(AuthSrv& server, const BenchQueries& queries,
+ MessageRenderer* renderer, const bool need_to_write) :
server_(server), queries_(queries), query_message_(Message::PARSE),
- obuffer_(4096)
- //, renderer_(obuffer_)
- , renderer_(obuffer_, &offset_table_)
- , null_fd_(-1)
+ renderer_(renderer), null_fd_(-1), need_to_write_(need_to_write)
{
null_fd_ = open("/dev/null", O_RDWR);
if (null_fd_ < 0) {
@@ -66,9 +64,11 @@
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);
- //write(null_fd_, obuffer_.getData(), obuffer_.getLength());
+ renderer_->clear();
+ server_.processMessage(buffer, query_message_, *renderer_, true);
+ if (need_to_write_) {
+ write(null_fd_, renderer_->getData(), renderer_->getLength());
+ }
}
return (queries_.size());
@@ -77,10 +77,9 @@
AuthSrv& server_;
const BenchQueries& queries_;
Message query_message_;
- OutputBuffer obuffer_;
- MessageRenderer renderer_;
- CompressOffsetTable offset_table_;
+ MessageRenderer* renderer_;
int null_fd_;
+ const bool need_to_write_;
};
}
@@ -145,10 +144,40 @@
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
- QueryBenchMark query_bench(*auth_server, queries);
- BenchMark<QueryBenchMark> bench(iteration, query_bench);
- bench.run();
+ cout << "Query processing benchmark with standard renderer, "
+ "no write to device " << endl;
+ QueryBenchMark query_bench1(*auth_server, queries, &standard_renderer,
+ false);
+ BenchMark<QueryBenchMark> 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<QueryBenchMark> 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<QueryBenchMark> 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<QueryBenchMark> bench4(iteration, query_bench4);
+ bench4.run();
delete auth_server;
Modified: experiments/jinmei-onmemdb/src/lib/dns/benchmarks/buffer_bench.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/benchmarks/buffer_bench.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/benchmarks/buffer_bench.cc Sun Jun 6 05:59:22 2010
@@ -68,7 +68,7 @@
memcpy(&data_[index_], net_data, 4);
index_ += 4;
}
- void writeData(const void *data, size_t len) {
+ void writeData(const void *data, const size_t len) {
if (len > limit_ || index_ > (limit_ - len)) {
isc_throw(InvalidBufferPosition, "write beyond the end of buffer");
}
Modified: experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc Sun Jun 6 05:59:22 2010
@@ -35,7 +35,7 @@
/// (ancestor) name against each new name to be rendered into the buffer.
struct NameCompressNode {
NameCompressNode(const MessageRenderer& renderer,
- const OutputBuffer& buffer, const size_t pos,
+ const OutputBuffer* buffer, const size_t pos,
const size_t len) :
renderer_(renderer), buffer_(buffer), pos_(pos), len_(len) {}
/// The renderer that performs name compression using the node.
@@ -43,7 +43,7 @@
/// (case-sensitive or not) in the comparison functor (\c NameCompare).
const MessageRenderer& renderer_;
/// The buffer in which the corresponding name is rendered.
- const OutputBuffer& buffer_;
+ const OutputBuffer* buffer_;
/// The position (offset from the beginning) in the buffer where the
/// name starts.
uint16_t pos_;
@@ -94,16 +94,16 @@
pos1 = nextPosition(n1.buffer_, pos1, l1);
pos2 = nextPosition(n2.buffer_, pos2, l2);
if (case_sensitive) {
- if (n1.buffer_[pos1] < n2.buffer_[pos2]) {
+ if ((*n1.buffer_)[pos1] < (*n2.buffer_)[pos2]) {
return (true);
- } else if (n1.buffer_[pos1] > n2.buffer_[pos2]) {
+ } else if ((*n1.buffer_)[pos1] > (*n2.buffer_)[pos2]) {
return (false);
}
} else {
- if (tolower(n1.buffer_[pos1]) < tolower(n2.buffer_[pos2])) {
+ if (tolower((*n1.buffer_)[pos1]) < tolower((*n2.buffer_)[pos2])) {
return (true);
- } else if (tolower(n1.buffer_[pos1]) >
- tolower(n2.buffer_[pos2])) {
+ } else if (tolower((*n1.buffer_)[pos1]) >
+ tolower((*n2.buffer_)[pos2])) {
return (false);
}
}
@@ -113,16 +113,16 @@
}
private:
- uint16_t nextPosition(const OutputBuffer& buffer,
+ uint16_t nextPosition(const OutputBuffer* buffer,
uint16_t pos, uint16_t& llen) const
{
if (llen == 0) {
int i = 0;
- while ((buffer[pos] & Name::COMPRESS_POINTER_MARK8) ==
+ while (((*buffer)[pos] & Name::COMPRESS_POINTER_MARK8) ==
Name::COMPRESS_POINTER_MARK8) {
- pos = (buffer[pos] & ~Name::COMPRESS_POINTER_MARK8) *
- 256 + buffer[pos + 1];
+ pos = ((*buffer)[pos] & ~Name::COMPRESS_POINTER_MARK8) *
+ 256 + (*buffer)[pos + 1];
// This loop should stop as long as the buffer has been
// constructed validly and the search/insert argument is based
@@ -131,7 +131,7 @@
i += 2;
assert(i < Name::MAX_WIRE);
}
- llen = buffer[pos];
+ llen = (*buffer)[pos];
} else {
--llen;
}
@@ -152,12 +152,12 @@
///
/// \param buffer An \c OutputBuffer object to which wire format data is
/// written.
- MessageRendererImpl(OutputBuffer& buffer) :
+ MessageRendererImpl(OutputBuffer* buffer) :
buffer_(buffer), nbuffer_(Name::MAX_WIRE), msglength_limit_(512),
truncated_(false), compress_mode_(MessageRenderer::CASE_INSENSITIVE)
{}
/// The buffer that holds the entire DNS message.
- OutputBuffer& buffer_;
+ OutputBuffer* buffer_;
/// A local working buffer to convert each given name into wire format.
/// This could be a local variable of the \c writeName() method, but
/// we keep it in the class so that we can reuse it and avoid construction
@@ -176,70 +176,85 @@
};
MessageRenderer::MessageRenderer(OutputBuffer& buffer) :
- impl_(new MessageRendererImpl(buffer)), arg_(NULL)
+ limit_(0), index_(0), data_(NULL),
+ impl_(new MessageRendererImpl(&buffer)), arg_(NULL)
{}
MessageRenderer::MessageRenderer(OutputBuffer& buffer, void* arg) :
- impl_(new MessageRendererImpl(buffer)), arg_(arg)
+ limit_(0), index_(0), data_(NULL),
+ impl_(new MessageRendererImpl(&buffer)), arg_(arg)
{}
+
+MessageRenderer::MessageRenderer(const size_t buflen, void* arg) :
+ limit_(buflen), index_(0), data_(NULL), arg_(arg)
+{
+ // XXX: this code is not exception safe.
+ impl_ = new MessageRendererImpl(NULL);
+ data_ = new uint8_t[buflen];
+}
MessageRenderer::~MessageRenderer() {
delete impl_;
}
void
-MessageRenderer::skip(const size_t len) {
- impl_->buffer_.skip(len);
-}
-
-void
-MessageRenderer::trim(const size_t len) {
- impl_->buffer_.trim(len);
+MessageRenderer::skip2(const size_t len) {
+ impl_->buffer_->skip(len);
+}
+
+void
+MessageRenderer::trim2(const size_t len) {
+ impl_->buffer_->trim(len);
}
void
MessageRenderer::clear() {
- impl_->buffer_.clear();
+ if (impl_->buffer_ != NULL) {
+ impl_->buffer_->clear();
+ }
impl_->nbuffer_.clear();
impl_->nodeset_.clear();
impl_->msglength_limit_ = 512;
impl_->truncated_ = false;
impl_->compress_mode_ = CASE_INSENSITIVE;
-}
-
-void
-MessageRenderer::writeUint8(const uint8_t data) {
- impl_->buffer_.writeUint8(data);
-}
-
-void
-MessageRenderer::writeUint16(const uint16_t data) {
- impl_->buffer_.writeUint16(data);
-}
-
-void
-MessageRenderer::writeUint16At(const uint16_t data, const size_t pos) {
- impl_->buffer_.writeUint16At(data, pos);
-}
-
-void
-MessageRenderer::writeUint32(const uint32_t data) {
- impl_->buffer_.writeUint32(data);
-}
-
-void
-MessageRenderer::writeData(const void* const data, const size_t len) {
- impl_->buffer_.writeData(data, len);
+
+ // for ad hoc extension
+ index_ = 0;
+}
+
+void
+MessageRenderer::writeUint8_2(const uint8_t data) {
+ impl_->buffer_->writeUint8(data);
+}
+
+void
+MessageRenderer::writeUint16_2(const uint16_t data) {
+ impl_->buffer_->writeUint16(data);
+}
+
+void
+MessageRenderer::writeUint16At_2(const uint16_t data, const size_t pos) {
+ impl_->buffer_->writeUint16At(data, pos);
+}
+
+void
+MessageRenderer::writeUint32_2(const uint32_t data) {
+ impl_->buffer_->writeUint32(data);
+}
+
+void
+MessageRenderer::writeData_2(const void* const data, const size_t len) {
+ impl_->buffer_->writeData(data, len);
}
const void*
-MessageRenderer::getData() const {
- return (impl_->buffer_.getData());
+MessageRenderer::getData2() const {
+ return (impl_->buffer_->getData());
}
size_t
-MessageRenderer::getLength() const {
- return (impl_->buffer_.getLength());
+MessageRenderer::getLength2() const {
+ return (impl_->buffer_->getLength());
}
size_t
@@ -288,7 +303,7 @@
if (impl_->nbuffer_[i] == 0) {
continue;
}
- n = impl_->nodeset_.find(NameCompressNode(*this, impl_->nbuffer_, i,
+ n = impl_->nodeset_.find(NameCompressNode(*this, &impl_->nbuffer_, i,
impl_->nbuffer_.getLength() -
i));
if (n != notfound) {
@@ -297,15 +312,15 @@
}
// Record the current offset before extending the buffer.
- const size_t offset = impl_->buffer_.getLength();
+ const size_t offset = impl_->buffer_->getLength();
// Write uncompress part...
- impl_->buffer_.writeData(impl_->nbuffer_.getData(),
+ impl_->buffer_->writeData(impl_->nbuffer_.getData(),
compress ? i : impl_->nbuffer_.getLength());
if (compress && n != notfound) {
// ...and compression pointer if available.
uint16_t pointer = (*n).pos_;
pointer |= Name::COMPRESS_POINTER_MARK16;
- impl_->buffer_.writeUint16(pointer);
+ impl_->buffer_->writeUint16(pointer);
}
// Finally, add to the set the newly rendered name and its ancestors that
Modified: experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h Sun Jun 6 05:59:22 2010
@@ -95,6 +95,10 @@
CASE_INSENSITIVE, //!< Compress names case-insensitive manner (default)
CASE_SENSITIVE //!< Compress names case-sensitive manner
};
+private:
+ const size_t limit_;
+ size_t index_;
+ uint8_t* data_;
public:
///
/// \name Constructors and Destructor
@@ -105,6 +109,7 @@
/// written.
MessageRenderer(OutputBuffer& buffer);
MessageRenderer(OutputBuffer& buffer, void* arg); // ad hoc extension
+ MessageRenderer(size_t buflen, void* arg); // ditto, using internal buffer
void* getArg() { return (arg_); }
/// \brief The destructor.
///
@@ -116,6 +121,103 @@
~MessageRenderer();
//@}
+ // ad hoc extensions
+ const void* getData() const {
+ if (data_ != NULL) {
+ return (data_);
+ } else {
+ return (getData2());
+ }
+ }
+ size_t getLength() const {
+ if (data_ != NULL) {
+ return (index_);
+ } else {
+ return (getLength2());
+ }
+ }
+ void skip(const size_t len) {
+ if (data_ != NULL) {
+ if (len > limit_ || index_ > (limit_ - len)) {
+ isc_throw(InvalidBufferPosition, "skip beyond the end of buffer");
+ }
+ index_ += len;
+ } else {
+ skip2(len);
+ }
+ }
+ void trim(const size_t len) {
+ if (data_ != NULL) {
+ if (len > index_) {
+ isc_throw(InvalidBufferPosition,
+ "trying to trim more than the data");
+ }
+ index_ -= len;
+ } else {
+ trim2(len);
+ }
+ }
+ void writeUint8(const uint8_t data) {
+ if (data_ != NULL) {
+ if (index_ + 1 > limit_) {
+ isc_throw(InvalidBufferPosition, "write beyond the end of buffer");
+ }
+ data_[index_] = data;
+ ++index_;
+ } else {
+ writeUint8_2(data);
+ }
+ }
+ void writeUint16(const uint16_t data) {
+ if (data_ != NULL) {
+ 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;
+ } else {
+ writeUint16_2(data);
+ }
+ }
+ void writeUint32(const uint32_t data) {
+ if (data_ != NULL) {
+ 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;
+ } else {
+ writeUint32_2(data);
+ }
+ }
+ void writeData(const void *data, const size_t len) {
+ if (data_ != NULL) {
+ if (len > limit_ || index_ > (limit_ - len)) {
+ isc_throw(InvalidBufferPosition, "write beyond the end of buffer");
+ }
+ memcpy(&data_[index_], data, len);
+ index_ += len;
+ } else {
+ writeData_2(data, len);
+ }
+ }
+ void writeUint16At(const uint16_t data, const size_t pos) {
+ if (data_ != NULL) {
+ if (pos + sizeof(data) > index_) {
+ isc_throw(InvalidBufferPosition, "write at invalid position");
+ }
+ const uint8_t net_data[2] = { (data & 0xff00U) >> 8, data & 0x00ffU };
+ memcpy(&data_[pos], net_data, 2);
+ } else {
+ writeUint16At_2(data, pos);
+ }
+ }
+
///
/// \name Getter Methods
///
@@ -125,9 +227,9 @@
///
/// This method works exactly same as the same method of the \c OutputBuffer
/// class; all notes for \c OutputBuffer apply.
- const void* getData() const;
+ const void* getData2() const;
/// \brief Return the length of data written in the internal buffer.
- size_t getLength() const;
+ size_t getLength2() const;
/// \brief Return whether truncation has occurred while rendering.
///
/// Once the return value of this method is \c true, it doesn't make sense
@@ -188,7 +290,7 @@
/// that is to be filled in later, e.g, by \ref writeUint16At().
///
/// \param len The length of the gap to be inserted in bytes.
- void skip(size_t len);
+ void skip2(size_t len);
/// \brief Trim the specified length of data from the end of the internal
/// buffer.
///
@@ -199,7 +301,7 @@
/// be thrown.
///
/// \param len The length of data that should be trimmed.
- void trim(size_t len);
+ void trim2(size_t len);
/// \brief Clear the internal buffer and other internal resources.
///
/// This method can be used to re-initialize and reuse the renderer
@@ -208,12 +310,12 @@
/// \brief Write an unsigned 8-bit integer into the internal buffer.
///
/// \param data The 8-bit integer to be written into the internal buffer.
- void writeUint8(uint8_t data);
+ void writeUint8_2(uint8_t data);
/// \brief Write an unsigned 16-bit integer in host byte order into the
/// internal buffer in network byte order.
///
/// \param data The 16-bit integer to be written into the buffer.
- void writeUint16(uint16_t data);
+ void writeUint16_2(uint16_t data);
/// \brief Write an unsigned 16-bit integer in host byte order at the
/// specified position of the internal buffer in network byte order.
///
@@ -225,12 +327,12 @@
///
/// \param data The 16-bit integer to be written into the internal buffer.
/// \param pos The beginning position in the buffer to write the data.
- void writeUint16At(uint16_t data, size_t pos);
+ void writeUint16At_2(uint16_t data, size_t pos);
/// \brief Write an unsigned 32-bit integer in host byte order into the
/// internal buffer in network byte order.
///
/// \param data The 32-bit integer to be written into the buffer.
- void writeUint32(uint32_t data);
+ void writeUint32_2(uint32_t data);
/// \brief Copy an arbitrary length of data into the internal buffer
/// of the \c MessageRenderer.
///
@@ -238,7 +340,7 @@
///
/// \param data A pointer to the data to be copied into the internal buffer.
/// \param len The length of the data in bytes.
- void writeData(const void *data, size_t len);
+ void writeData_2(const void *data, size_t len);
//@}
///
More information about the bind10-changes
mailing list