summaryrefslogtreecommitdiffstats
path: root/src/lib/statistics/counter_dict.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/statistics/counter_dict.cc')
-rw-r--r--src/lib/statistics/counter_dict.cc246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/lib/statistics/counter_dict.cc b/src/lib/statistics/counter_dict.cc
new file mode 100644
index 0000000000..d18c6a5ef1
--- /dev/null
+++ b/src/lib/statistics/counter_dict.cc
@@ -0,0 +1,246 @@
+#include <cassert>
+#include <stdexcept>
+#include <iterator>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/unordered_map.hpp>
+
+#include <statistics/counter_dict.h>
+
+namespace {
+typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
+typedef boost::unordered_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& element);
+ void deleteElement(const std::string& elemet);
+ Counter& getElement(const std::string& element);
+ public:
+ CounterDictionaryConstIteratorImpl begin() const;
+ CounterDictionaryConstIteratorImpl end() const;
+};
+
+// Constructor with number of items
+CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
+ items_(items)
+{
+ // The number of the items must not be 0.
+ assert(items != 0);
+}
+
+// Destructor
+CounterDictionaryImpl::~CounterDictionaryImpl() {}
+
+void
+CounterDictionaryImpl::addElement(const std::string& element) {
+ // throw if the element already exists
+ if (dictionary_.count(element) != 0) {
+ isc_throw(isc::InvalidParameter,
+ "Element " << element << " already exists");
+ }
+ // Create a new Counter and add to the map
+ dictionary_.insert(
+ DictionaryMap::value_type(element, CounterPtr(new Counter(items_))));
+}
+
+void
+CounterDictionaryImpl::deleteElement(const std::string& element) {
+ size_t result = dictionary_.erase(element);
+ if (result != 1) {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange, "Element " << element << " does not exist");
+ }
+}
+
+Counter&
+CounterDictionaryImpl::getElement(const std::string& element) {
+ try {
+ return (*(dictionary_.at(element)));
+ } catch (const std::out_of_range &e) {
+ // If an element with specified name does not exist, throw
+ // isc::OutOfRange.
+ isc_throw(isc::OutOfRange, "Element " << element << " 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& element) {
+ impl_->addElement(element);
+}
+
+void
+CounterDictionary::deleteElement(const std::string& element) {
+ impl_->deleteElement(element);
+}
+
+Counter&
+CounterDictionary::getElement(const std::string& element) const {
+ return (impl_->getElement(element));
+}
+
+Counter&
+CounterDictionary::operator[](const std::string& element) const {
+ return (impl_->getElement(element));
+}
+
+// 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();
+ CounterDictionary::ValueType 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;
+}
+
+CounterDictionary::ValueType
+CounterDictionaryConstIteratorImpl::dereference() const {
+ return (CounterDictionary::ValueType(iterator_->first,
+ *(iterator_->second)));
+}
+
+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::ValueType
+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