data: removed Singleton from Dictionary and made it a member of SearchIndex

Dictionary never had a good reason of being a Singleton in the first place so this will avoid concurrency and
structural issues in the future.
This commit is contained in:
Eberhard Graether
2014-09-30 22:10:42 +02:00
parent 95ece9ef2e
commit 390df1db1f
13 changed files with 128 additions and 103 deletions
+18 -8
View File
@@ -5,7 +5,6 @@
#include "data/query/QueryToken.h"
#include "utility/logging/logging.h"
#include "utility/text/Dictionary.h"
#include "utility/utilityString.h"
namespace
@@ -131,21 +130,22 @@ std::deque<SearchIndex::SearchNode*> SearchIndex::SearchNode::getParentsWithoutT
return nodes;
}
std::shared_ptr<SearchIndex::SearchNode> SearchIndex::SearchNode::addNodeRecursive(std::deque<Id>* nameIds)
{
std::shared_ptr<SearchIndex::SearchNode> SearchIndex::SearchNode::addNodeRecursive(
std::deque<Id>* nameIds, const Dictionary& dictionary
){
Id nameId = nameIds->front();
nameIds->pop_front();
std::shared_ptr<SearchNode> node = getChildWithNameId(nameId);
if (!node)
{
node = std::make_shared<SearchNode>(this, Dictionary::getInstance()->getWord(nameId), nameId);
node = std::make_shared<SearchNode>(this, dictionary.getWord(nameId), nameId);
m_nodes.insert(node);
}
if (nameIds->size())
{
return node->addNodeRecursive(nameIds);
return node->addNodeRecursive(nameIds, dictionary);
}
return node;
@@ -374,13 +374,23 @@ void SearchIndex::clear()
m_root.m_nodes.clear();
}
Id SearchIndex::getWordId(const std::string& word)
{
return m_dictionary.getWordId(word);
}
const std::string& SearchIndex::getWord(Id wordId) const
{
return m_dictionary.getWord(wordId);
}
SearchIndex::SearchNode* SearchIndex::addNode(const std::string& fullName)
{
std::deque<Id> nameIds = Dictionary::getInstance()->getWordIds(fullName, DELIMITER);
std::deque<Id> nameIds = m_dictionary.getWordIds(fullName, DELIMITER);
if (nameIds.size())
{
return m_root.addNodeRecursive(&nameIds).get();
return m_root.addNodeRecursive(&nameIds, m_dictionary).get();
}
return nullptr;
@@ -388,7 +398,7 @@ SearchIndex::SearchNode* SearchIndex::addNode(const std::string& fullName)
SearchIndex::SearchNode* SearchIndex::getNode(const std::string& fullName) const
{
std::deque<Id> nameIds = Dictionary::getInstance()->getWordIds(fullName, DELIMITER);
std::deque<Id> nameIds = m_dictionary.getWordIdsConst(fullName, DELIMITER);
if (nameIds.size())
{
+6 -1
View File
@@ -8,6 +8,7 @@
#include <set>
#include <vector>
#include "utility/text/Dictionary.h"
#include "utility/types.h"
class SearchIndex
@@ -54,7 +55,7 @@ public:
private:
// Accessed by SearchIndex
std::shared_ptr<SearchNode> addNodeRecursive(std::deque<Id>* nameIds);
std::shared_ptr<SearchNode> addNodeRecursive(std::deque<Id>* nameIds, const Dictionary& dictionary);
std::shared_ptr<SearchNode> getNodeRecursive(std::deque<Id>* nameIds) const;
std::vector<SearchIndex::SearchMatch> findFuzzyMatches(const std::string& query) const;
@@ -84,6 +85,9 @@ public:
void clear();
Id getWordId(const std::string& word);
const std::string& getWord(Id wordId) const;
SearchNode* addNode(const std::string& fullName);
SearchNode* getNode(const std::string& fullName) const;
@@ -93,6 +97,7 @@ public:
private:
SearchNode m_root;
Dictionary m_dictionary;
};
#endif // SEARCH_INDEX_H
+9 -13
View File
@@ -535,22 +535,14 @@ const Graph& Storage::getGraph() const
return m_graph;
}
Token* Storage::getTokenWithId(Id tokenId) const
const TokenLocationCollection& Storage::getTokenLocationCollection() const
{
return m_graph.getTokenById(tokenId);
return m_locationCollection;
}
std::vector<TokenLocation*> Storage::getTokenLocationsForId(Id tokenId) const
const SearchIndex& Storage::getSearchIndex() const
{
const std::vector<Id>& locationIds = getTokenWithId(tokenId)->getLocationIds();
std::vector<TokenLocation*> result;
for (Id locationId : locationIds)
{
result.push_back(m_locationCollection.findTokenLocationById(locationId));
}
return result;
return m_index;
}
void Storage::initSearchIndex()
@@ -582,7 +574,11 @@ Node* Storage::addNodeHierarchyWithDistinctSignature(Node::NodeType type, const
return nullptr;
}
return m_graph.createNodeHierarchyWithDistinctSignature(type, searchNode, ParserClient::functionSignatureStr(function));
// TODO: Instead of saving the whole signature string, the signature should be just a set of wordIds.
Id signatureId = m_index.getWordId(ParserClient::functionSignatureStr(function));
std::shared_ptr<TokenComponentSignature> signature = std::make_shared<TokenComponentSignature>(signatureId);
return m_graph.createNodeHierarchyWithDistinctSignature(type, searchNode, signature);
}
TokenComponentAccess::AccessType Storage::convertAccessType(ParserClient::AccessType access) const
+2 -2
View File
@@ -85,8 +85,8 @@ public:
protected:
const Graph& getGraph() const;
Token* getTokenWithId(Id tokenId) const;
std::vector<TokenLocation*> getTokenLocationsForId(Id tokenId) const;
const TokenLocationCollection& getTokenLocationCollection() const;
const SearchIndex& getSearchIndex() const;
private:
void initSearchIndex();
+5 -8
View File
@@ -1,7 +1,6 @@
#include "data/graph/StorageGraph.h"
#include "data/graph/token_component/TokenComponentName.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "utility/logging/logging.h"
#include "utility/utilityString.h"
@@ -30,11 +29,9 @@ Node* StorageGraph::createNodeHierarchy(Node::NodeType type, SearchIndex::Search
}
Node* StorageGraph::createNodeHierarchyWithDistinctSignature(
Node::NodeType type, SearchIndex::SearchNode* searchNode, const std::string& signature
Node::NodeType type, SearchIndex::SearchNode* searchNode, std::shared_ptr<TokenComponentSignature> signature
){
Node* node = getNodeById(searchNode->getFirstTokenId());
std::shared_ptr<TokenComponentSignature> sigPtr = TokenComponentSignature::create(signature);
if (!node)
{
node = insertNodeHierarchy(type, searchNode);
@@ -42,10 +39,10 @@ Node* StorageGraph::createNodeHierarchyWithDistinctSignature(
else
{
std::function<bool(Node*)> findSignature =
[sigPtr](Node* n)
[signature](Node* n)
{
TokenComponentSignature* c = n->getComponent<TokenComponentSignature>();
return c && *c == *sigPtr.get();
TokenComponentSignature* sig = n->getComponent<TokenComponentSignature>();
return sig && *sig == *signature.get();
};
Node* parentNode = node->getParentNode();
@@ -72,7 +69,7 @@ Node* StorageGraph::createNodeHierarchyWithDistinctSignature(
}
}
node->addComponentSignature(sigPtr);
node->addComponentSignature(signature);
return node;
}
+2 -1
View File
@@ -2,6 +2,7 @@
#define STORAGE_GRAPH_H
#include "data/graph/Graph.h"
#include "data/graph/token_component/TokenComponentSignature.h"
#include "data/SearchIndex.h"
class StorageGraph
@@ -13,7 +14,7 @@ public:
Node* createNodeHierarchy(Node::NodeType type, SearchIndex::SearchNode* searchNode);
Node* createNodeHierarchyWithDistinctSignature(
Node::NodeType type, SearchIndex::SearchNode* searchNode, const std::string& signature);
Node::NodeType type, SearchIndex::SearchNode* searchNode, std::shared_ptr<TokenComponentSignature> signature);
Edge* createEdge(Edge::EdgeType type, Node* from, Node* to);
private:
@@ -1,11 +1,8 @@
#include "data/graph/token_component/TokenComponentSignature.h"
#include "utility/text/Dictionary.h"
std::shared_ptr<TokenComponentSignature> TokenComponentSignature::create(const std::string& signature)
TokenComponentSignature::TokenComponentSignature(Id wordId)
: m_wordId(wordId)
{
return std::shared_ptr<TokenComponentSignature>(
new TokenComponentSignature(Dictionary::getInstance()->getWordId(signature)));
}
TokenComponentSignature::~TokenComponentSignature()
@@ -17,17 +14,12 @@ std::shared_ptr<TokenComponent> TokenComponentSignature::copy() const
return std::make_shared<TokenComponentSignature>(*this);
}
const std::string& TokenComponentSignature::getSignature() const
Id TokenComponentSignature::getWordId() const
{
return Dictionary::getInstance()->getWord(m_wordId);
return m_wordId;
}
bool TokenComponentSignature::operator==(const TokenComponentSignature& other) const
{
return m_wordId == other.m_wordId;
}
TokenComponentSignature::TokenComponentSignature(Id wordId)
: m_wordId(wordId)
{
}
@@ -1,9 +1,6 @@
#ifndef TOKEN_COMPONENT_SIGNATURE_H
#define TOKEN_COMPONENT_SIGNATURE_H
#include <memory>
#include <string>
#include "data/graph/token_component/TokenComponent.h"
#include "utility/types.h"
@@ -11,19 +8,16 @@ class TokenComponentSignature
: public TokenComponent
{
public:
static std::shared_ptr<TokenComponentSignature> create(const std::string& signature);
TokenComponentSignature(Id wordId);
virtual ~TokenComponentSignature();
virtual std::shared_ptr<TokenComponent> copy() const;
const std::string& getSignature() const;
Id getWordId() const;
bool operator==(const TokenComponentSignature& other) const;
private:
TokenComponentSignature(Id wordId);
const Id m_wordId;
};
+33 -15
View File
@@ -2,22 +2,34 @@
#include "utility/utilityString.h"
std::shared_ptr<Dictionary> Dictionary::getInstance()
Dictionary::Dictionary()
{
std::lock_guard<std::mutex> lockGuard(s_instanceMutex);
if (!s_instance)
{
s_instance = std::shared_ptr<Dictionary>(new Dictionary());
}
return s_instance;
}
Dictionary::~Dictionary()
{
}
void Dictionary::clear()
{
m_words.clear();
}
Id Dictionary::getWordId(const std::string& word)
{
Id wordId = getWordIdConst(word);
if (wordId)
{
return wordId;
}
m_words.emplace(++s_nextId, word);
return s_nextId;
}
Id Dictionary::getWordIdConst(const std::string& word) const
{
// TODO: This word lookup is very inefficient, use something smarter like a trie.
for (std::unordered_map<Id, std::string>::const_iterator it = m_words.begin(); it != m_words.end(); it++)
{
if (it->second == word)
@@ -26,8 +38,7 @@ Id Dictionary::getWordId(const std::string& word)
}
}
m_words.emplace(++s_nextId, word);
return s_nextId;
return 0;
}
std::deque<Id> Dictionary::getWordIds(const std::string& wordList, const std::string& delimiter)
@@ -43,6 +54,19 @@ std::deque<Id> Dictionary::getWordIds(const std::string& wordList, const std::st
return ids;
}
std::deque<Id> Dictionary::getWordIdsConst(const std::string& wordList, const std::string& delimiter) const
{
std::deque<std::string> words = utility::split(wordList, delimiter);
std::deque<Id> ids;
for (const std::string& word: words)
{
ids.push_back(getWordIdConst(word));
}
return ids;
}
const std::string& Dictionary::getWord(Id id) const
{
std::unordered_map<Id, std::string>::const_iterator it = m_words.find(id);
@@ -72,10 +96,4 @@ std::string Dictionary::getWord(const std::deque<Id> ids, const std::string& del
return word;
}
Dictionary::Dictionary()
{
}
std::shared_ptr<Dictionary> Dictionary::s_instance;
std::mutex Dictionary::s_instanceMutex;
Id Dictionary::s_nextId = 0;
+6 -7
View File
@@ -12,23 +12,22 @@
class Dictionary
{
public:
static std::shared_ptr<Dictionary> getInstance();
Dictionary();
~Dictionary();
void clear();
Id getWordId(const std::string& word);
Id getWordIdConst(const std::string& word) const;
std::deque<Id> getWordIds(const std::string& wordList, const std::string& delimiter);
std::deque<Id> getWordIdsConst(const std::string& wordList, const std::string& delimiter) const;
// Note: References to values in an unordered_map don't change on rehashing so they can be saved and used elsewhere.
const std::string& getWord(Id id) const;
std::string getWord(const std::deque<Id> ids, const std::string& delimiter) const;
private:
Dictionary();
Dictionary(const Dictionary&);
void operator=(const Dictionary&);
static std::shared_ptr<Dictionary> s_instance;
static std::mutex s_instanceMutex;
static Id s_nextId;
std::unordered_map<Id, std::string> m_words;