Commit c76e3fc0 authored by Yoshitaka Aharen's avatar Yoshitaka Aharen
Browse files

[2155] inlining isc::statistics::Counter

make isc::statistics::Counter and isc::statistics::CounterDict
inline for performance
parent 50c395e0
......@@ -579,8 +579,8 @@ INPUT = ../src/lib/exceptions ../src/lib/cc \
../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
../src/bin/sockcreator/ ../src/lib/util/ ../src/lib/util/io/ \
../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6 ../src/lib/dhcp \
../src/bin/dhcp4 ../tests/tools/perfdhcp devel
../src/lib/resolve ../src/lib/acl ../src/lib/statistics ../src/lib/dhcp \
../src/bin/dhcp6 ../src/bin/dhcp4 ../tests/tools/perfdhcp devel
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -73,7 +73,6 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_auth_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libb10-xfr.la
b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
b10_auth_LDADD += $(SQLITE_LIBS)
# TODO: config.h.in is wrong because doesn't honor pkgdatadir
......
......@@ -33,6 +33,5 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
query_bench_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
query_bench_LDADD += $(SQLITE_LIBS)
......@@ -71,7 +71,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/tests/libfake_session.la
run_unittests_LDADD += $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
......
SUBDIRS = . tests
SUBDIRS = tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
......@@ -17,8 +17,4 @@ if USE_CLANGPP
AM_CXXFLAGS += -Wno-unused-parameter
endif
lib_LTLIBRARIES = libb10-statistics.la
libb10_statistics_la_SOURCES = counter.h counter.cc
libb10_statistics_la_SOURCES += counter_dict.h counter_dict.cc
CLEANFILES = *.gcno *.gcda
// Copyright (C) 2011 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.
#include <vector>
#include <boost/noncopyable.hpp>
#include <statistics/counter.h>
namespace {
const unsigned int InitialValue = 0;
} // namespace
namespace isc {
namespace statistics {
class CounterImpl : boost::noncopyable {
private:
std::vector<Counter::Value> counters_;
public:
CounterImpl(const size_t nelements);
~CounterImpl();
void inc(const Counter::Type&);
const Counter::Value& get(const Counter::Type&) const;
};
CounterImpl::CounterImpl(const size_t items) :
counters_(items, InitialValue)
{
if (items == 0) {
isc_throw(isc::InvalidParameter, "Items must not be 0");
}
}
CounterImpl::~CounterImpl() {}
void
CounterImpl::inc(const Counter::Type& type) {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
++counters_.at(type);
return;
}
const Counter::Value&
CounterImpl::get(const Counter::Type& type) const {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
return (counters_.at(type));
}
Counter::Counter(const size_t items) : impl_(new CounterImpl(items))
{}
Counter::~Counter() {}
void
Counter::inc(const Type& type) {
impl_->inc(type);
return;
}
const Counter::Value&
Counter::get(const Type& type) const {
return (impl_->get(type));
}
} // namespace statistics
} // namespace isc
......@@ -15,24 +15,29 @@
#ifndef __COUNTER_H
#define __COUNTER_H 1
#include <exceptions/exceptions.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <exceptions/exceptions.h>
#include <vector>
namespace {
const unsigned int InitialValue = 0;
} // anonymous namespace
namespace isc {
namespace statistics {
// forward declaration for pImpl idiom
class CounterImpl;
class Counter : boost::noncopyable {
private:
boost::scoped_ptr<CounterImpl> impl_;
public:
typedef unsigned int Type;
typedef unsigned int Value;
private:
std::vector<Counter::Value> counters_;
public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still throw
......@@ -41,29 +46,56 @@ public:
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
Counter(const size_t items);
explicit inline Counter(const size_t items);
/// The destructor.
///
/// This method never throws an exception.
~Counter();
inline ~Counter();
/// \brief Increment a counter item specified with \a type.
///
/// \param type %Counter item to increment
///
/// \throw isc::OutOfRange \a type is invalid
void inc(const Type& type);
inline void inc(const Counter::Type);
/// \brief Get the value of a counter item specified with \a type.
///
/// \param type %Counter item to get the value of
///
/// \throw isc::OutOfRange \a type is invalid
const Value& get(const Type& type) const;
inline const Counter::Value& get(const Counter::Type) const;
};
inline Counter::Counter(const size_t items) :
counters_(items, InitialValue)
{
if (items == 0) {
isc_throw(isc::InvalidParameter, "Items must not be 0");
}
}
inline Counter::~Counter() {}
inline void
Counter::inc(const Counter::Type type) {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
++counters_.at(type);
return;
}
inline const Counter::Value&
Counter::get(const Counter::Type type) const {
if(type >= counters_.size()) {
isc_throw(isc::OutOfRange, "Counter type is out of range");
}
return (counters_.at(type));
}
} // namespace statistics
} // namespace isc
#endif
#endif // __COUNTER_H
// Copyright (C) 2011 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.
#include <cassert>
#include <stdexcept>
#include <iterator>
#include <map>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <statistics/counter_dict.h>
namespace {
typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
typedef std::map<std::string, CounterPtr> DictionaryMap;
}
namespace isc {
namespace statistics {
// Implementation detail class for CounterDictionary::ConstIterator
class CounterDictionaryConstIteratorImpl;
class CounterDictionaryImpl : boost::noncopyable {
private:
DictionaryMap dictionary_;
std::vector<std::string> elements_;
const size_t items_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionaryImpl();
public:
CounterDictionaryImpl(const size_t items);
~CounterDictionaryImpl();
void addElement(const std::string& name);
void deleteElement(const std::string& name);
Counter& getElement(const std::string& name);
public:
CounterDictionaryConstIteratorImpl begin() const;
CounterDictionaryConstIteratorImpl end() const;
};
// Constructor with number of items
CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
items_(items)
{
// The number of items must not be 0
if (items == 0) {
isc_throw(isc::InvalidParameter, "Items must not be 0");
}
}
// Destructor
CounterDictionaryImpl::~CounterDictionaryImpl() {}
void
CounterDictionaryImpl::addElement(const std::string& name) {
// throw if the element already exists
if (dictionary_.count(name) != 0) {
isc_throw(isc::InvalidParameter,
"Element " << name << " already exists");
}
assert(items_ != 0);
// Create a new Counter and add to the map
dictionary_.insert(
DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
}
void
CounterDictionaryImpl::deleteElement(const std::string& name) {
size_t result = dictionary_.erase(name);
if (result != 1) {
// If an element with specified name does not exist, throw
// isc::OutOfRange.
isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
}
}
Counter&
CounterDictionaryImpl::getElement(const std::string& name) {
DictionaryMap::const_iterator i = dictionary_.find(name);
if (i != dictionary_.end()) {
// the key was found. return the element.
return (*(i->second));
} else {
// If an element with specified name does not exist, throw
// isc::OutOfRange.
isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
}
}
// Constructor
// Initialize impl_
CounterDictionary::CounterDictionary(const size_t items) :
impl_(new CounterDictionaryImpl(items))
{}
// Destructor
// impl_ will be freed automatically with scoped_ptr
CounterDictionary::~CounterDictionary() {}
void
CounterDictionary::addElement(const std::string& name) {
impl_->addElement(name);
}
void
CounterDictionary::deleteElement(const std::string& name) {
impl_->deleteElement(name);
}
Counter&
CounterDictionary::getElement(const std::string& name) const {
return (impl_->getElement(name));
}
Counter&
CounterDictionary::operator[](const std::string& name) const {
return (impl_->getElement(name));
}
// Implementation detail class for CounterDictionary::ConstIterator
class CounterDictionaryConstIteratorImpl {
public:
CounterDictionaryConstIteratorImpl();
~CounterDictionaryConstIteratorImpl();
CounterDictionaryConstIteratorImpl(
const CounterDictionaryConstIteratorImpl &other);
CounterDictionaryConstIteratorImpl &operator=(
const CounterDictionaryConstIteratorImpl &source);
CounterDictionaryConstIteratorImpl(
DictionaryMap::const_iterator iterator);
public:
void increment();
const CounterDictionary::ConstIterator::value_type&
dereference() const;
bool equal(const CounterDictionaryConstIteratorImpl& other) const;
private:
DictionaryMap::const_iterator iterator_;
};
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl() {}
CounterDictionaryConstIteratorImpl::~CounterDictionaryConstIteratorImpl() {}
// Copy constructor: deep copy of iterator_
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
const CounterDictionaryConstIteratorImpl &other) :
iterator_(other.iterator_)
{}
// Assignment operator: deep copy of iterator_
CounterDictionaryConstIteratorImpl &
CounterDictionaryConstIteratorImpl::operator=(
const CounterDictionaryConstIteratorImpl &source)
{
iterator_ = source.iterator_;
return (*this);
}
// Constructor from implementation detail DictionaryMap::const_iterator
CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
DictionaryMap::const_iterator iterator) :
iterator_(iterator)
{}
CounterDictionaryConstIteratorImpl
CounterDictionaryImpl::begin() const {
return (CounterDictionaryConstIteratorImpl(dictionary_.begin()));
}
CounterDictionaryConstIteratorImpl
CounterDictionaryImpl::end() const {
return (CounterDictionaryConstIteratorImpl(dictionary_.end()));
}
void
CounterDictionaryConstIteratorImpl::increment() {
++iterator_;
return;
}
const CounterDictionary::ConstIterator::value_type&
CounterDictionaryConstIteratorImpl::dereference() const {
return (iterator_->first);
}
bool
CounterDictionaryConstIteratorImpl::equal(
const CounterDictionaryConstIteratorImpl& other) const
{
return (iterator_ == other.iterator_);
}
CounterDictionary::ConstIterator
CounterDictionary::begin() const {
return (CounterDictionary::ConstIterator(
CounterDictionaryConstIteratorImpl(impl_->begin())));
}
CounterDictionary::ConstIterator
CounterDictionary::end() const {
return (CounterDictionary::ConstIterator(
CounterDictionaryConstIteratorImpl(impl_->end())));
}
CounterDictionary::ConstIterator::ConstIterator() :
impl_(new CounterDictionaryConstIteratorImpl())
{}
CounterDictionary::ConstIterator::~ConstIterator() {}
// Copy constructor: deep copy of impl_
CounterDictionary::ConstIterator::ConstIterator(
const CounterDictionary::ConstIterator& source) :
impl_(new CounterDictionaryConstIteratorImpl(*(source.impl_)))
{}
// Assignment operator: deep copy of impl_
CounterDictionary::ConstIterator &
CounterDictionary::ConstIterator::operator=(
const CounterDictionary::ConstIterator &source)
{
*impl_ = *source.impl_;
return (*this);
}
// The constructor from implementation detail
CounterDictionary::ConstIterator::ConstIterator(
const CounterDictionaryConstIteratorImpl& source) :
impl_(new CounterDictionaryConstIteratorImpl(source))
{}
const CounterDictionary::ConstIterator::value_type&
CounterDictionary::ConstIterator::dereference() const
{
return (impl_->dereference());
}
bool
CounterDictionary::ConstIterator::equal(
CounterDictionary::ConstIterator const& other) const
{
return (impl_->equal(*(other.impl_)));
}
void
CounterDictionary::ConstIterator::increment() {
impl_->increment();
return;
}
} // namespace statistics
} // namespace isc
......@@ -15,67 +15,45 @@
#ifndef __COUNTER_DICT_H
#define __COUNTER_DICT_H 1
#include <string>
#include <vector>
#include <utility>
#include <statistics/counter.h>
#include <exceptions/exceptions.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <exceptions/exceptions.h>
#include <statistics/counter.h>
#include <cassert>
#include <stdexcept>
#include <string>
#include <vector>
#include <map>
#include <iterator>
#include <utility>
namespace {
typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
typedef std::map<std::string, CounterPtr> DictionaryMap;
}
namespace isc {
namespace statistics {
class CounterDictionaryImpl;
class CounterDictionaryConstIteratorImpl;
class CounterDictionary : boost::noncopyable {
private:
boost::scoped_ptr<CounterDictionaryImpl> impl_;
DictionaryMap dictionary_;
std::vector<std::string> elements_;
const size_t items_;
// Default constructor is forbidden; number of counter items must be
// specified at the construction of this class.
CounterDictionary();
public:
/// The constructor.
/// This constructor is mostly exception free. But it may still throw
/// a standard exception if memory allocation fails inside the method.
///
/// \param items A number of counter items to hold (greater than 0)
///
/// \throw isc::InvalidParameter \a items is 0
CounterDictionary(const size_t items);
/// The destructor.
///
/// This method never throws an exception.
~CounterDictionary();
/// \brief Add an element
///
/// \throw isc::InvalidParameter \a element already exists.
///
/// \param name A name of the element to append
void addElement(const std::string& name);
/// \brief Delete
///
/// \throw isc::OutOfRange \a element does not exist.
///
/// \param name A name of the element to delete
void deleteElement(const std::string& name);
/// \brief Lookup
///
/// \throw isc::OutOfRange \a element does not exist.
///
/// \param name A name of the element to get the counters
Counter& getElement(const std::string &name) const;
/// Same as getElement()
Counter& operator[](const std::string &name) const;
explicit inline CounterDictionary(const size_t items);
inline ~CounterDictionary();
inline void addElement(const std::string& name);
inline void deleteElement(const std::string& name);
inline Counter& getElement(const std::string& name);
inline Counter& operator[](const std::string& name);
/// \brief \c ConstIterator is a constant iterator that provides an
/// interface for enumerating name of zones stored in CounterDictionary.
///
......@@ -90,68 +68,134 @@ public:
const std::string,
boost::forward_traversal_tag>
{
private:
boost::scoped_ptr<CounterDictionaryConstIteratorImpl> impl_;
public:
/// The constructor.
///
/// This constructor is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator();
inline ConstIterator() {}
/// The destructor.
///
/// This method never throws an exception.
~ConstIterator();
inline ~ConstIterator() {}
/// The assignment operator.
///
/// This method is mostly exception free. But it may still
/// throw a standard exception if memory allocation fails
/// inside the method.
ConstIterator& operator=(const ConstIterator &source);
inline ConstIterator& operator=(const ConstIterator& source) {
iterator_ = source.iterator_;
return (*this);
}
/// The copy constructor.
///