logic: improved performance of NodeTypeSet by internally using a bit-mask

This commit is contained in:
mlangkabel
2017-11-27 15:36:44 +01:00
parent 5fbf7b1acc
commit 4b854d4545
6 changed files with 108 additions and 73 deletions
+2
View File
@@ -530,6 +530,8 @@ add_files(
utility/utilityFile.cpp
utility/utilityFile.h
utility/utilityLibrary.h
utility/utilityMath.cpp
utility/utilityMath.h
utility/utilityString.cpp
utility/utilityString.h
utility/utilityUuid.cpp
+20 -20
View File
@@ -15,29 +15,29 @@ public:
typedef int TypeMask;
enum Type : NodeType::TypeMask
{ // make sure that the value of 0x0 is not used here because it doesn't work for bitmasking.
NODE_SYMBOL = 0x1,
NODE_TYPE = 0x2,
NODE_BUILTIN_TYPE = 0x4,
NODE_SYMBOL = 1 << 0,
NODE_TYPE = 1 << 1,
NODE_BUILTIN_TYPE = 1 << 2,
NODE_NAMESPACE = 0x8,
NODE_PACKAGE = 0x10,
NODE_STRUCT = 0x20,
NODE_CLASS = 0x40,
NODE_INTERFACE = 0x80,
NODE_GLOBAL_VARIABLE = 0x100,
NODE_FIELD = 0x200,
NODE_FUNCTION = 0x400,
NODE_METHOD = 0x800,
NODE_NAMESPACE = 1 << 3,
NODE_PACKAGE = 1 << 4,
NODE_STRUCT = 1 << 5,
NODE_CLASS = 1 << 6,
NODE_INTERFACE = 1 << 7,
NODE_GLOBAL_VARIABLE = 1 << 8,
NODE_FIELD = 1 << 9,
NODE_FUNCTION = 1 << 10,
NODE_METHOD = 1 << 11,
NODE_ENUM = 0x1000,
NODE_ENUM_CONSTANT = 0x2000,
NODE_TYPEDEF = 0x4000,
NODE_TEMPLATE_PARAMETER_TYPE = 0x8000,
NODE_TYPE_PARAMETER = 0x10000,
NODE_ENUM = 1 << 12,
NODE_ENUM_CONSTANT = 1 << 13,
NODE_TYPEDEF = 1 << 14,
NODE_TEMPLATE_PARAMETER_TYPE = 1 << 15,
NODE_TYPE_PARAMETER = 1 << 16,
NODE_FILE = 0x20000,
NODE_MACRO = 0x40000,
NODE_UNION = 0x80000,
NODE_FILE = 1 << 17,
NODE_MACRO = 1 << 18,
NODE_UNION = 1 << 19,
NODE_MAX_VALUE = NODE_UNION
};
+56 -51
View File
@@ -1,32 +1,12 @@
#include "data/NodeTypeSet.h"
#include "utility/utility.h"
#include "utility/utilityMath.h"
NodeTypeSet NodeTypeSet::all()
{
NodeTypeSet ret;
ret.add(NodeType(NodeType::NODE_SYMBOL));
ret.add(NodeType(NodeType::NODE_TYPE));
ret.add(NodeType(NodeType::NODE_BUILTIN_TYPE));
ret.add(NodeType(NodeType::NODE_NAMESPACE));
ret.add(NodeType(NodeType::NODE_PACKAGE));
ret.add(NodeType(NodeType::NODE_STRUCT));
ret.add(NodeType(NodeType::NODE_CLASS));
ret.add(NodeType(NodeType::NODE_INTERFACE));
ret.add(NodeType(NodeType::NODE_GLOBAL_VARIABLE));
ret.add(NodeType(NodeType::NODE_FIELD));
ret.add(NodeType(NodeType::NODE_FUNCTION));
ret.add(NodeType(NodeType::NODE_METHOD));
ret.add(NodeType(NodeType::NODE_ENUM));
ret.add(NodeType(NodeType::NODE_ENUM_CONSTANT));
ret.add(NodeType(NodeType::NODE_TYPEDEF));
ret.add(NodeType(NodeType::NODE_TEMPLATE_PARAMETER_TYPE));
ret.add(NodeType(NodeType::NODE_TYPE_PARAMETER));
ret.add(NodeType(NodeType::NODE_FILE));
ret.add(NodeType(NodeType::NODE_MACRO));
ret.add(NodeType(NodeType::NODE_UNION));
ret.m_nodeTypeMask = ~0;
return ret;
}
@@ -37,17 +17,17 @@ NodeTypeSet NodeTypeSet::none()
NodeTypeSet::NodeTypeSet()
{
std::string i;
m_nodeTypeMask = 0;
}
NodeTypeSet::NodeTypeSet(const NodeType& type)
{
m_nodeTypes.insert(type);
m_nodeTypeMask = nodeTypeToMask(type);
}
bool NodeTypeSet::operator==(const NodeTypeSet& other) const
{
return utility::isPermutation(getNodeTypeIds(), other.getNodeTypeIds()); // TODO: reimplement using mask
return m_nodeTypeMask == other.m_nodeTypeMask;
}
bool NodeTypeSet::operator!=(const NodeTypeSet& other) const
@@ -57,8 +37,7 @@ bool NodeTypeSet::operator!=(const NodeTypeSet& other) const
void NodeTypeSet::invert()
{
NodeTypeSet inverse = NodeTypeSet::all().getWithRemoved(*this);
m_nodeTypes = std::move(inverse.m_nodeTypes);
m_nodeTypeMask = ~m_nodeTypeMask;
}
NodeTypeSet NodeTypeSet::getInverse() const
@@ -70,24 +49,27 @@ NodeTypeSet NodeTypeSet::getInverse() const
void NodeTypeSet::add(const NodeTypeSet& typeSet)
{
utility::append(m_nodeTypes, typeSet.m_nodeTypes);
m_nodeTypeMask |= typeSet.m_nodeTypeMask;
}
std::set<NodeType> NodeTypeSet::getNodeTypes() const
std::vector<NodeType> NodeTypeSet::getNodeTypes() const
{
return m_nodeTypes;
std::vector<NodeType> nodeTypes;
for (const NodeType& type : s_allNodeTypes)
{
if (m_nodeTypeMask & nodeTypeToMask(type))
{
nodeTypes.push_back(type);
}
}
return nodeTypes;
}
void NodeTypeSet::remove(const NodeTypeSet& typeSet)
{
for (const NodeType& type : typeSet.getNodeTypes())
{
std::set<NodeType>::const_iterator it = m_nodeTypes.find(type);
if (it != m_nodeTypes.end())
{
m_nodeTypes.erase(it);
}
}
m_nodeTypeMask &= ~typeSet.m_nodeTypeMask;
}
NodeTypeSet NodeTypeSet::getWithRemoved(const NodeTypeSet& typeSet) const
@@ -99,35 +81,58 @@ NodeTypeSet NodeTypeSet::getWithRemoved(const NodeTypeSet& typeSet) const
bool NodeTypeSet::isEmpty() const
{
return m_nodeTypes.empty();
return m_nodeTypeMask == 0;
}
bool NodeTypeSet::contains(const NodeType& type) const
{
return m_nodeTypes.find(type) != m_nodeTypes.end();
return m_nodeTypeMask & nodeTypeToMask(type);
}
bool NodeTypeSet::intersectsWith(const NodeTypeSet& typeSet) const
{
for (const NodeType& type : typeSet.getNodeTypes())
{
std::set<NodeType>::const_iterator it = m_nodeTypes.find(type);
if (it != m_nodeTypes.end())
{
return true;
}
}
return false;
return m_nodeTypeMask & typeSet.m_nodeTypeMask;
}
std::vector<Id> NodeTypeSet::getNodeTypeIds() const
{
std::vector<Id> ids;
for (const NodeType type : m_nodeTypes)
for (const NodeType& type: s_allNodeTypes)
{
ids.push_back(type.getId());
if (m_nodeTypeMask & nodeTypeToMask(type))
{
ids.push_back(type.getId());
}
}
return ids;
}
NodeTypeSet::MaskType NodeTypeSet::nodeTypeToMask(const NodeType& nodeType)
{
// todo: convert to mask if ids are not power of two anymore
return nodeType.getId();
}
const std::vector<NodeType> NodeTypeSet::s_allNodeTypes = {
NodeType(NodeType::NODE_SYMBOL),
NodeType(NodeType::NODE_TYPE),
NodeType(NodeType::NODE_BUILTIN_TYPE),
NodeType(NodeType::NODE_NAMESPACE),
NodeType(NodeType::NODE_PACKAGE),
NodeType(NodeType::NODE_STRUCT),
NodeType(NodeType::NODE_CLASS),
NodeType(NodeType::NODE_INTERFACE),
NodeType(NodeType::NODE_FIELD),
NodeType(NodeType::NODE_FUNCTION),
NodeType(NodeType::NODE_METHOD),
NodeType(NodeType::NODE_ENUM),
NodeType(NodeType::NODE_ENUM_CONSTANT),
NodeType(NodeType::NODE_TYPEDEF),
NodeType(NodeType::NODE_TEMPLATE_PARAMETER_TYPE),
NodeType(NodeType::NODE_TYPE_PARAMETER),
NodeType(NodeType::NODE_FILE),
NodeType(NodeType::NODE_MACRO),
NodeType(NodeType::NODE_UNION)
};
+8 -2
View File
@@ -23,7 +23,7 @@ public:
NodeTypeSet getInverse() const;
void add(const NodeTypeSet& typeSet);
std::set<NodeType> getNodeTypes() const;
std::vector<NodeType> getNodeTypes() const;
void remove(const NodeTypeSet& typeSet);
NodeTypeSet getWithRemoved(const NodeTypeSet& typeSet) const;
@@ -34,7 +34,13 @@ public:
std::vector<Id> getNodeTypeIds() const;
private:
std::set<NodeType> m_nodeTypes;
typedef unsigned long int MaskType;
static MaskType nodeTypeToMask(const NodeType& nodeType);
static const std::vector<NodeType> s_allNodeTypes;
MaskType m_nodeTypeMask;
//std::set<NodeType> m_nodeTypes;
};
#endif // NODE_TYPE_SET_H
+13
View File
@@ -0,0 +1,13 @@
#include "utility/utilityMath.h"
unsigned long int utility::getPowerOfTwo(unsigned int exponent)
{
static const long int powerOfTwos[] =
{
1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7,
1 << 8, 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15,
1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, 1 << 21, 1 << 22, 1 << 23,
1 << 24, 1 << 25, 1 << 26, 1 << 27, 1 << 28, 1 << 29, 1 << 30, 1 << 31
};
return powerOfTwos[exponent];
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef UTILITY_MATH_H
#define UTILITY_MATH_H
namespace utility
{
unsigned long int getPowerOfTwo(unsigned int exponent);
}
#endif // UTILITY_MATH_H