Speed up type lookups

refs #7561
This commit is contained in:
Gunnar Beutner 2014-11-07 12:32:25 +01:00
parent 3cf08ad050
commit 266b1754c7
57 changed files with 119 additions and 104 deletions

View File

@ -36,7 +36,7 @@ class DynamicTypeIterator;
class I2_BASE_API DynamicType : public Object
{
public:
DECLARE_OBJECT(DynamicType);
DECLARE_PTR_TYPEDEFS(DynamicType);
DynamicType(const String& name);

View File

@ -34,7 +34,7 @@ namespace icinga
class I2_BASE_API FIFO : public Stream
{
public:
DECLARE_OBJECT(FIFO);
DECLARE_PTR_TYPEDEFS(FIFO);
static const size_t BlockSize = 16 * 1024;

View File

@ -35,7 +35,7 @@ namespace icinga
class I2_BASE_API NetworkStream : public Stream
{
public:
DECLARE_OBJECT(NetworkStream);
DECLARE_PTR_TYPEDEFS(NetworkStream);
NetworkStream(const Socket::Ptr& socket);

View File

@ -83,8 +83,3 @@ Value Object::GetField(int) const
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
}
Type::Ptr icinga::LookupType(const char *name)
{
return Type::GetByName(name);
}

View File

@ -60,24 +60,40 @@ namespace icinga
{
class Value;
class Object;
class Type;
#define DECLARE_PTR_TYPEDEFS(klass) \
typedef shared_ptr<klass> Ptr; \
typedef weak_ptr<klass> WeakPtr
#define IMPL_TYPE_LOOKUP(klass) \
static shared_ptr<Type> TypeInstance; \
inline virtual shared_ptr<Type> GetReflectionType(void) const \
{ \
return LookupType(#klass); \
return TypeInstance; \
}
#define DECLARE_OBJECT(klass) \
DECLARE_PTR_TYPEDEFS(klass); \
IMPL_TYPE_LOOKUP(klass);
class Type;
template<typename T>
shared_ptr<Object> DefaultObjectFactory(void)
{
return make_shared<T>();
}
I2_BASE_API shared_ptr<Type> LookupType(const char *name);
typedef shared_ptr<Object> (*ObjectFactory)(void);
template<typename T>
struct TypeHelper
{
static ObjectFactory GetFactory(void)
{
return DefaultObjectFactory<T>;
}
};
/**
* Base class for all heap-allocated objects. At least one of its methods

View File

@ -21,9 +21,9 @@
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(int);
REGISTER_PRIMITIVE_TYPE(double);
REGISTER_PRIMITIVE_TYPE(bool);
REGISTER_BUILTIN_TYPE(int);
REGISTER_BUILTIN_TYPE(double);
REGISTER_BUILTIN_TYPE(bool);
PrimitiveType::PrimitiveType(const String& name)
: m_Name(name)
@ -59,3 +59,8 @@ int PrimitiveType::GetFieldCount(void) const
return 0;
}
ObjectFactory PrimitiveType::GetFactory(void) const
{
return NULL;
}

View File

@ -39,11 +39,14 @@ public:
virtual Field GetFieldInfo(int id) const;
virtual int GetFieldCount(void) const;
protected:
virtual ObjectFactory GetFactory(void) const;
private:
String m_Name;
};
#define REGISTER_PRIMITIVE_TYPE(type) \
#define REGISTER_BUILTIN_TYPE(type) \
namespace { namespace UNIQUE_NAME(prt) { namespace prt ## type { \
void RegisterPrimitiveType(void) \
{ \
@ -54,6 +57,10 @@ private:
INITIALIZE_ONCE(RegisterPrimitiveType); \
} } }
#define REGISTER_PRIMITIVE_TYPE(type) \
REGISTER_BUILTIN_TYPE(type); \
DEFINE_TYPE_INSTANCE(type)
}
#endif /* PRIMITIVETYPE_H */

View File

@ -53,7 +53,7 @@ struct ProcessResult
class I2_BASE_API Process : public Object
{
public:
DECLARE_OBJECT(Process);
DECLARE_PTR_TYPEDEFS(Process);
#ifdef _WIN32
typedef String Arguments;

View File

@ -35,7 +35,7 @@ namespace icinga
class I2_BASE_API RingBuffer : public Object
{
public:
DECLARE_OBJECT(RingBuffer);
DECLARE_PTR_TYPEDEFS(RingBuffer);
typedef std::vector<int>::size_type SizeType;

View File

@ -37,7 +37,7 @@ namespace icinga
class I2_BASE_API ScriptFunction : public Object
{
public:
DECLARE_OBJECT(ScriptFunction);
DECLARE_PTR_TYPEDEFS(ScriptFunction);
typedef boost::function<Value (const std::vector<Value>& arguments)> Callback;

View File

@ -43,7 +43,7 @@ public:
class I2_BASE_API ScriptVariable : public Object
{
public:
DECLARE_OBJECT(ScriptVariable);
DECLARE_PTR_TYPEDEFS(ScriptVariable);
ScriptVariable(const Value& data);

View File

@ -38,7 +38,7 @@ namespace icinga
class I2_BASE_API Socket : public Object
{
public:
DECLARE_OBJECT(Socket);
DECLARE_PTR_TYPEDEFS(Socket);
Socket(void);
Socket(SOCKET fd);

View File

@ -38,7 +38,7 @@ namespace icinga
class I2_BASE_API StatsFunction : public Object
{
public:
DECLARE_OBJECT(StatsFunction);
DECLARE_PTR_TYPEDEFS(StatsFunction);
typedef boost::function<Value (Dictionary::Ptr& status, Array::Ptr& perfdata)> Callback;

View File

@ -29,7 +29,7 @@ namespace icinga {
class I2_BASE_API StdioStream : public Stream
{
public:
DECLARE_OBJECT(StdioStream);
DECLARE_PTR_TYPEDEFS(StdioStream);
StdioStream(std::iostream *innerStream, bool ownsStream);
~StdioStream(void);

View File

@ -54,7 +54,7 @@ struct ReadLineContext
class I2_BASE_API Stream : public Object
{
public:
DECLARE_OBJECT(Stream);
DECLARE_PTR_TYPEDEFS(Stream);
/**
* Reads data from the stream.

View File

@ -25,7 +25,7 @@
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(String);
REGISTER_BUILTIN_TYPE(String);
const String::SizeType String::NPos = std::string::npos;

View File

@ -34,7 +34,7 @@ namespace icinga
class I2_BASE_API TcpSocket : public Socket
{
public:
DECLARE_OBJECT(TcpSocket);
DECLARE_PTR_TYPEDEFS(TcpSocket);
void Bind(const String& service, int family);
void Bind(const String& node, const String& service, int family);

View File

@ -34,7 +34,7 @@ namespace icinga {
class I2_BASE_API Timer : public Object
{
public:
DECLARE_OBJECT(Timer);
DECLARE_PTR_TYPEDEFS(Timer);
Timer(void);
~Timer(void);

View File

@ -36,7 +36,7 @@ namespace icinga
class I2_BASE_API TlsStream : public Stream
{
public:
DECLARE_OBJECT(TlsStream);
DECLARE_PTR_TYPEDEFS(TlsStream);
TlsStream(const Socket::Ptr& socket, ConnectionRole role, const shared_ptr<SSL_CTX>& sslContext);

View File

@ -49,7 +49,12 @@ Type::Ptr Type::GetByName(const String& name)
Object::Ptr Type::Instantiate(void) const
{
return m_Factory();
ObjectFactory factory = GetFactory();
if (!factory)
return Object::Ptr();
return factory();
}
bool Type::IsAbstract(void) const
@ -67,7 +72,3 @@ bool Type::IsAssignableFrom(const Type::Ptr& other) const
return false;
}
void Type::SetFactory(const Type::Factory& factory)
{
m_Factory = factory;
}

View File

@ -59,9 +59,7 @@ enum TypeAttribute
class I2_BASE_API Type : public Object
{
public:
DECLARE_OBJECT(Type);
typedef boost::function<Object::Ptr (void)> Factory;
DECLARE_PTR_TYPEDEFS(Type);
virtual String GetName(void) const = 0;
virtual Type::Ptr GetBaseType(void) const = 0;
@ -79,14 +77,13 @@ public:
static void Register(const Type::Ptr& type);
static Type::Ptr GetByName(const String& name);
void SetFactory(const Factory& factory);
protected:
virtual ObjectFactory GetFactory(void) const = 0;
private:
typedef std::map<String, Type::Ptr> TypeMap;
static TypeMap& GetTypes(void);
Factory m_Factory;
};
template<typename T>
@ -94,32 +91,21 @@ class TypeImpl
{
};
template<typename T>
shared_ptr<T> ObjectFactory(void)
{
return make_shared<T>();
}
template<typename T>
struct FactoryHelper
{
Type::Factory GetFactory(void)
{
return ObjectFactory<T>;
}
};
#define REGISTER_TYPE(type) \
namespace { namespace UNIQUE_NAME(rt) { \
void RegisterType ## type(void) \
{ \
icinga::Type::Ptr t = make_shared<TypeImpl<type> >(); \
t->SetFactory(FactoryHelper<type>().GetFactory()); \
type::TypeInstance = t; \
icinga::Type::Register(t); \
} \
\
INITIALIZE_ONCE(RegisterType ## type); \
} }
} } \
DEFINE_TYPE_INSTANCE(type)
#define DEFINE_TYPE_INSTANCE(type) \
Type::Ptr type::TypeInstance;
}

View File

@ -29,7 +29,7 @@ namespace icinga
class I2_BASE_API UnixSocket : public Socket
{
public:
DECLARE_OBJECT(UnixSocket);
DECLARE_PTR_TYPEDEFS(UnixSocket);
UnixSocket(void);

View File

@ -48,7 +48,7 @@ enum ImpersonationLevel
class I2_CLI_API CLICommand : public Object
{
public:
DECLARE_OBJECT(CLICommand);
DECLARE_PTR_TYPEDEFS(CLICommand);
typedef std::vector<String>(*ArgumentCompletionCallback)(const String&, const String&);

View File

@ -33,7 +33,7 @@ namespace icinga
class DaemonCommand : public CLICommand
{
public:
DECLARE_OBJECT(DaemonCommand);
DECLARE_PTR_TYPEDEFS(DaemonCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class FeatureDisableCommand : public CLICommand
{
public:
DECLARE_OBJECT(FeatureDisableCommand);
DECLARE_PTR_TYPEDEFS(FeatureDisableCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class FeatureEnableCommand : public CLICommand
{
public:
DECLARE_OBJECT(FeatureEnableCommand);
DECLARE_PTR_TYPEDEFS(FeatureEnableCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class FeatureListCommand : public CLICommand
{
public:
DECLARE_OBJECT(FeatureListCommand);
DECLARE_PTR_TYPEDEFS(FeatureListCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeAddCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeAddCommand);
DECLARE_PTR_TYPEDEFS(NodeAddCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -40,7 +40,7 @@ enum BlackAndWhitelistCommandType
class I2_CLI_API BlackAndWhitelistCommand : public CLICommand
{
public:
DECLARE_OBJECT(BlackAndWhitelistCommand);
DECLARE_PTR_TYPEDEFS(BlackAndWhitelistCommand);
BlackAndWhitelistCommand(const String& type, BlackAndWhitelistCommandType command);

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeListCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeListCommand);
DECLARE_PTR_TYPEDEFS(NodeListCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeRemoveCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeRemoveCommand);
DECLARE_PTR_TYPEDEFS(NodeRemoveCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeSetCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeSetCommand);
DECLARE_PTR_TYPEDEFS(NodeSetCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeSetupCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeSetupCommand);
DECLARE_PTR_TYPEDEFS(NodeSetupCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeUpdateConfigCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeUpdateConfigCommand);
DECLARE_PTR_TYPEDEFS(NodeUpdateConfigCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class NodeWizardCommand : public CLICommand
{
public:
DECLARE_OBJECT(NodeWizardCommand);
DECLARE_PTR_TYPEDEFS(NodeWizardCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -36,7 +36,7 @@ namespace icinga
class ObjectListCommand : public CLICommand
{
public:
DECLARE_OBJECT(ObjectListCommand);
DECLARE_PTR_TYPEDEFS(ObjectListCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKINewCACommand : public CLICommand
{
public:
DECLARE_OBJECT(PKINewCACommand);
DECLARE_PTR_TYPEDEFS(PKINewCACommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKINewCertCommand : public CLICommand
{
public:
DECLARE_OBJECT(PKINewCertCommand);
DECLARE_PTR_TYPEDEFS(PKINewCertCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKIRequestCommand : public CLICommand
{
public:
DECLARE_OBJECT(PKIRequestCommand);
DECLARE_PTR_TYPEDEFS(PKIRequestCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKISaveCertCommand : public CLICommand
{
public:
DECLARE_OBJECT(PKISaveCertCommand);
DECLARE_PTR_TYPEDEFS(PKISaveCertCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKISignCSRCommand : public CLICommand
{
public:
DECLARE_OBJECT(PKISignCSRCommand);
DECLARE_PTR_TYPEDEFS(PKISignCSRCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -33,7 +33,7 @@ namespace icinga
class PKITicketCommand : public CLICommand
{
public:
DECLARE_OBJECT(PKITicketCommand);
DECLARE_PTR_TYPEDEFS(PKITicketCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -36,7 +36,7 @@ namespace icinga
class RepositoryClearChangesCommand : public CLICommand
{
public:
DECLARE_OBJECT(RepositoryClearChangesCommand);
DECLARE_PTR_TYPEDEFS(RepositoryClearChangesCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -36,7 +36,7 @@ namespace icinga
class RepositoryCommitCommand : public CLICommand
{
public:
DECLARE_OBJECT(RepositoryCommitCommand);
DECLARE_PTR_TYPEDEFS(RepositoryCommitCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -41,7 +41,7 @@ enum RepositoryCommandType
class I2_CLI_API RepositoryObjectCommand : public CLICommand
{
public:
DECLARE_OBJECT(RepositoryObjectCommand);
DECLARE_PTR_TYPEDEFS(RepositoryObjectCommand);
RepositoryObjectCommand(const String& type, RepositoryCommandType command);

View File

@ -36,7 +36,7 @@ namespace icinga
class VariableGetCommand : public CLICommand
{
public:
DECLARE_OBJECT(VariableGetCommand);
DECLARE_PTR_TYPEDEFS(VariableGetCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -36,7 +36,7 @@ namespace icinga
class VariableListCommand : public CLICommand
{
public:
DECLARE_OBJECT(VariableListCommand);
DECLARE_PTR_TYPEDEFS(VariableListCommand);
virtual String GetDescription(void) const;
virtual String GetShortDescription(void) const;

View File

@ -35,7 +35,7 @@ namespace icinga
*/
class I2_CONFIG_API ConfigItem : public Object {
public:
DECLARE_OBJECT(ConfigItem);
DECLARE_PTR_TYPEDEFS(ConfigItem);
ConfigItem(const String& type, const String& name, bool abstract,
const Expression::Ptr& exprl, const DebugInfo& debuginfo,

View File

@ -37,7 +37,7 @@ namespace icinga
class I2_CONFIG_API ConfigItemBuilder : public Object
{
public:
DECLARE_OBJECT(ConfigItemBuilder);
DECLARE_PTR_TYPEDEFS(ConfigItemBuilder);
ConfigItemBuilder(void);
explicit ConfigItemBuilder(const DebugInfo& debugInfo);

View File

@ -37,7 +37,7 @@ namespace icinga
*/
class I2_CONFIG_API ConfigType : public Object {
public:
DECLARE_OBJECT(ConfigType);
DECLARE_PTR_TYPEDEFS(ConfigType);
ConfigType(const String& name, const DebugInfo& debuginfo);

View File

@ -61,7 +61,7 @@ enum CombinedSetOp
class I2_CONFIG_API Expression : public Object
{
public:
DECLARE_OBJECT(Expression);
DECLARE_PTR_TYPEDEFS(Expression);
typedef Value (*OpCallback)(const Expression *, const Dictionary::Ptr&, DebugHint *dhint);

View File

@ -48,7 +48,7 @@ enum TypeValidationResult
class I2_CONFIG_API TypeRuleList : public Object
{
public:
DECLARE_OBJECT(TypeRuleList);
DECLARE_PTR_TYPEDEFS(TypeRuleList);
void SetValidator(const String& validator);
String GetValidator(void) const;

View File

@ -36,7 +36,7 @@ namespace icinga
class I2_ICINGA_API MacroResolver
{
public:
DECLARE_OBJECT(MacroResolver);
DECLARE_PTR_TYPEDEFS(MacroResolver);
virtual bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, String *result) const = 0;
};

View File

@ -43,7 +43,7 @@ enum ClientRole
class I2_REMOTE_API ApiClient : public Object
{
public:
DECLARE_OBJECT(ApiClient);
DECLARE_PTR_TYPEDEFS(ApiClient);
ApiClient(const String& identity, bool authenticated, const TlsStream::Ptr& stream, ConnectionRole role);

View File

@ -39,7 +39,7 @@ namespace icinga
class I2_REMOTE_API ApiFunction : public Object
{
public:
DECLARE_OBJECT(ApiFunction);
DECLARE_PTR_TYPEDEFS(ApiFunction);
typedef boost::function<Value(const MessageOrigin& origin, const Dictionary::Ptr&)> Callback;

View File

@ -26,7 +26,7 @@ using namespace icinga;
class TestObject : public Object
{
public:
DECLARE_OBJECT(TestObject);
DECLARE_PTR_TYPEDEFS(TestObject);
TestObject::Ptr GetTestRef(void)
{

View File

@ -114,6 +114,18 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
if (klass.Name.find_first_of(':') == std::string::npos)
std::cout << "class " << klass.Name << ";" << std::endl << std::endl;
/* TypeHelper */
if (klass.Attributes & TAAbstract) {
std::cout << "template<>" << std::endl
<< "struct TypeHelper<" << klass.Name << ">" << std::endl
<< "{" << std::endl
<< "\t" << "static ObjectFactory GetFactory(void)" << std::endl
<< "\t" << "{" << std::endl
<< "\t\t" << "return NULL;" << std::endl
<< "\t" << "}" << std::endl
<< "};" << std::endl << std::endl;
}
/* TypeImpl */
std::cout << "template<>" << std::endl
<< "class TypeImpl<" << klass.Name << ">"
@ -294,6 +306,12 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
std::cout << ";" << std::endl
<< "\t" << "}" << std::endl << std::endl;
/* GetFactory */
std::cout << "\t" << "virtual ObjectFactory GetFactory(void) const" << std::endl
<< "\t" << "{" << std::endl
<< "\t\t" << "return TypeHelper<" << klass.Name << ">::GetFactory();" << std::endl
<< "\t" << "}" << std::endl << std::endl;
std::cout << "};" << std::endl << std::endl;
/* ObjectImpl */
@ -302,8 +320,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
<< " : public " << (klass.Parent.empty() ? "Object" : klass.Parent) << std::endl
<< "{" << std::endl
<< "public:" << std::endl
<< "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl
<< "\t" << "IMPL_TYPE_LOOKUP(" << klass.Name << ");" << std::endl << std::endl;
<< "\t" << "DECLARE_PTR_TYPEDEFS(ObjectImpl<" << klass.Name << ">);" << std::endl;
if (!klass.Fields.empty()) {
/* constructor */
@ -466,18 +483,6 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
}
std::cout << "};" << std::endl << std::endl;
/* FactoryHelper */
if (klass.Attributes & TAAbstract) {
std::cout << "template<>" << std::endl
<< "struct FactoryHelper<" << klass.Name << ">" << std::endl
<< "{" << std::endl
<< "\t" << "Type::Factory GetFactory(void)" << std::endl
<< "\t" << "{" << std::endl
<< "\t\t" << "return Type::Factory();" << std::endl
<< "\t" << "}" << std::endl
<< "};" << std::endl << std::endl;
}
}
void ClassCompiler::CompileFile(const std::string& path)