00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _DICTIONARY_H_
00034 #define _DICTIONARY_H_
00035
00036 #if (defined(__XLC__) || defined(__xlC__)) && defined(__TEMPINC__)
00037
00038 #endif
00039
00040 #include "common/h/language.h"
00041 #include "common/h/Vector.h"
00042 #include "common/h/Pair.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 template<class K, class V> class dictionary_hash_iter;
00078
00079 template<class K, class V>
00080 class dictionary_hash {
00081 typedef const V &RET;
00082 friend class dictionary_hash_iter<K,V>;
00083
00084 public:
00085 typedef K key_type;
00086 typedef V value_type;
00087 typedef RET iter_value_return_type;
00088 typedef V& value_reference_type;
00089
00090 typedef dictionary_hash_iter<K,V> const_iterator;
00091 typedef dictionary_hash_iter<K,V> iterator;
00092
00093 dictionary_hash (unsigned (*hashfunc)(const K &),
00094 unsigned nbins=101,
00095 unsigned max_bin_load=70
00096
00097
00098
00099 );
00100 ~dictionary_hash () {}
00101
00102
00103
00104 dictionary_hash (const dictionary_hash<K,V> &);
00105 dictionary_hash<K,V>& operator= (const dictionary_hash<K,V> &);
00106
00107 unsigned getMemUsage_exceptObjItself_AndExtraFromKeyOrValue() const {
00108 return all_elems.capacity() * sizeof(entry) + bins.capacity() * sizeof(unsigned);
00109 }
00110
00111 unsigned size () const;
00112
00113 V& operator[] (const K &);
00114
00115
00116 const V& operator[] (const K &) const;
00117
00118 V& get(const K &);
00119 const V& get(const K &) const;
00120
00121
00122 const V& get_and_remove(const K &);
00123
00124
00125
00126 bool find_and_remove(const K &, V&);
00127
00128 void set(const K &, const V &);
00129
00130
00131 bool find (const K &, V &) const;
00132 bool find (const K &, const V **) const;
00133
00134 iterator find(const K &);
00135 const_iterator find(const K &) const;
00136
00137 bool defines (const K &) const;
00138 void undef (const K &);
00139
00140 #ifndef _KERNEL
00141
00142 pdvector<K> keys () const;
00143 pdvector<V> values () const;
00144 pdvector< pdpair<K, V> > keysAndValues() const;
00145 #endif
00146
00147 void clear ();
00148
00149 const_iterator begin() const {
00150
00151 return const_iterator(*this);
00152 }
00153 const_iterator end() const {
00154
00155 return const_iterator(*this).end();
00156 }
00157
00158
00159 private:
00160 bool enoughBins() const {
00161
00162
00163 return bins.size() * max_bin_load >= all_elems.size();
00164 }
00165 bool enoughBinsIf1MoreItemAdded() const {
00166 return bins.size() * max_bin_load >= all_elems.size() + 1;
00167 }
00168
00169 unsigned add(const K &, const V &);
00170
00171
00172
00173
00174 unsigned locate_addIfNotFound(const K &);
00175
00176
00177 unsigned locate(const K &, bool even_if_removed) const;
00178
00179
00180 void grow_numbins(unsigned new_numbins);
00181
00182
00183 unsigned (*hasher)(const K &);
00184
00185
00186
00187
00188 struct entry {
00189 K key;
00190 V val;
00191 unsigned key_hashval : 31;
00192
00193
00194 unsigned removed : 1;
00195
00196
00197
00198 unsigned next;
00199
00200
00201 entry() {}
00202 entry(const K &ikey, unsigned ikey_hashval, const V &ival, unsigned inext) :
00203 key(ikey), val(ival), key_hashval(ikey_hashval), next(inext) {
00204 removed = false;
00205 }
00206 entry(const entry &src) : key(src.key), val(src.val) {
00207 key_hashval = src.key_hashval;
00208 removed = src.removed;
00209 next = src.next;
00210 }
00211 entry& operator=(const entry &src) {
00212 if (&src == this) return *this;
00213
00214 key = src.key;
00215 val = src.val;
00216 key_hashval = src.key_hashval;
00217 removed = src.removed;
00218 next = src.next;
00219 return *this;
00220 }
00221 };
00222
00223
00224
00225
00226
00227
00228 pdvector<entry> all_elems;
00229
00230
00231
00232 pdvector<unsigned> bins;
00233
00234
00235
00236
00237 unsigned num_removed_elems;
00238
00239
00240
00241
00242
00243
00244
00245
00246 unsigned max_bin_load;
00247 static const unsigned bin_grow_factor;
00248 };
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 template<class K, class V>
00259 class dictionary_hash_iter {
00260 private:
00261 typedef const V &RET;
00262 dictionary_hash<K,V> &dict;
00263 TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry >::iterator i;
00264 TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry >::iterator the_end;
00265
00266
00267
00268 void move_to_next() {
00269 i++;
00270 make_valid_or_end();
00271 }
00272 void make_valid_or_end() {
00273 while (i != the_end && i->removed)
00274 i++;
00275 }
00276
00277 public:
00278
00279
00280
00281
00282
00283
00284 dictionary_hash_iter(dictionary_hash<K,V> &idict) : dict(idict) {
00285 reset();
00286 }
00287
00288 dictionary_hash_iter(const dictionary_hash<K,V> &idict) :
00289 dict(const_cast< dictionary_hash<K,V>& >(idict)) {
00290 reset();
00291 }
00292
00293 #if defined (cap_use_pdvector)
00294 dictionary_hash_iter(dictionary_hash<K,V> &idict,
00295 TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry>::iterator curi)
00296 : dict(idict), i(curi), the_end(dict.all_elems.end()) {
00297 }
00298
00299 dictionary_hash_iter(const dictionary_hash<K,V> &idict,
00300 TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry>::const_iterator curi)
00301 : dict(const_cast< dictionary_hash<K,V>& >(idict)),
00302 i(const_cast< TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry >::iterator>(curi)),
00303 the_end(const_cast< TYPENAME pdvector< TYPENAME dictionary_hash<K,V>::entry >::iterator>(
00304 dict.all_elems.end()))
00305 { }
00306 #else
00307 dictionary_hash_iter(dictionary_hash<K,V> &idict,
00308 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry>::iterator curi)
00309 : dict(idict), i(curi), the_end(dict.all_elems.end()) {
00310 }
00311
00312 dictionary_hash_iter(const dictionary_hash<K,V> &idict,
00313 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry>::const_iterator curi)
00314 : dict( const_cast< dictionary_hash<K,V>& >(idict))
00315 {
00316 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry>::const_iterator *temp = &curi;
00317 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry>::iterator *iptr = NULL;
00318
00319
00320 iptr = ( TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry >::iterator *)
00321 (temp);
00322 i = *iptr;
00323
00324
00325
00326
00327
00328
00329 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry >::const_iterator ci = dict.all_elems.end();
00330 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry >::const_iterator *cip = &ci;
00331 TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry >::iterator *nip;
00332 nip = (TYPENAME std::vector< TYPENAME dictionary_hash<K,V>::entry >::iterator *) cip;
00333 the_end = *nip;
00334
00335
00336
00337
00338 }
00339
00340 #endif
00341
00342 dictionary_hash_iter(const dictionary_hash_iter<K,V> &src) :
00343 dict(src.dict), i(src.i), the_end(src.the_end) { }
00344
00345
00346
00347
00348
00349
00350
00351 dictionary_hash_iter operator++(int) {
00352 dictionary_hash_iter result = *this;
00353 move_to_next();
00354 return result;
00355 }
00356 dictionary_hash_iter operator++() {
00357 move_to_next();
00358 return *this;
00359 }
00360
00361 bool next(K &k, V &v) {
00362 for (; i != the_end; i++) {
00363 if (!i->removed) {
00364 k = i->key;
00365 v = i->val;
00366 i++;
00367 return true;
00368 }
00369 }
00370 return false;
00371 }
00372
00373 void reset() {
00374
00375 if (dict.all_elems.size() == 0) {
00376 #if defined (use_pdvector)
00377 i = NULL;
00378 the_end = NULL;
00379 #else
00380 i = dict.all_elems.begin();
00381 the_end = dict.all_elems.end();
00382 #endif
00383
00384 }
00385 else {
00386 i = dict.all_elems.begin();
00387 the_end = dict.all_elems.end();
00388
00389 while (i != the_end && i->removed)
00390 i++;
00391 }
00392 }
00393
00394 dictionary_hash_iter end() {
00395 i = the_end;
00396 return *this;
00397 }
00398
00399 RET operator*() {
00400 return i->val;
00401 }
00402
00403
00404
00405
00406 K currkey() {
00407 return i->key;
00408 }
00409 const K &currkey() const {
00410 return i->key;
00411 }
00412 RET currval() const {
00413 return i->val;
00414 }
00415 V &currval() {
00416 return i->val;
00417 }
00418
00419 bool operator==(const dictionary_hash_iter &other) const {
00420 return i == other.i;
00421 }
00422 bool operator!=(const dictionary_hash_iter &other) const {
00423 return i != other.i;
00424 }
00425
00426 operator bool() const {return i < the_end;}
00427 };
00428
00429 #if defined(__XLC__) || defined(__xlC__) || defined (AUTO_TEMPLATES)
00430 #define DICT_C_IS_HEADER
00431 #include "../src/Dictionary.C"
00432 #endif
00433
00434 #endif