Avoid unnecessary copies for DynamicType::GetObjects.

Fixes #5987
This commit is contained in:
Gunnar Beutner 2014-04-09 12:22:23 +02:00
parent bb5e7561ed
commit a16ef350e2
6 changed files with 72 additions and 35 deletions

View File

@ -1570,7 +1570,7 @@ bool ClusterListener::SupportsChecks(void)
if (!type)
return false;
return !type->GetObjects().empty() && IcingaApplication::GetInstance()->GetEnableChecks();
return std::distance(type->GetObjects().first, type->GetObjects().second) > 0 && IcingaApplication::GetInstance()->GetEnableChecks();
}
bool ClusterListener::SupportsNotifications(void)
@ -1580,7 +1580,7 @@ bool ClusterListener::SupportsNotifications(void)
if (!type)
return false;
return !type->GetObjects().empty() && IcingaApplication::GetInstance()->GetEnableNotifications();
return std::distance(type->GetObjects().first, type->GetObjects().second) > 0 && IcingaApplication::GetInstance()->GetEnableNotifications();
}
bool ClusterListener::SupportsFeature(const String& name)
@ -1590,7 +1590,7 @@ bool ClusterListener::SupportsFeature(const String& name)
if (!type)
return false;
return !type->GetObjects().empty();
return std::distance(type->GetObjects().first, type->GetObjects().second) > 0;
}
std::pair<Dictionary::Ptr, Dictionary::Ptr> ClusterListener::GetClusterStatus(void)

View File

@ -184,12 +184,12 @@ Value StatusTable::ProgramStartAccessor(const Value&)
Value StatusTable::NumHostsAccessor(const Value&)
{
return static_cast<long>(DynamicType::GetObjects<Host>().size());
return std::distance(DynamicType::GetObjects<Host>().first, DynamicType::GetObjects<Host>().second);
}
Value StatusTable::NumServicesAccessor(const Value&)
{
return static_cast<long>(DynamicType::GetObjects<Service>().size());
return std::distance(DynamicType::GetObjects<Service>().first, DynamicType::GetObjects<Service>().second);
}
Value StatusTable::ProgramVersionAccessor(const Value&)

View File

@ -73,17 +73,12 @@ DynamicType::TypeVector DynamicType::GetTypes(void)
return InternalGetTypeVector(); /* Making a copy of the vector here. */
}
std::vector<DynamicObject::Ptr> DynamicType::GetObjects(const String& type)
std::pair<DynamicTypeIterator<DynamicObject>, DynamicTypeIterator<DynamicObject> > DynamicType::GetObjects(void)
{
DynamicType::Ptr dt = GetByName(type);
return dt->GetObjects();
}
std::vector<DynamicObject::Ptr> DynamicType::GetObjects(void) const
{
ObjectLock olock(this);
return m_ObjectVector; /* Making a copy of the vector here. */
return std::make_pair(
DynamicTypeIterator<DynamicObject>(GetSelf(), 0),
DynamicTypeIterator<DynamicObject>(GetSelf(), -1)
);
}
String DynamicType::GetName(void) const

View File

@ -24,13 +24,18 @@
#include "base/registry.h"
#include "base/dynamicobject.h"
#include "base/debug.h"
#include "base/objectlock.h"
#include <map>
#include <set>
#include <boost/function.hpp>
# include <boost/iterator/iterator_facade.hpp>
namespace icinga
{
template<typename T>
class I2_BASE_API DynamicTypeIterator;
class I2_BASE_API DynamicType : public Object
{
public:
@ -48,25 +53,21 @@ public:
void RegisterObject(const DynamicObject::Ptr& object);
static std::vector<DynamicType::Ptr> GetTypes(void);
std::vector<DynamicObject::Ptr> GetObjects(void) const;
std::pair<DynamicTypeIterator<DynamicObject>, DynamicTypeIterator<DynamicObject> > GetObjects(void);
template<typename T>
static std::vector<shared_ptr<T> > GetObjects(void)
static std::pair<DynamicTypeIterator<T>, DynamicTypeIterator<T> > GetObjects(void)
{
std::vector<shared_ptr<T> > objects;
BOOST_FOREACH(const DynamicObject::Ptr& object, GetObjects(T::GetTypeName())) {
shared_ptr<T> tobject = static_pointer_cast<T>(object);
ASSERT(tobject);
objects.push_back(tobject);
}
return objects;
DynamicType::Ptr type = GetByName(T::GetTypeName());
return std::make_pair(
DynamicTypeIterator<T>(type, 0),
DynamicTypeIterator<T>(type, -1)
);
}
private:
template<typename T> friend class DynamicTypeIterator;
String m_Name;
typedef std::map<String, DynamicObject::Ptr> ObjectMap;
@ -81,8 +82,48 @@ private:
static TypeMap& InternalGetTypeMap(void);
static TypeVector& InternalGetTypeVector(void);
static boost::mutex& GetStaticMutex(void);
};
static std::vector<DynamicObject::Ptr> GetObjects(const String& type);
template<typename T>
class I2_BASE_API DynamicTypeIterator : public boost::iterator_facade<DynamicTypeIterator<T>, const shared_ptr<T>, boost::forward_traversal_tag>
{
public:
DynamicTypeIterator(const DynamicType::Ptr& type, int index)
: m_Type(type), m_Index(index)
{ }
private:
friend class boost::iterator_core_access;
DynamicType::Ptr m_Type;
int m_Index;
mutable shared_ptr<T> m_Current;
void increment(void) {
m_Index++;
}
bool equal(const DynamicTypeIterator<T>& other) const
{
ASSERT(other.m_Type == m_Type);
{
ObjectLock olock(m_Type);
if ((other.m_Index == -1 || other.m_Index >= other.m_Type->m_ObjectVector.size()) &&
(m_Index == -1 || m_Index >= m_Type->m_ObjectVector.size()))
return true;
}
return (other.m_Index == m_Index);
}
const shared_ptr<T>& dereference(void) const
{
ObjectLock olock(m_Type);
m_Current = static_pointer_cast<T>(*(m_Type->m_ObjectVector.begin() + m_Index));
return m_Current;
}
};
}

View File

@ -341,8 +341,9 @@ bool ConfigItem::ActivateItems(ValidationType validate)
if (validate != ValidateNone) {
/* log stats for external parsers */
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
if (type->GetObjects().size() > 0)
Log(LogInformation, "config", "Checked " + Convert::ToString(type->GetObjects().size()) + " " + type->GetName() + "(s).");
int count = std::distance(type->GetObjects().first, type->GetObjects().second);
if (count > 0)
Log(LogInformation, "config", "Checked " + Convert::ToString(count) + " " + type->GetName() + "(s).");
}
}

View File

@ -111,10 +111,10 @@ void DbConnection::ProgramStatusHandler(void)
query3.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
DbObject::OnQuery(query3);
InsertRuntimeVariable("total_services", static_cast<long>(DynamicType::GetObjects<Service>().size()));
InsertRuntimeVariable("total_scheduled_services", static_cast<long>(DynamicType::GetObjects<Service>().size()));
InsertRuntimeVariable("total_hosts", static_cast<long>(DynamicType::GetObjects<Host>().size()));
InsertRuntimeVariable("total_scheduled_hosts", static_cast<long>(DynamicType::GetObjects<Host>().size()));
InsertRuntimeVariable("total_services", std::distance(DynamicType::GetObjects<Service>().first, DynamicType::GetObjects<Service>().second));
InsertRuntimeVariable("total_scheduled_services", std::distance(DynamicType::GetObjects<Service>().first, DynamicType::GetObjects<Service>().second));
InsertRuntimeVariable("total_hosts", std::distance(DynamicType::GetObjects<Host>().first, DynamicType::GetObjects<Host>().second));
InsertRuntimeVariable("total_scheduled_hosts", std::distance(DynamicType::GetObjects<Host>().first, DynamicType::GetObjects<Host>().second));
Dictionary::Ptr vars = IcingaApplication::GetInstance()->GetVars();