From: Tomek Mrugalski Date: Fri, 8 May 2015 13:49:02 +0000 (+0200) Subject: [3793] StatContext implemented. X-Git-Tag: trac3513_base~5^2~1^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2a599377ea4c6d93dfe14bd2c4e1bf49376f2282;p=thirdparty%2Fkea.git [3793] StatContext implemented. --- diff --git a/src/lib/stats/context.cc b/src/lib/stats/context.cc index e69de29bb2..a4840197d1 100644 --- a/src/lib/stats/context.cc +++ b/src/lib/stats/context.cc @@ -0,0 +1,52 @@ +// Copyright (C) 2015 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 +#include + +namespace isc { +namespace stats { + +ObservationPtr StatContext::get(const std::string& name) { + std::map::iterator obs = stats_.find(name); + if (obs == stats_.end()) { + return (ObservationPtr()); + } else { + return (obs->second); + } +} + +void StatContext::add(const ObservationPtr& obs) { + std::map::iterator obs = stats_.find(name); + if (obs == stats_.end()) { + stats_.insert(make_pair(obs->getName() ,obs)); + } else { + isc_throw(InvalidStatType, "Statistic named " << obs->getName() + << " already exists."); + } + +} + +bool StatContext::del(const std::string& name) { + std::map::iterator obs = stats_.find(name); + if (obs == stats_.end()) { + return (false); + } else { + stats_.erase(obs); + return (true); + } +} + +}; +}; diff --git a/src/lib/stats/context.h b/src/lib/stats/context.h index 33e20c6d70..4506fdd3be 100644 --- a/src/lib/stats/context.h +++ b/src/lib/stats/context.h @@ -1,20 +1,69 @@ - +// Copyright (C) 2015 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. #ifndef CONTEXT_H #define CONTEXT_H #include #include +#include namespace isc { namespace stats { +/// @brief Exception indicating that a given statistic is duplicated. +class DuplicateStat : public Exception { +public: + DuplicateStat(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) {} +}; + +/// @brief Statistics context +/// +/// Statistics context is essentially a container used to group statistics +/// related to a given context together. Two examples of such contexts are +/// all statistics related to a given subnet or all statistics related to a +/// given network interface. class StatContext { public: - std::map stats; + + /// @brief attempts to get an observation + /// @param name name of the statistic + /// @return appropriate Observation object (or NULL) + ObservationPtr get(const std::string& name); + + /// @brief Adds a new observation + /// @param obs observation to be added + /// @throw DuplicateStat if an observation with the same name exists already + void add(const ObservationPtr& obs); + + /// @brief Attempts to delete an observation + /// @param name name of the observation to be deleted + /// @return true if successful, false if no such statistic was found + bool del(const std::string& name); + + /// @brief Statistics container + /// + /// It is public to allow various operations that require iterating over + /// all elements. In particular, two operations (setting all stats to 0; + /// reporting all stats) will take advantage of this. Alternatively, we + /// could make it protected and then return a pointer to it, but that + /// would defeat the purpose of the hermetization in the first place. + std::map stats_; }; - typedef boost::shared_ptr StatContextPtr; +typedef boost::shared_ptr StatContextPtr; }; }; diff --git a/src/lib/stats/tests/context_unittest.cc b/src/lib/stats/tests/context_unittest.cc index e69de29bb2..5105547719 100644 --- a/src/lib/stats/tests/context_unittest.cc +++ b/src/lib/stats/tests/context_unittest.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2015 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 + +#include +#include + +using namespace isc::stats; + +// Basic test that checks get, add, del methods +TEST(ContextTest, basic) { + + // Let's create a couple observations. Using floating point, + // as they're easiest to initialize. + ObservationPtr a(new Observation("alpha", 1.11)); + ObservationPtr b(new Observation("beta", 2.22)); + ObservationPtr c(new Observation("gamma", 3.33)); + + // Context where we will store the observations. + StatContext ctx; + + // By default the context does not hold any statistics. + EXPECT_EQ(0, ctx.stats_.size()); + EXPECT_TRUE(ctx.stats_.empty()); + + // It should be possible to add 'a' statistic + EXPECT_NO_THROW(ctx.add(a)); + + // We can't add a duplicate. + EXPECT_THROW(ctx.add(a), DuplicateStat); + + // It should be ok to add other statistics + EXPECT_NO_THROW(ctx.add(b)); + EXPECT_NO_THROW(ctx.add(c)); + + // By now we should have 3 statistics recorded + EXPECT_EQ(3, ctx.stats_.size()); + EXPECT_FALSE(ctx.stats_.empty()); + + // Let's try to retrieve them + ObservationPtr from_ctx; + EXPECT_NO_THROW(from_ctx = ctx.get("alpha")); + ASSERT_TRUE(from_ctx); + EXPECT_EQ(a->getJSON()->str(), from_ctx->getJSON()->str()); + + EXPECT_NO_THROW(from_ctx = ctx.get("beta")); + ASSERT_TRUE(from_ctx); + EXPECT_EQ(b->getJSON()->str(), from_ctx->getJSON()->str()); + + EXPECT_NO_THROW(from_ctx = ctx.get("gamma")); + ASSERT_TRUE(from_ctx); + EXPECT_EQ(c->getJSON()->str(), from_ctx->getJSON()->str()); + + // Let's try to retrieve non-existing stat + EXPECT_NO_THROW(from_ctx = ctx.get("delta")); + EXPECT_FALSE(from_ctx); + + // Now delete one of the stats... + EXPECT_TRUE(ctx.del("beta")); + + // ... and check that it's really gone. + EXPECT_FALSE(ctx.get("beta")); + + // Attempt to delete non-existing stat should fail. + EXPECT_FALSE(ctx.del("beta")); +} +