00001
00027
00028
00029
00030
00031
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 }
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 }
00070
00071 bool occupied () const
00072 {
00073 return _occupied;
00074 }
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 };
00084
00085
00086 int* _lengthPointer;
00087 int _length;
00088 int _noOfEntries;
00089 Entry* _entries;
00090 Entry* _afterLast;
00091 int _maxEntries;
00092
00093 void expand ();
00094 Entry* findEntry (Key);
00095 };
00096
00097
00098
00099
00100
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 }
00112
00113
00114
00115
00116 template <class Key, class Val>
00117 void Map<Key, Val>::expand ()
00118 {
00119 TRACER ("Map::expand");
00120
00121 if (_lengthPointer[1] == 0) {
00122
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
00138
00139
00140
00141
00142
00143
00144
00145 Entry* current = oldEntries;
00146 int remaining = _noOfEntries;
00147 _noOfEntries = 0;
00148 while (remaining != 0) {
00149
00150 while (! current->occupied()) {
00151 current ++;
00152 }
00153
00154 insert (current->key(), current->value());
00155 current ++;
00156 remaining --;
00157 }
00158
00159 delete [] oldEntries;
00160 }
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 }
00171
00172
00173
00174
00175
00176
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 }
00190
00191
00192
00193
00194
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) {
00201 expand ();
00202 }
00203
00204 Entry* entry = findEntry (key);
00205
00206 ASS (! entry->occupied());
00207
00208 entry->fill (key, value);
00209 _noOfEntries ++;
00210 }
00211
00212
00213
00214
00215
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
00230 if (entry ==_afterLast) {
00231 entry =_entries;
00232 }
00233 }
00234
00235
00236 return entry;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 #endif // __lst__
00289