00001
00002
00004
00005
00006
00008
00009 #include "AlphabetMap.h"
00010
00011 using namespace Dasher;
00012 using namespace std;
00013
00014 alphabet_map::alphabet_map(unsigned int InitialTableSize)
00015 : HashTable(InitialTableSize<<1), Undefined(0)
00016 {
00017 Entries.reserve(InitialTableSize);
00018 }
00019
00020
00021 void alphabet_map::Add(const string& Key, symbol Value)
00022 {
00023 RecursiveAdd(Key, Value, false);
00024 }
00025
00026
00027 void alphabet_map::RecursiveAdd(const string& Key, symbol Value, bool PrefixFlag)
00028 {
00029 Entry*& HashEntry = HashTable[Hash(Key)];
00030
00031
00032 for (Entry* i = HashEntry; i; i=i->Next) {
00033 if (i->Key==Key) {
00034 if (PrefixFlag) {
00035
00036 i->KeyIsPrefix = true;
00037 if (Key.size()>1)
00038 RecursiveAdd(Key.substr(Key.size()-1), Undefined, true);
00039 } else {
00040
00041 i->Symbol = Value;
00042 }
00043 return;
00044 }
00045 }
00046
00047
00048
00049 if (Entries.size()<<1 >= HashTable.size()) {
00050
00051 HashTable.clear();
00052 HashTable.resize(Entries.size()<<2);
00053 Entries.reserve(Entries.size()<<1);
00054
00055
00056 for (uint j=0; j<Entries.size(); j++) {
00057 Entry*& HashEntry2 = HashTable[Hash(Entries[j].Key)];
00058 Entries[j].Next = HashEntry2;
00059 HashEntry2 = &Entries[j];
00060 }
00061
00062
00063 RecursiveAdd(Key, Value, PrefixFlag);
00064 return;
00065 }
00066
00067 Entries.push_back(Entry(Key, Value, HashEntry));
00068 HashEntry = &Entries.back();
00069 }
00070
00071
00072 symbol alphabet_map::Get(const string& Key, bool* KeyIsPrefix) const
00073 {
00074
00075 for (Entry* i = HashTable[Hash(Key)]; i; i=i->Next) {
00076 if (i->Key==Key) {
00077 if (KeyIsPrefix!=0)
00078 *KeyIsPrefix = i->KeyIsPrefix;
00079 return i->Symbol;
00080 }
00081 }
00082
00083 if (KeyIsPrefix!=0)
00084 *KeyIsPrefix = false;
00085 return Undefined;
00086 }