diff options
Diffstat (limited to 'src/lib/statistics/counter_dict.cc')
-rw-r--r-- | src/lib/statistics/counter_dict.cc | 246 |
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 |