summaryrefslogtreecommitdiff
path: root/inputmethods/dasher/AlphabetMap.cpp
Unidiff
Diffstat (limited to 'inputmethods/dasher/AlphabetMap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--inputmethods/dasher/AlphabetMap.cpp86
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 @@
1// AlphabetMap.cpp
2//
3/////////////////////////////////////////////////////////////////////////////
4//
5// Copyright (c) 2002 Iain Murray
6//
7/////////////////////////////////////////////////////////////////////////////
8
9#include "AlphabetMap.h"
10
11using namespace Dasher;
12using namespace std;
13
14alphabet_map::alphabet_map(unsigned int InitialTableSize)
15 : Undefined(0), HashTable(InitialTableSize<<1)
16{
17 Entries.reserve(InitialTableSize);
18}
19
20
21void alphabet_map::Add(const string& Key, symbol Value)
22{
23 RecursiveAdd(Key, Value, false);
24}
25
26
27void alphabet_map::RecursiveAdd(const string& Key, symbol Value, bool PrefixFlag)
28{
29 Entry*& HashEntry = HashTable[Hash(Key)];
30
31 // Loop through Entries with the correct Hash value.
32 for (Entry* i = HashEntry; i; i=i->Next) {
33 if (i->Key==Key) {
34 if (PrefixFlag) {
35 // Just tagging - don't change symbol. Recurse if necessary
36 i->KeyIsPrefix = true;
37 if (Key.size()>1)
38 RecursiveAdd(Key.substr(Key.size()-1), Undefined, true);
39 } else {
40 // Add symbol and leave
41 i->Symbol = Value;
42 }
43 return;
44 }
45 }
46
47 // When hash table gets 1/2 full...
48 // (no I haven't optimised when to resize)
49 if (Entries.size()<<1 >= HashTable.size()) {
50 // Double up all the storage
51 HashTable.clear();
52 HashTable.resize(Entries.size()<<2);
53 Entries.reserve(Entries.size()<<1);
54
55 // Rehash as the pointers will all be mangled.
56 for (uint j=0; j<Entries.size(); j++) {
57 Entry*& HashEntry2 = HashTable[Hash(Entries[j].Key)];
58 Entries[j].Next = HashEntry2;
59 HashEntry2 = &Entries[j];
60 }
61
62 // Have to recall this function as the key's hash needs recalculating
63 RecursiveAdd(Key, Value, PrefixFlag);
64 return;
65 }
66
67 Entries.push_back(Entry(Key, Value, HashEntry));
68 HashEntry = &Entries.back();
69}
70
71
72symbol alphabet_map::Get(const string& Key, bool* KeyIsPrefix) const
73{
74 // Loop through Entries with the correct Hash value.
75 for (Entry* i = HashTable[Hash(Key)]; i; i=i->Next) {
76 if (i->Key==Key) {
77 if (KeyIsPrefix!=0)
78 *KeyIsPrefix = i->KeyIsPrefix;
79 return i->Symbol;
80 }
81 }
82
83 if (KeyIsPrefix!=0)
84 *KeyIsPrefix = false;
85 return Undefined;
86}