Skip to content

Commit

Permalink
dictionary: changed key hash to standard unordered key map
Browse files Browse the repository at this point in the history
added key map alias for convenience
renamed key hash member to key map
use standard transform function to convert string to upper case
changed to use iterator when adding keys to map
  • Loading branch information
thunder422 committed Oct 4, 2014
1 parent 8487553 commit 66561d4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
25 changes: 15 additions & 10 deletions dictionary.cpp
Expand Up @@ -37,7 +37,7 @@ void Dictionary::clear(void)
{
m_freeStack = {};
m_keyList.clear();
m_keyHash.clear();
m_keyMap.clear();
m_useCount.clear();
}

Expand All @@ -48,11 +48,15 @@ uint16_t Dictionary::add(const TokenPtr &token, CaseSensitive cs,
EntryType newEntry;

// if requested, store upper case of key in hash to make search case
// insensitive (first actual string will be stored in key list)
QString hashKey {cs == CaseSensitive::No
? token->string().toUpper() : token->string()};
int index {m_keyHash.value(hashKey, -1)};
if (index == -1) // string not present?
// insensitive (actual string will be stored in key list)
std::string key {token->string().toStdString()};
if (cs == CaseSensitive::No)
{
std::transform(key.begin(), key.end(), key.begin(), toupper);
}
auto iterator = m_keyMap.find(key);
int index;
if (iterator == m_keyMap.end()) // string not present?
{
if (m_freeStack.empty()) // no free indexes available?
{
Expand All @@ -69,10 +73,11 @@ uint16_t Dictionary::add(const TokenPtr &token, CaseSensitive cs,
m_useCount[index] = 1;
newEntry = EntryType::Reused;
}
m_keyHash[hashKey] = index; // save key/index in map
m_keyMap[key] = index; // save key/index in map
}
else // string already present, update use count
{
index = iterator->second;
m_useCount[index]++;
newEntry = EntryType::Exists;
}
Expand All @@ -88,12 +93,12 @@ int Dictionary::remove(uint16_t index, CaseSensitive cs)
{
if (--m_useCount[index] == 0) // update use count, if zero then remove it
{
QString hashKey {QString::fromStdString(m_keyList[index])};
std::string key {m_keyList[index]};
if (cs == CaseSensitive::No)
{
hashKey = hashKey.toUpper();
std::transform(key.begin(), key.end(), key.begin(), toupper);
}
m_keyHash.remove(hashKey); // remove key/index from hash map
m_keyMap.erase(key);
m_keyList[index].clear();
m_freeStack.emplace(index);
return true;
Expand Down
7 changes: 5 additions & 2 deletions dictionary.h
Expand Up @@ -27,9 +27,10 @@

#include <memory>
#include <stack>
#include <unordered_map>
#include <vector>

#include <QHash>
#include <QString>

class Token;
using TokenPtr = std::shared_ptr<Token>;
Expand Down Expand Up @@ -59,9 +60,11 @@ class Dictionary
QString debugText(const QString header);

private:
using KeyMap = std::unordered_map<std::string, int>;

std::stack<uint16_t> m_freeStack; // stack of free items
std::vector<std::string> m_keyList; // list of keys
QHash<QString, int> m_keyHash; // hash map of keys to indexes
KeyMap m_keyMap; // hash map of keys to indexes
std::vector<uint16_t> m_useCount; // list of key use counts
};

Expand Down

0 comments on commit 66561d4

Please sign in to comment.