Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

Map.hpp

Go to the documentation of this file.
00001 
00027 //
00028 //  file Map.hpp 
00029 //  defines class Map<Key,Val> of arbitrary maps
00030 //    Key can be a pointer or integral value: anything that can be cast
00031 //    to integer and compared using ==
00032 //
00033 
00034 #ifndef __Map__
00035 #define __Map__
00036 
00037 
00038 #include "assert.hpp"
00039 
00040 
00041 extern int _mapLengths[];
00042 
00043 
00044 template <typename Key, typename Val>
00045 class Map 
00046 {
00047  public:
00048   Map ();
00049   ~Map ();
00050   bool find (Key key, Val& value);
00051   void insert (Key key, Val value);
00052 
00053  private:
00054   class Entry
00055   {
00056   public:
00057     Entry ()
00058       : _occupied (false)
00059     {
00060     } // Map::Entry::Entry
00061 
00062     void fill (Key key, Val value)
00063     {
00064       TRACER ("Map::Entry::fill");
00065 
00066       _occupied = true;
00067       _key = key;
00068       _value = value;
00069     } // Map::Entry::fill
00070 
00071     bool occupied () const
00072     {
00073       return _occupied;
00074     } // Map::Entry::occupied
00075 
00076     Key key () const { return _key; }
00077     Val value () const { return _value; }
00078 
00079   private:
00080     bool _occupied;
00081     Key _key;
00082     Val _value;
00083   }; // class Map::Entry
00084 
00085   // structure
00086   int* _lengthPointer;
00087   int _length;
00088   int _noOfEntries;
00089   Entry* _entries;
00090   Entry* _afterLast; // entry after the last one
00091   int _maxEntries;
00092 
00093   void expand ();
00094   Entry* findEntry (Key); // find entry for the key
00095 }; // class Map
00096 
00097 
00098 
00099 
00100 // ******************* Map definitions ************************
00101 
00102 template <class Key, class Val>
00103 Map<Key,Val>::Map ()
00104   : _lengthPointer (_mapLengths),
00105     _noOfEntries (0),
00106     _entries (0)
00107 {
00108   TRACER ("Map::Map");
00109 
00110   expand ();
00111 } // Map::Map
00112 
00113 
00114 // expand the map to the next available size
00115 // 29/09/2002 Manchester
00116 template <class Key, class Val>
00117 void Map<Key, Val>::expand ()
00118 {
00119   TRACER ("Map::expand");
00120 
00121   if (_lengthPointer[1] == 0) {
00122     // no way to expand the array itself
00123     throw MyException ("cannot expand a map");
00124   }
00125 
00126   _lengthPointer ++;
00127   _length = *_lengthPointer;
00128 
00129   Entry* oldEntries = _entries;
00130   _entries = new Entry [_length];
00131   if (! _entries) {
00132     throw MyException ("insufficient memory when allocating a map");
00133   }
00134 
00135   _afterLast = _entries + _length;
00136   _maxEntries = (int)(_length * 0.7);
00137   // experiments using random numbers: 38,000,000 allocations 
00138   // and 30,000,000 allocations (+ 100,000,000 chechs in both cases)
00139   // 0.5 : 32.21, 28.01
00140   // 0.6 : 33.61, 29.61
00141   // 0.7 : 35.51, 31.31
00142   // 0.8 : 37.71, 29,91* one less allocation
00143   // 0.9 : 41.11, 31,61* 
00144   // copy old entries
00145   Entry* current = oldEntries;
00146   int remaining = _noOfEntries;
00147   _noOfEntries = 0;
00148   while (remaining != 0) {
00149     // find first occupied entry
00150     while (! current->occupied()) {
00151       current ++;
00152     }
00153     // now current is occupied
00154     insert (current->key(), current->value());
00155     current ++;
00156     remaining --;
00157   }
00158 
00159   delete [] oldEntries;
00160 } // Map::expand
00161 
00162 
00163 template <class Key, class Val>
00164 inline
00165 Map<Key,Val>::~Map ()
00166 {
00167   TRACER ("Map::~Map");
00168 
00169   delete [] _entries;
00170 } // Map::~Map
00171 
00172 
00173 // find value by the key. The result is true if a pair with this key
00174 // is in the map. If such a pair is found then its value is
00175 // returned in found
00176 // 29/09/2002 Manchester
00177 template <class Key, class Val>
00178 bool Map<Key,Val>::find (Key key, Val& found)
00179 {
00180   TRACER( "Map::find" );
00181   Entry* entry = findEntry (key);
00182 
00183   if (entry->occupied()) {
00184     found = entry->value();
00185     return true;
00186   }
00187 
00188   return false;
00189 } // Map::find
00190 
00191 
00192 // add pair (key,value) to the map. 
00193 // WARNING: a value under this key must not be in the table!
00194 // 29/09/2002 Manchester
00195 template <class Key, class Val>
00196 void Map<Key,Val>::insert (Key key, Val value)
00197 {
00198   TRACER( "Map::insert" );
00199 
00200   if (_noOfEntries > _maxEntries) { // too many entries
00201     expand ();
00202   }
00203 
00204   Entry* entry = findEntry (key);
00205 
00206   ASS (! entry->occupied());
00207 
00208   entry->fill (key, value);
00209   _noOfEntries ++;
00210 } // Map::insert
00211 
00212 
00213 // compute hash value of a key and return the entry 
00214 // (occupied or not) for this key
00215 // 29/09/2002 Manchester
00216 template <class Key, class Val>
00217 Map<Key, Val>::Entry* Map<Key, Val>::findEntry (Key key)
00218 {
00219   TRACER( "Map::findEntry" );
00220 
00221   div_t d = div((int)key, _length);
00222   Entry* entry = _entries + d.rem;
00223   while ( entry->occupied() ) {
00224     if (entry->key() == key) {
00225       return entry;
00226     }
00227 
00228     entry ++;
00229     // check if the entry is a valid one
00230     if (entry ==_afterLast) {
00231       entry =_entries;
00232     }
00233   }
00234 
00235   // found non-occupied entry
00236   return entry;
00237 } // Map::findEntry
00238 
00239 
00240 
00241 
00242 // **************** Map::Entry definitions *********************
00243 
00244 /*
00245 template <class Key, class Val>
00246 inline
00247 Map<Key,Val>::Entry::Entry ()
00248   : _occupied (false)
00249 {
00250 } // Map::Entry::Entry
00251 
00252 
00253 template <class Key, class Val>
00254 inline
00255 bool Map<Key,Val>::Entry::occupied () const
00256 {
00257   return _occupied;
00258 } // Map::Entry::occupied
00259 
00260 
00261 template <class Key, class Val>
00262 inline
00263 Key Map<Key,Val>::Entry::key () const
00264 {
00265   return _key;
00266 } // Map::Entry::key
00267 
00268 
00269 template <class Key, class Val>
00270 inline
00271 Val Map<Key,Val>::Entry::value () const
00272 {
00273   return _value;
00274 } // Map::Entry::value
00275 
00276 
00277 template <class Key, class Val>
00278 void Map<Key,Val>::Entry::fill (Key key, Val value)
00279 {
00280   TRACER ("Map::Entry::fill");
00281 
00282   _occupied = true;
00283   _key = key;
00284   _value = value;
00285 } // Map::Entry::fill
00286 */
00287 
00288 #endif // __lst__
00289 

Generated on Sat Jun 28 15:08:57 2003 for Vampire by doxygen 1.3.2