Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

AlphabetMap.cpp

Go to the documentation of this file.
00001 // AlphabetMap.cpp
00002 //
00004 //
00005 // Copyright (c) 2002 Iain Murray
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         // Loop through Entries with the correct Hash value.
00032         for (Entry* i = HashEntry; i; i=i->Next) {
00033                 if (i->Key==Key) {
00034                         if (PrefixFlag) {
00035                                 // Just tagging - don't change symbol. Recurse if necessary
00036                                 i->KeyIsPrefix = true;
00037                                 if (Key.size()>1)
00038                                         RecursiveAdd(Key.substr(Key.size()-1), Undefined, true);
00039                         } else {
00040                                 // Add symbol and leave
00041                                 i->Symbol = Value;
00042                         }
00043                         return;
00044                 }
00045         }
00046         
00047         // When hash table gets 1/2 full...
00048         // (no I haven't optimised when to resize)
00049         if (Entries.size()<<1 >= HashTable.size()) {
00050                 // Double up all the storage
00051                 HashTable.clear();
00052                 HashTable.resize(Entries.size()<<2);
00053                 Entries.reserve(Entries.size()<<1);
00054                 
00055                 // Rehash as the pointers will all be mangled.
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                 // Have to recall this function as the key's hash needs recalculating
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         // Loop through Entries with the correct Hash value.
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 }

Generated on Sat Nov 5 16:15:59 2005 for OPIE by  doxygen 1.4.2