src: Improved project load speed with move semantics and in-place initialization
* switched SearchIndex and HierarchyCache to std::unique_ptr * use move semantics and in-place initialization in StorageTypes and SearchIndex * improved autocompletion speed by fixing contained node type checking
This commit is contained in:
@@ -1319,29 +1319,21 @@ std::shared_ptr<DummyNode> GraphController::bundleByType(
|
||||
|
||||
if (!bundleInfoTree.children.empty())
|
||||
{
|
||||
std::list<std::shared_ptr<DummyNode>> bundledNodes;
|
||||
for (const std::shared_ptr<DummyNode>& node : bundleNode->bundledNodes)
|
||||
{
|
||||
bundledNodes.push_back(node);
|
||||
}
|
||||
std::list<std::shared_ptr<DummyNode>> bundledNodes(
|
||||
bundleNode->bundledNodes.begin(), bundleNode->bundledNodes.end());
|
||||
bundleNode->bundledNodes.clear();
|
||||
|
||||
// crate a sub-bundle for anonymous namespaces
|
||||
for (const Tree<NodeType::BundleInfo>& childBundleInfoTree : bundleInfoTree.children)
|
||||
{
|
||||
std::shared_ptr<DummyNode> childBundle = bundleByType(bundledNodes, type, childBundleInfoTree, true);
|
||||
|
||||
|
||||
if (childBundle)
|
||||
{
|
||||
bundleNode->bundledNodes.insert(childBundle);
|
||||
}
|
||||
}
|
||||
|
||||
for (const std::shared_ptr<DummyNode>& bundledNode : bundledNodes)
|
||||
{
|
||||
bundleNode->bundledNodes.insert(bundledNode);
|
||||
}
|
||||
bundleNode->bundledNodes.insert(bundledNodes.begin(), bundledNodes.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,21 +1344,16 @@ void GraphController::bundleNodesByType()
|
||||
{
|
||||
TRACE();
|
||||
|
||||
std::vector<std::shared_ptr<DummyNode>> oldNodes = m_dummyNodes;
|
||||
std::list<std::shared_ptr<DummyNode>> nodes(m_dummyNodes.begin(), m_dummyNodes.end());
|
||||
std::vector<std::shared_ptr<DummyNode>> oldNodes = std::move(m_dummyNodes);
|
||||
m_dummyNodes.clear();
|
||||
|
||||
std::list<std::shared_ptr<DummyNode>> nodes;
|
||||
for (size_t i = 0; i < oldNodes.size(); i++)
|
||||
{
|
||||
nodes.push_back(oldNodes[i]);
|
||||
}
|
||||
|
||||
for (const NodeType& nodeType : NodeType::getOverviewBundleNodeTypesOrdered())
|
||||
{
|
||||
Tree<NodeType::BundleInfo> bundleInfoTree = nodeType.getOverviewBundleTree();
|
||||
if (bundleInfoTree.data.isValid())
|
||||
{
|
||||
std::shared_ptr<DummyNode> bundleNode = bundleByType(nodes, nodeType, bundleInfoTree);
|
||||
std::shared_ptr<DummyNode> bundleNode = bundleByType(nodes, nodeType, bundleInfoTree, false);
|
||||
if (bundleNode)
|
||||
{
|
||||
m_dummyNodes.push_back(bundleNode);
|
||||
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
std::list<std::shared_ptr<DummyNode>>& nodes,
|
||||
const NodeType& type,
|
||||
const Tree<NodeType::BundleInfo>& bundleInfoTree,
|
||||
const bool considerInvisibleNodes = false);
|
||||
const bool considerInvisibleNodes);
|
||||
void bundleNodesByType();
|
||||
|
||||
void addCharacterIndex();
|
||||
|
||||
@@ -342,7 +342,7 @@ std::vector<std::tuple<Id, Id, std::vector<Id>>> HierarchyCache::getInheritanceE
|
||||
|
||||
HierarchyCache::HierarchyNode* HierarchyCache::getNode(Id nodeId) const
|
||||
{
|
||||
std::map<Id, std::shared_ptr<HierarchyNode>>::const_iterator it = m_nodes.find(nodeId);
|
||||
auto it = m_nodes.find(nodeId);
|
||||
|
||||
if (it != m_nodes.end())
|
||||
{
|
||||
@@ -354,11 +354,11 @@ HierarchyCache::HierarchyNode* HierarchyCache::getNode(Id nodeId) const
|
||||
|
||||
HierarchyCache::HierarchyNode* HierarchyCache::createNode(Id nodeId)
|
||||
{
|
||||
std::map<Id, std::shared_ptr<HierarchyNode>>::iterator it = m_nodes.find(nodeId);
|
||||
auto it = m_nodes.find(nodeId);
|
||||
|
||||
if (it == m_nodes.end())
|
||||
{
|
||||
it = m_nodes.emplace(nodeId, std::make_shared<HierarchyNode>(nodeId)).first;
|
||||
it = m_nodes.emplace(nodeId, std::make_unique<HierarchyNode>(nodeId)).first;
|
||||
}
|
||||
|
||||
return it->second.get();
|
||||
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
HierarchyNode* getNode(Id nodeId) const;
|
||||
HierarchyNode* createNode(Id nodeId);
|
||||
|
||||
std::map<Id, std::shared_ptr<HierarchyNode>> m_nodes;
|
||||
std::map<Id, std::unique_ptr<HierarchyNode>> m_nodes;
|
||||
};
|
||||
|
||||
#endif // HIERARCHY_CACHE_H
|
||||
|
||||
@@ -13,12 +13,12 @@ std::vector<NodeType> NodeType::getOverviewBundleNodeTypesOrdered()
|
||||
NodeType(NodeType::NODE_CLASS),
|
||||
NodeType(NodeType::NODE_INTERFACE),
|
||||
NodeType(NodeType::NODE_STRUCT),
|
||||
NodeType(NodeType::NODE_UNION),
|
||||
NodeType(NodeType::NODE_FUNCTION),
|
||||
NodeType(NodeType::NODE_GLOBAL_VARIABLE),
|
||||
NodeType(NodeType::NODE_TYPE),
|
||||
NodeType(NodeType::NODE_TYPEDEF),
|
||||
NodeType(NodeType::NODE_ENUM),
|
||||
NodeType(NodeType::NODE_UNION),
|
||||
NodeType(NodeType::NODE_ENUM)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ NodeTypeSet::NodeTypeSet()
|
||||
}
|
||||
|
||||
NodeTypeSet::NodeTypeSet(const NodeType& type)
|
||||
: m_nodeTypeMask(nodeTypeToMask(type))
|
||||
{
|
||||
m_nodeTypeMask = nodeTypeToMask(type);
|
||||
}
|
||||
|
||||
bool NodeTypeSet::operator==(const NodeTypeSet& other) const
|
||||
@@ -36,6 +36,21 @@ bool NodeTypeSet::operator!=(const NodeTypeSet& other) const
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
std::vector<NodeType> NodeTypeSet::getNodeTypes() const
|
||||
{
|
||||
std::vector<NodeType> nodeTypes;
|
||||
|
||||
for (const NodeType& type : s_allNodeTypes)
|
||||
{
|
||||
if (m_nodeTypeMask & nodeTypeToMask(type))
|
||||
{
|
||||
nodeTypes.push_back(type);
|
||||
}
|
||||
}
|
||||
|
||||
return nodeTypes;
|
||||
}
|
||||
|
||||
void NodeTypeSet::invert()
|
||||
{
|
||||
m_nodeTypeMask = ~m_nodeTypeMask;
|
||||
@@ -53,19 +68,9 @@ void NodeTypeSet::add(const NodeTypeSet& typeSet)
|
||||
m_nodeTypeMask |= typeSet.m_nodeTypeMask;
|
||||
}
|
||||
|
||||
std::vector<NodeType> NodeTypeSet::getNodeTypes() const
|
||||
NodeTypeSet NodeTypeSet::getWithAdded(const NodeTypeSet& typeSet) const
|
||||
{
|
||||
std::vector<NodeType> nodeTypes;
|
||||
|
||||
for (const NodeType& type : s_allNodeTypes)
|
||||
{
|
||||
if (m_nodeTypeMask & nodeTypeToMask(type))
|
||||
{
|
||||
nodeTypes.push_back(type);
|
||||
}
|
||||
}
|
||||
|
||||
return nodeTypes;
|
||||
return NodeTypeSet(m_nodeTypeMask | typeSet.m_nodeTypeMask);
|
||||
}
|
||||
|
||||
void NodeTypeSet::remove(const NodeTypeSet& typeSet)
|
||||
@@ -75,9 +80,7 @@ void NodeTypeSet::remove(const NodeTypeSet& typeSet)
|
||||
|
||||
NodeTypeSet NodeTypeSet::getWithRemoved(const NodeTypeSet& typeSet) const
|
||||
{
|
||||
NodeTypeSet ret(*this);
|
||||
ret.remove(typeSet);
|
||||
return ret;
|
||||
return NodeTypeSet(m_nodeTypeMask & ~typeSet.m_nodeTypeMask);
|
||||
}
|
||||
|
||||
void NodeTypeSet::keepMatching(const std::function<bool(const NodeType&)>& matcher)
|
||||
@@ -158,6 +161,11 @@ std::vector<Id> NodeTypeSet::getNodeTypeIds() const
|
||||
return ids;
|
||||
}
|
||||
|
||||
NodeTypeSet::NodeTypeSet(NodeTypeSet::MaskType typeMask)
|
||||
: m_nodeTypeMask(typeMask)
|
||||
{
|
||||
}
|
||||
|
||||
NodeTypeSet::MaskType NodeTypeSet::nodeTypeToMask(const NodeType& nodeType)
|
||||
{
|
||||
// todo: convert to mask if ids are not power of two anymore
|
||||
|
||||
@@ -20,11 +20,13 @@ public:
|
||||
bool operator==(const NodeTypeSet& other) const;
|
||||
bool operator!=(const NodeTypeSet& other) const;
|
||||
|
||||
std::vector<NodeType> getNodeTypes() const;
|
||||
|
||||
void invert();
|
||||
NodeTypeSet getInverse() const;
|
||||
|
||||
void add(const NodeTypeSet& typeSet);
|
||||
std::vector<NodeType> getNodeTypes() const;
|
||||
NodeTypeSet getWithAdded(const NodeTypeSet& typeSet) const;
|
||||
|
||||
void remove(const NodeTypeSet& typeSet);
|
||||
NodeTypeSet getWithRemoved(const NodeTypeSet& typeSet) const;
|
||||
@@ -44,6 +46,8 @@ public:
|
||||
private:
|
||||
typedef unsigned long int MaskType;
|
||||
|
||||
NodeTypeSet(MaskType typeMask);
|
||||
|
||||
static MaskType nodeTypeToMask(const NodeType& nodeType);
|
||||
static const std::vector<NodeType> s_allNodeTypes;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ void Graph::forEachToken(std::function<void(Token*)> func) const
|
||||
forEachEdge(func);
|
||||
}
|
||||
|
||||
Node* Graph::createNode(Id id, NodeType type, const NameHierarchy& nameHierarchy, DefinitionKind definitionKind)
|
||||
Node* Graph::createNode(Id id, NodeType type, NameHierarchy nameHierarchy, DefinitionKind definitionKind)
|
||||
{
|
||||
Node* n = getNodeById(id);
|
||||
if (n)
|
||||
@@ -49,7 +49,7 @@ Node* Graph::createNode(Id id, NodeType type, const NameHierarchy& nameHierarchy
|
||||
return n;
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> node = std::make_shared<Node>(id, type, nameHierarchy, definitionKind);
|
||||
std::shared_ptr<Node> node = std::make_shared<Node>(id, type, std::move(nameHierarchy), definitionKind);
|
||||
m_nodes.emplace(node->getId(), node);
|
||||
return node.get();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
void forEachEdge(std::function<void(Edge*)> func) const;
|
||||
void forEachToken(std::function<void(Token*)> func) const;
|
||||
|
||||
Node* createNode(Id id, NodeType type, const NameHierarchy& nameHierarchy, DefinitionKind definitionKind);
|
||||
Node* createNode(Id id, NodeType type, NameHierarchy nameHierarchy, DefinitionKind definitionKind);
|
||||
Edge* createEdge(Id id, Edge::EdgeType type, Node* from, Node* to);
|
||||
|
||||
size_t getNodeCount() const;
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
#include "data/graph/token_component/TokenComponentConst.h"
|
||||
#include "data/graph/token_component/TokenComponentStatic.h"
|
||||
|
||||
Node::Node(Id id, NodeType type, const NameHierarchy& nameHierarchy, DefinitionKind definitionKind)
|
||||
Node::Node(Id id, NodeType type, NameHierarchy nameHierarchy, DefinitionKind definitionKind)
|
||||
: Token(id)
|
||||
, m_type(type)
|
||||
, m_nameHierarchy(nameHierarchy)
|
||||
, m_nameHierarchy(std::move(nameHierarchy))
|
||||
, m_definitionKind(definitionKind)
|
||||
, m_childCount(0)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ class Node
|
||||
: public Token
|
||||
{
|
||||
public:
|
||||
Node(Id id, NodeType type, const NameHierarchy& nameHierarchy, DefinitionKind definitionKind);
|
||||
Node(Id id, NodeType type, NameHierarchy nameHierarchy, DefinitionKind definitionKind);
|
||||
Node(const Node& other);
|
||||
virtual ~Node();
|
||||
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
std::map<Id, Edge*> m_edges;
|
||||
|
||||
NodeType m_type;
|
||||
NameHierarchy m_nameHierarchy;
|
||||
const NameHierarchy m_nameHierarchy;
|
||||
DefinitionKind m_definitionKind;
|
||||
|
||||
size_t m_childCount;
|
||||
|
||||
@@ -16,23 +16,24 @@ SearchIndex::~SearchIndex()
|
||||
{
|
||||
}
|
||||
|
||||
void SearchIndex::addNode(Id id, const std::wstring& name, NodeTypeSet typeSet)
|
||||
void SearchIndex::addNode(Id id, std::wstring name, NodeType type)
|
||||
{
|
||||
SearchNode* currentNode = m_root;
|
||||
|
||||
std::wstring remaining = name;
|
||||
while (remaining.size() > 0)
|
||||
while (name.size() > 0)
|
||||
{
|
||||
auto it = currentNode->edges.find(remaining[0]);
|
||||
currentNode->containedTypes.add(type);
|
||||
|
||||
auto it = currentNode->edges.find(name[0]);
|
||||
if (it != currentNode->edges.end())
|
||||
{
|
||||
SearchEdge* currentEdge = it->second;
|
||||
const std::wstring& edgeString = currentEdge->s;
|
||||
|
||||
size_t matchCount = 1;
|
||||
for (size_t j = 1; j < edgeString.size() && j < remaining.size(); j++)
|
||||
for (size_t j = 1; j < edgeString.size() && j < name.size(); j++)
|
||||
{
|
||||
if (edgeString[j] != remaining[j])
|
||||
if (edgeString[j] != name[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -42,47 +43,42 @@ void SearchIndex::addNode(Id id, const std::wstring& name, NodeTypeSet typeSet)
|
||||
if (matchCount < edgeString.size())
|
||||
{
|
||||
// split current edge
|
||||
std::shared_ptr<SearchNode> n = std::make_shared<SearchNode>();
|
||||
m_nodes.push_back(n);
|
||||
std::shared_ptr<SearchEdge> e = std::make_shared<SearchEdge>();
|
||||
m_edges.push_back(e);
|
||||
m_nodes.push_back(std::make_unique<SearchNode>(currentNode->containedTypes));
|
||||
SearchNode* n = m_nodes.back().get();
|
||||
|
||||
e->s = edgeString.substr(matchCount);
|
||||
e->target = currentEdge->target;
|
||||
m_edges.push_back(std::make_unique<SearchEdge>(currentEdge->target, edgeString.substr(matchCount)));
|
||||
SearchEdge* e = m_edges.back().get();
|
||||
|
||||
n->edges.emplace(e->s[0], e.get());
|
||||
n->edges.emplace(e->s[0], e);
|
||||
|
||||
currentEdge->s = edgeString.substr(0, matchCount);
|
||||
currentEdge->target = n.get();
|
||||
currentEdge->target = n;
|
||||
}
|
||||
|
||||
remaining = remaining.substr(matchCount);
|
||||
name = name.substr(matchCount);
|
||||
currentNode = currentEdge->target;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<SearchNode> n = std::make_shared<SearchNode>();
|
||||
m_nodes.push_back(n);
|
||||
std::shared_ptr<SearchEdge> e = std::make_shared<SearchEdge>();
|
||||
m_edges.push_back(e);
|
||||
m_nodes.push_back(std::make_unique<SearchNode>(currentNode->containedTypes));
|
||||
SearchNode* n = m_nodes.back().get();
|
||||
|
||||
e->s = remaining;
|
||||
e->target = n.get();
|
||||
m_edges.push_back(std::make_unique<SearchEdge>(n, std::move(name)));
|
||||
SearchEdge* e = m_edges.back().get();
|
||||
|
||||
currentNode->edges.emplace(e->s[0], e.get());
|
||||
currentNode = n.get();
|
||||
currentNode->edges.emplace(e->s[0], e);
|
||||
currentNode = n;
|
||||
|
||||
remaining = L"";
|
||||
name.clear();
|
||||
}
|
||||
}
|
||||
|
||||
currentNode->elementIds.insert(id);
|
||||
currentNode->containedTypes.add(typeSet);
|
||||
currentNode->elementIds.emplace(id, type);
|
||||
}
|
||||
|
||||
void SearchIndex::finishSetup()
|
||||
{
|
||||
for (auto p : m_root->edges)
|
||||
for (auto& p : m_root->edges)
|
||||
{
|
||||
populateEdgeGate(p.second);
|
||||
}
|
||||
@@ -93,21 +89,17 @@ void SearchIndex::clear()
|
||||
m_nodes.clear();
|
||||
m_edges.clear();
|
||||
|
||||
std::shared_ptr<SearchNode> n = std::make_shared<SearchNode>();
|
||||
m_nodes.push_back(n);
|
||||
m_nodes.push_back(std::make_unique<SearchNode>(NodeTypeSet()));
|
||||
|
||||
m_root = n.get();
|
||||
m_root = m_nodes.back().get();
|
||||
}
|
||||
|
||||
std::vector<SearchResult> SearchIndex::search(
|
||||
const std::wstring& query, NodeTypeSet acceptedNodeTypes, size_t maxResultCount, size_t maxBestScoredResultsLength) const
|
||||
{
|
||||
// find paths containing query
|
||||
SearchPath startPath;
|
||||
startPath.node = m_root;
|
||||
|
||||
std::vector<SearchPath> paths;
|
||||
searchRecursive(startPath, utility::toLowerCase(query), acceptedNodeTypes, &paths);
|
||||
searchRecursive(SearchPath(L"", {}, m_root), utility::toLowerCase(query), acceptedNodeTypes, &paths);
|
||||
|
||||
// create scored search results
|
||||
std::multiset<SearchResult> searchResults = createScoredResults(paths, acceptedNodeTypes, maxResultCount * 3);
|
||||
@@ -150,16 +142,16 @@ std::vector<SearchResult> SearchIndex::search(
|
||||
|
||||
void SearchIndex::populateEdgeGate(SearchEdge* e)
|
||||
{
|
||||
SearchNode* target = e->target;
|
||||
for (auto p : target->edges)
|
||||
for (auto& p : e->target->edges)
|
||||
{
|
||||
SearchEdge* targetEdge = p.second;
|
||||
populateEdgeGate(targetEdge);
|
||||
utility::append(e->gate, targetEdge->gate);
|
||||
}
|
||||
for (size_t i = 0; i < e->s.size(); i++)
|
||||
|
||||
for (const wchar_t& c : e->s)
|
||||
{
|
||||
e->gate.insert(towlower(e->s[i]));
|
||||
e->gate.insert(towlower(c));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,16 +159,15 @@ void SearchIndex::searchRecursive(
|
||||
const SearchPath& path, const std::wstring& remainingQuery, NodeTypeSet acceptedNodeTypes,
|
||||
std::vector<SearchIndex::SearchPath>* results) const
|
||||
{
|
||||
if (remainingQuery.size() == 0 && (acceptedNodeTypes.intersectsWith(path.node->containedTypes)))
|
||||
{
|
||||
results->push_back(std::move(path));
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto p : path.node->edges)
|
||||
for (const auto& p : path.node->edges)
|
||||
{
|
||||
const SearchEdge* currentEdge = p.second;
|
||||
|
||||
if (!acceptedNodeTypes.intersectsWith(currentEdge->target->containedTypes))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// test if s passes the edge's gate.
|
||||
bool passesGate = true;
|
||||
for (const wchar_t& c : remainingQuery)
|
||||
@@ -188,26 +179,31 @@ void SearchIndex::searchRecursive(
|
||||
}
|
||||
}
|
||||
|
||||
if (passesGate)
|
||||
if (!passesGate)
|
||||
{
|
||||
// consume characters for edge
|
||||
const std::wstring& edgeString = currentEdge->s;
|
||||
continue;
|
||||
}
|
||||
|
||||
SearchPath currentPath;
|
||||
currentPath.node = currentEdge->target;
|
||||
currentPath.indices = path.indices;
|
||||
currentPath.text = path.text + edgeString;
|
||||
// consume characters for edge
|
||||
const std::wstring& edgeString = currentEdge->s;
|
||||
SearchPath currentPath{ path.text + edgeString, path.indices, currentEdge->target };
|
||||
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < edgeString.size() && j < remainingQuery.size(); i++)
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < edgeString.size() && j < remainingQuery.size(); i++)
|
||||
{
|
||||
if (towlower(edgeString[i]) == remainingQuery[j])
|
||||
{
|
||||
if (towlower(edgeString[i]) == remainingQuery[j])
|
||||
{
|
||||
currentPath.indices.push_back(path.text.size() + i);
|
||||
j++;
|
||||
}
|
||||
currentPath.indices.push_back(path.text.size() + i);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == remainingQuery.size())
|
||||
{
|
||||
results->push_back(std::move(currentPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
searchRecursive(currentPath, remainingQuery.substr(j), acceptedNodeTypes, results);
|
||||
}
|
||||
}
|
||||
@@ -238,31 +234,34 @@ std::multiset<SearchResult> SearchIndex::createScoredResults(
|
||||
{
|
||||
if (!path.node->elementIds.empty() && (acceptedNodeTypes.intersectsWith(path.node->containedTypes)))
|
||||
{
|
||||
SearchResult result;
|
||||
result.text = path.text;
|
||||
result.elementIds = path.node->elementIds;
|
||||
result.indices = path.indices;
|
||||
result.score = scoreText(path.text, path.indices);
|
||||
searchResults.insert(std::move(result));
|
||||
|
||||
if (maxResultCount && searchResults.size() >= maxResultCount)
|
||||
std::vector<Id> elementIds;
|
||||
for (const auto& p : path.node->elementIds)
|
||||
{
|
||||
return searchResults;
|
||||
if (acceptedNodeTypes.contains(p.second))
|
||||
{
|
||||
elementIds.push_back(p.first);
|
||||
}
|
||||
}
|
||||
|
||||
if (!elementIds.empty())
|
||||
{
|
||||
searchResults.emplace(path.text, std::move(elementIds), path.indices, scoreText(path.text, path.indices));
|
||||
|
||||
if (maxResultCount && searchResults.size() >= maxResultCount)
|
||||
{
|
||||
return searchResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto p : path.node->edges)
|
||||
{
|
||||
const SearchEdge* edge = p.second;
|
||||
SearchPath nextPath;
|
||||
nextPath.indices = path.indices;
|
||||
nextPath.node = edge->target;
|
||||
nextPath.text = path.text + edge->s;
|
||||
nextPaths.push_back(std::move(nextPath));
|
||||
nextPaths.emplace_back(path.text + edge->s, path.indices, edge->target);
|
||||
}
|
||||
}
|
||||
|
||||
currentPaths = nextPaths;
|
||||
currentPaths = std::move(nextPaths);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,11 +470,7 @@ SearchResult SearchIndex::rescoreText(
|
||||
int score,
|
||||
size_t maxBestScoredResultsLength)
|
||||
{
|
||||
SearchResult result;
|
||||
result.text = text;
|
||||
result.score = score;
|
||||
result.indices = indices;
|
||||
|
||||
SearchResult result(text, {}, indices, score);
|
||||
std::vector<size_t> textIndices;
|
||||
|
||||
// match is already within text
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "utility/types.h"
|
||||
#include "data/graph/Node.h"
|
||||
@@ -15,13 +14,21 @@
|
||||
// SearchResult is only used as an internal type in the SearchIndex and the PersistentStorage
|
||||
struct SearchResult
|
||||
{
|
||||
SearchResult(std::wstring text, std::vector<Id> elementIds, std::vector<size_t> indices, int score)
|
||||
: text(std::move(text))
|
||||
, elementIds(std::move(elementIds))
|
||||
, indices(std::move(indices))
|
||||
, score(score)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const SearchResult& other) const
|
||||
{
|
||||
return score > other.score;
|
||||
}
|
||||
|
||||
std::wstring text;
|
||||
std::set<Id> elementIds;
|
||||
std::vector<Id> elementIds;
|
||||
std::vector<size_t> indices;
|
||||
int score;
|
||||
};
|
||||
@@ -32,7 +39,7 @@ public:
|
||||
SearchIndex();
|
||||
virtual ~SearchIndex();
|
||||
|
||||
void addNode(Id id, const std::wstring& name, NodeTypeSet typeSet = NodeTypeSet::all());
|
||||
void addNode(Id id, std::wstring name, NodeType type = NodeType::NODE_SYMBOL);
|
||||
void finishSetup();
|
||||
void clear();
|
||||
|
||||
@@ -45,20 +52,36 @@ private:
|
||||
|
||||
struct SearchNode
|
||||
{
|
||||
std::set<Id> elementIds;
|
||||
SearchNode(NodeTypeSet containedTypes)
|
||||
: containedTypes(containedTypes)
|
||||
{}
|
||||
|
||||
std::map<Id, NodeType> elementIds;
|
||||
NodeTypeSet containedTypes;
|
||||
std::map<wchar_t, SearchEdge*> edges;
|
||||
};
|
||||
|
||||
struct SearchEdge
|
||||
{
|
||||
SearchEdge(SearchNode* target, std::wstring s)
|
||||
: target(target)
|
||||
, s(std::move(s))
|
||||
{}
|
||||
|
||||
SearchNode* target;
|
||||
std::wstring s;
|
||||
std::unordered_set<wchar_t> gate;
|
||||
std::set<wchar_t> gate;
|
||||
};
|
||||
|
||||
struct SearchPath
|
||||
{
|
||||
SearchPath(std::wstring text, std::vector<size_t> indices, SearchNode* node)
|
||||
: text(std::move(text))
|
||||
, indices(std::move(indices))
|
||||
, node(node)
|
||||
{
|
||||
}
|
||||
|
||||
std::wstring text;
|
||||
std::vector<size_t> indices;
|
||||
SearchNode* node;
|
||||
@@ -89,8 +112,8 @@ public:
|
||||
static bool isNoLetter(const wchar_t c);
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<SearchNode>> m_nodes;
|
||||
std::vector<std::shared_ptr<SearchEdge>> m_edges;
|
||||
std::vector<std::unique_ptr<SearchNode>> m_nodes;
|
||||
std::vector<std::unique_ptr<SearchEdge>> m_edges;
|
||||
SearchNode* m_root;
|
||||
};
|
||||
|
||||
|
||||
@@ -749,7 +749,7 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionSymbolMatches(
|
||||
|
||||
for (const StorageNode& node : m_sqliteIndexStorage.getAllByIds<StorageNode>(elementIds))
|
||||
{
|
||||
storageNodeMap[node.id] = node;
|
||||
storageNodeMap.emplace(node.id, node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,7 +830,7 @@ std::vector<SearchMatch> PersistentStorage::getAutocompletionFileMatches(const s
|
||||
match.text = FilePath(match.name).fileName();
|
||||
match.subtext = match.name;
|
||||
|
||||
match.tokenIds = utility::toVector(result.elementIds);
|
||||
match.tokenIds = result.elementIds;
|
||||
if (match.tokenIds.size())
|
||||
{
|
||||
match.tokenName = NameHierarchy(getFileNodePath(match.tokenIds[0]).wstr(), NAME_DELIMITER_FILE);
|
||||
@@ -941,7 +941,7 @@ std::shared_ptr<Graph> PersistentStorage::getGraphForAll() const
|
||||
TRACE();
|
||||
|
||||
std::vector<Id> tokenIds;
|
||||
for (StorageNode& node: m_sqliteIndexStorage.getAll<StorageNode>())
|
||||
for (const StorageNode& node: m_sqliteIndexStorage.getAll<StorageNode>())
|
||||
{
|
||||
auto it = m_symbolDefinitionKinds.find(node.id);
|
||||
if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT &&
|
||||
@@ -2502,10 +2502,12 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
||||
|
||||
for (const StorageNode& storageNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(nodeIds))
|
||||
{
|
||||
NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName);
|
||||
|
||||
const NodeType type(utility::intToType(storageNode.type));
|
||||
if (type.isFile())
|
||||
{
|
||||
const FilePath filePath(NameHierarchy::deserialize(storageNode.serializedName).getRawName());
|
||||
const FilePath filePath(nameHierarchy.getRawName());
|
||||
|
||||
bool complete = getFileNodeComplete(storageNode.id);
|
||||
bool indexed = getFileNodeIndexed(storageNode.id);
|
||||
@@ -2520,8 +2522,6 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
||||
}
|
||||
else
|
||||
{
|
||||
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName);
|
||||
|
||||
DefinitionKind defKind = DEFINITION_NONE;
|
||||
auto it = m_symbolDefinitionKinds.find(storageNode.id);
|
||||
if (it != m_symbolDefinitionKinds.end())
|
||||
@@ -2529,7 +2529,7 @@ void PersistentStorage::addNodesToGraph(const std::vector<Id>& newNodeIds, Graph
|
||||
defKind = it->second;
|
||||
}
|
||||
|
||||
Node* node = graph->createNode(storageNode.id, type, nameHierarchy, defKind);
|
||||
Node* node = graph->createNode(storageNode.id, type, std::move(nameHierarchy), defKind);
|
||||
|
||||
if (addChildCount)
|
||||
{
|
||||
@@ -2875,7 +2875,7 @@ void PersistentStorage::buildFilePathMaps()
|
||||
{
|
||||
TRACE();
|
||||
|
||||
for (StorageFile& file: m_sqliteIndexStorage.getAll<StorageFile>())
|
||||
for (const StorageFile& file: m_sqliteIndexStorage.getAll<StorageFile>())
|
||||
{
|
||||
const FilePath path(file.filePath);
|
||||
|
||||
@@ -2903,9 +2903,9 @@ void PersistentStorage::buildSearchIndex()
|
||||
|
||||
const FilePath dbPath = getIndexDbFilePath();
|
||||
|
||||
for (StorageNode& node : m_sqliteIndexStorage.getAll<StorageNode>())
|
||||
for (const StorageNode& node : m_sqliteIndexStorage.getAll<StorageNode>())
|
||||
{
|
||||
NodeType type = utility::intToType(node.type);
|
||||
const NodeType type = utility::intToType(node.type);
|
||||
if (type.isFile())
|
||||
{
|
||||
bool indexed = getFileNodeIndexed(node.id);
|
||||
@@ -2945,7 +2945,7 @@ void PersistentStorage::buildSearchIndex()
|
||||
name = utility::replaceBetween(name, L'<', L'>', L"..");
|
||||
}
|
||||
|
||||
m_symbolIndex.addNode(node.id, name, type);
|
||||
m_symbolIndex.addNode(node.id, std::move(name), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1168,7 +1168,7 @@ std::vector<StorageEdge> SqliteIndexStorage::doGetAll<StorageEdge>(const std::st
|
||||
|
||||
if (id != 0 && type != -1)
|
||||
{
|
||||
edges.push_back(StorageEdge(id, type, sourceId, targetId));
|
||||
edges.emplace_back(id, type, sourceId, targetId);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1192,7 +1192,7 @@ std::vector<StorageNode> SqliteIndexStorage::doGetAll<StorageNode>(const std::st
|
||||
|
||||
if (id != 0 && type != -1)
|
||||
{
|
||||
nodes.push_back(StorageNode(id, type, utility::decodeFromUtf8(serializedName)));
|
||||
nodes.emplace_back(id, type, utility::decodeFromUtf8(serializedName));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1215,7 +1215,7 @@ std::vector<StorageSymbol> SqliteIndexStorage::doGetAll<StorageSymbol>(const std
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
symbols.push_back(StorageSymbol(id, definitionKind));
|
||||
symbols.emplace_back(id, definitionKind);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1241,7 +1241,7 @@ std::vector<StorageFile> SqliteIndexStorage::doGetAll<StorageFile>(const std::st
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
files.push_back(StorageFile(id, utility::decodeFromUtf8(filePath), modificationTime, indexed, complete));
|
||||
files.emplace_back(id, utility::decodeFromUtf8(filePath), modificationTime, indexed, complete);
|
||||
}
|
||||
q.nextRow();
|
||||
}
|
||||
@@ -1265,7 +1265,7 @@ std::vector<StorageLocalSymbol> SqliteIndexStorage::doGetAll<StorageLocalSymbol>
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
localSymbols.push_back(StorageLocalSymbol(id, utility::decodeFromUtf8(name)));
|
||||
localSymbols.emplace_back(id, utility::decodeFromUtf8(name));
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1294,7 +1294,7 @@ std::vector<StorageSourceLocation> SqliteIndexStorage::doGetAll<StorageSourceLoc
|
||||
|
||||
if (id != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1 && type != -1)
|
||||
{
|
||||
sourceLocations.push_back(StorageSourceLocation(id, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, type));
|
||||
sourceLocations.emplace_back(id, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber, type);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1318,7 +1318,7 @@ std::vector<StorageOccurrence> SqliteIndexStorage::doGetAll<StorageOccurrence>(c
|
||||
|
||||
if (elementId != 0 && sourceLocationId != 0)
|
||||
{
|
||||
occurrences.push_back(StorageOccurrence(elementId, sourceLocationId));
|
||||
occurrences.emplace_back(elementId, sourceLocationId);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1343,7 +1343,7 @@ std::vector<StorageComponentAccess> SqliteIndexStorage::doGetAll<StorageComponen
|
||||
|
||||
if (id != 0 && nodeId != 0 && type != -1)
|
||||
{
|
||||
componentAccesses.push_back(StorageComponentAccess(id, nodeId, type));
|
||||
componentAccesses.emplace_back(id, nodeId, type);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1371,9 +1371,9 @@ std::vector<StorageCommentLocation> SqliteIndexStorage::doGetAll<StorageCommentL
|
||||
|
||||
if (id != 0 && fileNodeId != 0 && startLineNumber != -1 && startColNumber != -1 && endLineNumber != -1 && endColNumber != -1)
|
||||
{
|
||||
commentLocations.push_back(StorageCommentLocation(
|
||||
commentLocations.emplace_back(
|
||||
id, fileNodeId, startLineNumber, startColNumber, endLineNumber, endColNumber
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
q.nextRow();
|
||||
@@ -1402,8 +1402,9 @@ std::vector<StorageError> SqliteIndexStorage::doGetAll<StorageError>(const std::
|
||||
|
||||
if (lineNumber != -1 && columnNumber != -1)
|
||||
{
|
||||
errors.push_back(StorageError(
|
||||
id, utility::decodeFromUtf8(message), utility::decodeFromUtf8(filePath), lineNumber, columnNumber, utility::decodeFromUtf8(translationUnit), fatal, indexed)
|
||||
errors.emplace_back(
|
||||
id, utility::decodeFromUtf8(message), utility::decodeFromUtf8(filePath), lineNumber, columnNumber,
|
||||
utility::decodeFromUtf8(translationUnit), fatal, indexed
|
||||
);
|
||||
id++;
|
||||
}
|
||||
|
||||
@@ -19,19 +19,19 @@ struct StorageErrorData
|
||||
{}
|
||||
|
||||
StorageErrorData(
|
||||
const std::wstring& message,
|
||||
const std::wstring& filePath,
|
||||
std::wstring message,
|
||||
std::wstring filePath,
|
||||
uint lineNumber,
|
||||
uint columnNumber,
|
||||
const std::wstring& translationUnit,
|
||||
std::wstring translationUnit,
|
||||
bool fatal,
|
||||
bool indexed
|
||||
)
|
||||
: message(message)
|
||||
, filePath(filePath)
|
||||
: message(std::move(message))
|
||||
, filePath(std::move(filePath))
|
||||
, lineNumber(lineNumber)
|
||||
, columnNumber(columnNumber)
|
||||
, translationUnit(translationUnit)
|
||||
, translationUnit(std::move(translationUnit))
|
||||
, fatal(fatal)
|
||||
, indexed(indexed)
|
||||
{}
|
||||
@@ -61,20 +61,20 @@ struct StorageError: public StorageErrorData
|
||||
|
||||
StorageError(
|
||||
Id id,
|
||||
const std::wstring& message,
|
||||
const std::wstring& filePath,
|
||||
std::wstring message,
|
||||
std::wstring filePath,
|
||||
uint lineNumber,
|
||||
uint columnNumber,
|
||||
const std::wstring& translationUnit,
|
||||
std::wstring translationUnit,
|
||||
bool fatal,
|
||||
bool indexed
|
||||
)
|
||||
: StorageErrorData(
|
||||
message,
|
||||
filePath,
|
||||
std::move(message),
|
||||
std::move(filePath),
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
translationUnit,
|
||||
std::move(translationUnit),
|
||||
fatal,
|
||||
indexed
|
||||
)
|
||||
|
||||
@@ -15,10 +15,10 @@ struct StorageFile
|
||||
, complete(true)
|
||||
{}
|
||||
|
||||
StorageFile(Id id, const std::wstring& filePath, const std::string& modificationTime, bool indexed, bool complete)
|
||||
StorageFile(Id id, std::wstring filePath, std::string modificationTime, bool indexed, bool complete)
|
||||
: id(id)
|
||||
, filePath(filePath)
|
||||
, modificationTime(modificationTime)
|
||||
, filePath(std::move(filePath))
|
||||
, modificationTime(std::move(modificationTime))
|
||||
, indexed(indexed)
|
||||
, complete(complete)
|
||||
{}
|
||||
|
||||
@@ -11,8 +11,8 @@ struct StorageLocalSymbolData
|
||||
: name(L"")
|
||||
{}
|
||||
|
||||
StorageLocalSymbolData(const std::wstring& name)
|
||||
: name(name)
|
||||
StorageLocalSymbolData(std::wstring name)
|
||||
: name(std::move(name))
|
||||
{}
|
||||
|
||||
std::wstring name;
|
||||
@@ -30,8 +30,8 @@ struct StorageLocalSymbol: public StorageLocalSymbolData
|
||||
, id(id)
|
||||
{}
|
||||
|
||||
StorageLocalSymbol(Id id, const std::wstring& name)
|
||||
: StorageLocalSymbolData(name)
|
||||
StorageLocalSymbol(Id id, std::wstring name)
|
||||
: StorageLocalSymbolData(std::move(name))
|
||||
, id(id)
|
||||
{}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ struct StorageNodeData
|
||||
, serializedName(L"")
|
||||
{}
|
||||
|
||||
StorageNodeData(int type, const std::wstring& serializedName)
|
||||
StorageNodeData(int type, std::wstring serializedName)
|
||||
: type(type)
|
||||
, serializedName(serializedName)
|
||||
, serializedName(std::move(serializedName))
|
||||
{}
|
||||
|
||||
int type;
|
||||
@@ -28,8 +28,8 @@ struct StorageNode: public StorageNodeData
|
||||
, id(0)
|
||||
{}
|
||||
|
||||
StorageNode(Id id, int type, const std::wstring& serializedName)
|
||||
: StorageNodeData(type, serializedName)
|
||||
StorageNode(Id id, int type, std::wstring serializedName)
|
||||
: StorageNodeData(type, std::move(serializedName))
|
||||
, id(id)
|
||||
{}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "data/name/NameHierarchy.h"
|
||||
#include "data/search/SearchIndex.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
class SearchIndexTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
@@ -16,7 +17,7 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(1, results.size());
|
||||
TS_ASSERT_EQUALS(1, results[0].elementIds.size());
|
||||
TS_ASSERT_DIFFERS(results[0].elementIds.end(), results[0].elementIds.find(1));
|
||||
TS_ASSERT(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
}
|
||||
|
||||
void test_search_index_finds_correct_indices_for_query()
|
||||
@@ -42,9 +43,9 @@ public:
|
||||
|
||||
TS_ASSERT_EQUALS(2, results.size());
|
||||
TS_ASSERT_EQUALS(1, results[0].elementIds.size());
|
||||
TS_ASSERT_DIFFERS(results[0].elementIds.end(), results[0].elementIds.find(1));
|
||||
TS_ASSERT(utility::containsElement<Id>(results[0].elementIds, 1));
|
||||
TS_ASSERT_EQUALS(1, results[1].elementIds.size());
|
||||
TS_ASSERT_DIFFERS(results[1].elementIds.end(), results[1].elementIds.find(2));
|
||||
TS_ASSERT(utility::containsElement<Id>(results[1].elementIds, 2));
|
||||
}
|
||||
|
||||
void test_search_index_does_not_find_anything_after_clear()
|
||||
|
||||
Reference in New Issue
Block a user