Diffstat (limited to 'inputmethods/dasher/AlphabetMap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | inputmethods/dasher/AlphabetMap.cpp | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/inputmethods/dasher/AlphabetMap.cpp b/inputmethods/dasher/AlphabetMap.cpp new file mode 100644 index 0000000..09e2c72 --- a/dev/null +++ b/inputmethods/dasher/AlphabetMap.cpp @@ -0,0 +1,86 @@ +// AlphabetMap.cpp +// +///////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2002 Iain Murray +// +///////////////////////////////////////////////////////////////////////////// + +#include "AlphabetMap.h" + +using namespace Dasher; +using namespace std; + +alphabet_map::alphabet_map(unsigned int InitialTableSize) + : Undefined(0), HashTable(InitialTableSize<<1) +{ + Entries.reserve(InitialTableSize); +} + + +void alphabet_map::Add(const string& Key, symbol Value) +{ + RecursiveAdd(Key, Value, false); +} + + +void alphabet_map::RecursiveAdd(const string& Key, symbol Value, bool PrefixFlag) +{ + Entry*& HashEntry = HashTable[Hash(Key)]; + + // Loop through Entries with the correct Hash value. + for (Entry* i = HashEntry; i; i=i->Next) { + if (i->Key==Key) { + if (PrefixFlag) { + // Just tagging - don't change symbol. Recurse if necessary + i->KeyIsPrefix = true; + if (Key.size()>1) + RecursiveAdd(Key.substr(Key.size()-1), Undefined, true); + } else { + // Add symbol and leave + i->Symbol = Value; + } + return; + } + } + + // When hash table gets 1/2 full... + // (no I haven't optimised when to resize) + if (Entries.size()<<1 >= HashTable.size()) { + // Double up all the storage + HashTable.clear(); + HashTable.resize(Entries.size()<<2); + Entries.reserve(Entries.size()<<1); + + // Rehash as the pointers will all be mangled. + for (uint j=0; j<Entries.size(); j++) { + Entry*& HashEntry2 = HashTable[Hash(Entries[j].Key)]; + Entries[j].Next = HashEntry2; + HashEntry2 = &Entries[j]; + } + + // Have to recall this function as the key's hash needs recalculating + RecursiveAdd(Key, Value, PrefixFlag); + return; + } + + Entries.push_back(Entry(Key, Value, HashEntry)); + HashEntry = &Entries.back(); +} + + +symbol alphabet_map::Get(const string& Key, bool* KeyIsPrefix) const +{ + // Loop through Entries with the correct Hash value. + for (Entry* i = HashTable[Hash(Key)]; i; i=i->Next) { + if (i->Key==Key) { + if (KeyIsPrefix!=0) + *KeyIsPrefix = i->KeyIsPrefix; + return i->Symbol; + } + } + + if (KeyIsPrefix!=0) + *KeyIsPrefix = false; + return Undefined; +} |