[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