00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _map_H_
00025 #define _map_H_
00026
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include "ink_assert.h"
00030 #include "List.h"
00031 #include "Vec.h"
00032
00033 #define MAP_INTEGRAL_SIZE (1 << (2))
00034
00035
00036
00037 typedef const char cchar;
00038
00039 template<class A>
00040 static inline char *
00041 _dupstr(cchar *s, cchar *e = 0) {
00042 int l = e ? e-s : strlen(s);
00043 char *ss = (char*)A::alloc(l+1);
00044 memcpy(ss, s, l);
00045 ss[l] = 0;
00046 return ss;
00047 }
00048
00049
00050
00051 template <class K, class C> class MapElem {
00052 public:
00053 K key;
00054 C value;
00055 bool operator==(MapElem &e) { return e.key == key; }
00056 operator uintptr_t(void) { return (uintptr_t)(uintptr_t)key; }
00057 MapElem(uintptr_t x) { ink_assert(!x); key = 0; }
00058 MapElem(K akey, C avalue) : key(akey), value(avalue) {}
00059 MapElem(MapElem &e) : key(e.key), value(e.value) {}
00060 MapElem() : key(0) {}
00061 };
00062
00063 template <class K, class C, class A = DefaultAlloc> class Map : public Vec<MapElem<K,C>, A> {
00064 public:
00065 typedef MapElem<K,C> ME;
00066 typedef Vec<ME,A> PType;
00067 using PType::n;
00068 using PType::i;
00069 using PType::v;
00070 ME *put(K akey, C avalue);
00071 ME *put(K akey);
00072 C get(K akey);
00073 C *getp(K akey);
00074 void get_keys(Vec<K> &keys);
00075 void get_keys_set(Vec<K> &keys);
00076 void get_values(Vec<C> &values);
00077 void map_union(Map<K,C> &m);
00078 bool some_disjunction(Map<K,C> &m) const;
00079 };
00080
00081 template <class C> class HashFns {
00082 public:
00083 static uintptr_t hash(C a);
00084 static int equal(C a, C b);
00085 };
00086
00087 template <class K, class C> class HashSetFns {
00088 public:
00089 static uintptr_t hash(C a);
00090 static uintptr_t hash(K a);
00091 static int equal(C a, C b);
00092 static int equal(K a, C b);
00093 };
00094
00095 template <class K, class AHashFns, class C, class A = DefaultAlloc> class HashMap : public Map<K,C,A> {
00096 public:
00097 typedef MapElem<K,C> value_type;
00098 using Map<K,C,A>::n;
00099 using Map<K,C,A>::i;
00100 using Map<K,C,A>::v;
00101 using Map<K,C,A>::e;
00102 MapElem<K,C> *get_internal(K akey);
00103 C get(K akey);
00104 value_type* put(K akey, C avalue);
00105 void get_keys(Vec<K> &keys);
00106 void get_values(Vec<C> &values);
00107 };
00108
00109 #define form_Map(_c, _p, _v) if ((_v).n) for (_c *qq__##_p = (_c*)0, *_p = &(_v).v[0]; \
00110 ((uintptr_t)(qq__##_p) < (_v).n) && ((_p = &(_v).v[(uintptr_t)qq__##_p]) || 1); \
00111 qq__##_p = (_c*)(((uintptr_t)qq__##_p) + 1)) \
00112 if ((_p)->key)
00113
00114
00115 template <class K, class AHashFns, class C, class A = DefaultAlloc> class HashSet : public Vec<C,A> {
00116 public:
00117 typedef Vec<C,A> V;
00118 using V::n;
00119 using V::i;
00120 using V::v;
00121 using V::e;
00122 C get(K akey);
00123 C *put( C avalue);
00124 };
00125
00126 class StringHashFns {
00127 public:
00128 static uintptr_t hash(cchar *s) {
00129 uintptr_t h = 0;
00130
00131 while (*s) h = h * 27 + (unsigned char)*s++;
00132 return h;
00133 }
00134 static int equal(cchar *a, cchar *b) { return !strcmp(a, b); }
00135 };
00136
00137 class CaseStringHashFns {
00138 public:
00139 static uintptr_t hash(cchar *s) {
00140 uintptr_t h = 0;
00141
00142 while (*s) h = h * 27 + (unsigned char)toupper(*s++);
00143 return h;
00144 }
00145 static int equal(cchar *a, cchar *b) { return !strcasecmp(a, b); }
00146 };
00147
00148 class PointerHashFns {
00149 public:
00150 static uintptr_t hash(void *s) { return (uintptr_t)(uintptr_t)s; }
00151 static int equal(void *a, void *b) { return a == b; }
00152 };
00153
00154 template <class C, class AHashFns, class A = DefaultAlloc> class ChainHash : public Map<uintptr_t, List<C,A>,A> {
00155 public:
00156 using Map<uintptr_t, List<C,A>,A>::n;
00157 using Map<uintptr_t, List<C,A>,A>::v;
00158 typedef ConsCell<C, A> ChainCons;
00159 C put(C c);
00160 C get(C c);
00161 C put_bag(C c);
00162 int get_bag(C c,Vec<C> &v);
00163 int del(C avalue);
00164 void get_elements(Vec<C> &elements);
00165 };
00166
00167 template <class K, class AHashFns, class C, class A = DefaultAlloc> class ChainHashMap :
00168 public Map<uintptr_t, List<MapElem<K,C>,A>,A> {
00169 public:
00170 using Map<uintptr_t, List<MapElem<K,C>,A>,A>::n;
00171 using Map<uintptr_t, List<MapElem<K,C>,A>,A>::v;
00172 MapElem<K,C> *put(K akey, C avalue);
00173 C get(K akey);
00174 int del(K akey);
00175 MapElem<K,C> *put_bag(K akey, C c);
00176 int get_bag(K akey, Vec<C> &v);
00177 void get_keys(Vec<K> &keys);
00178 void get_values(Vec<C> &values);
00179 };
00180
00181 template<class F = StringHashFns, class A = DefaultAlloc>
00182 class StringChainHash : public ChainHash<cchar *, F, A> {
00183 public:
00184 cchar *canonicalize(cchar *s, cchar *e);
00185 cchar *canonicalize(cchar *s) { return canonicalize(s, s + strlen(s)); }
00186 };
00187
00188 template <class C, class AHashFns, int N, class A = DefaultAlloc> class NBlockHash {
00189 public:
00190 int n;
00191 int i;
00192 C *v;
00193 C e[N];
00194
00195 C* end() { return last(); }
00196 int length() { return N * n; }
00197 C *first();
00198 C *last();
00199 C put(C c);
00200 C get(C c);
00201 C* assoc_put(C *c);
00202 C* assoc_get(C *c);
00203 int del(C c);
00204 void clear();
00205 void reset();
00206 int count();
00207 void size(int p2);
00208 void copy(const NBlockHash<C,AHashFns,N,A> &hh);
00209 void move(NBlockHash<C,AHashFns,N,A> &hh);
00210 NBlockHash();
00211 NBlockHash(NBlockHash<C,AHashFns,N,A> &hh) { v = e; copy(hh); }
00212 };
00213
00214
00215
00216 #define DEFAULT_BLOCK_HASH_SIZE 4
00217 template <class C, class ABlockHashFns> class BlockHash :
00218 public NBlockHash<C, ABlockHashFns, DEFAULT_BLOCK_HASH_SIZE> {};
00219 typedef BlockHash<cchar *, StringHashFns> StringBlockHash;
00220
00221 template <class K, class C, class A = DefaultAlloc> class Env {
00222 public:
00223 typedef ConsCell<C, A> EnvCons;
00224 void put(K akey, C avalue);
00225 C get(K akey);
00226 void push();
00227 void pop();
00228 void clear() { store.clear(); scope.clear(); }
00229
00230 Env() {}
00231 Map<K,List<C> *, A> store;
00232 List<List<K>, A> scope;
00233 List<C, A> *get_bucket(K akey);
00234 };
00235
00236
00237
00238 template <class K, class C, class A> inline C
00239 Map<K,C,A>::get(K akey) {
00240 MapElem<K,C> e(akey, (C)0);
00241 MapElem<K,C> *x = this->set_in(e);
00242 if (x)
00243 return x->value;
00244 return (C)0;
00245 }
00246
00247 template <class K, class C, class A> inline C *
00248 Map<K,C,A>::getp(K akey) {
00249 MapElem<K,C> e(akey, (C)0);
00250 MapElem<K,C> *x = this->set_in(e);
00251 if (x)
00252 return &x->value;
00253 return 0;
00254 }
00255
00256 template <class K, class C, class A> inline MapElem<K,C> *
00257 Map<K,C,A>::put(K akey, C avalue) {
00258 MapElem<K,C> e(akey, avalue);
00259 MapElem<K,C> *x = this->set_in(e);
00260 if (x) {
00261 x->value = avalue;
00262 return x;
00263 } else
00264 return this->set_add(e);
00265 }
00266
00267 template <class K, class C, class A> inline MapElem<K,C> *
00268 Map<K,C,A>::put(K akey) {
00269 MapElem<K,C> e(akey, 0);
00270 MapElem<K,C> *x = this->set_in(e);
00271 if (x)
00272 return x;
00273 else
00274 return this->set_add(e);
00275 }
00276
00277 template <class K, class C, class A> inline void
00278 Map<K,C,A>::get_keys(Vec<K> &keys) {
00279 for (int i = 0; i < n; i++)
00280 if (v[i].key)
00281 keys.add(v[i].key);
00282 }
00283
00284 template <class K, class C, class A> inline void
00285 Map<K,C,A>::get_keys_set(Vec<K> &keys) {
00286 for (int i = 0; i < n; i++)
00287 if (v[i].key)
00288 keys.set_add(v[i].key);
00289 }
00290
00291 template <class K, class C, class A> inline void
00292 Map<K,C,A>::get_values(Vec<C> &values) {
00293 for (int i = 0; i < n; i++)
00294 if (v[i].key)
00295 values.set_add(v[i].value);
00296 values.set_to_vec();
00297 }
00298
00299 template <class K, class C, class A> inline void
00300 Map<K,C,A>::map_union(Map<K,C> &m) {
00301 for (int i = 0; i < m.n; i++)
00302 if (m.v[i].key)
00303 put(m.v[i].key, m.v[i].value);
00304 }
00305
00306 template <class K, class C, class A> inline bool
00307 Map<K,C,A>::some_disjunction(Map<K,C> &m) const {
00308 for (size_t i = 0; i < m.n; i++) {
00309 if (m.v[i].key && get(m.v[i].key) != m.v[i].value) {
00310 return true;
00311 }
00312 }
00313 for (size_t i = 0; i < n; i++) {
00314 if (v[i].key && m.get(v[i].key) != v[i].value) {
00315 return true;
00316 }
00317 }
00318 return false;
00319 }
00320
00321 template <class K, class C, class A> inline void
00322 map_set_add(Map<K,Vec<C,A>*,A> &m, K akey, C avalue) {
00323 Vec<C,A> *v = m.get(akey);
00324 if (!v)
00325 m.put(akey, (v = new Vec<C,A>));
00326 v->set_add(avalue);
00327 }
00328
00329 template <class K, class C, class A> inline void
00330 map_set_add(Map<K,Vec<C,A>*,A> &m, K akey, Vec<C> *madd) {
00331 Vec<C,A> *v = m.get(akey);
00332 if (!v)
00333 m.put(akey, (v = new Vec<C,A>));
00334 v->set_union(*madd);
00335 }
00336
00337 template <class K, class AHashFns, class C, class A> inline C
00338 HashSet<K, AHashFns, C, A>::get(K akey) {
00339 if (!n)
00340 return 0;
00341 if (n <= MAP_INTEGRAL_SIZE) {
00342 for (C *c = v; c < v + n; c++)
00343 if (c)
00344 if (AHashFns::equal(akey, *c))
00345 return *c;
00346 return 0;
00347 }
00348 uintptr_t h = AHashFns::hash(akey);
00349 h = h % n;
00350 for (int k = h, j = 0; j < i + 3;j++) {
00351 if (!v[k])
00352 return 0;
00353 else if (AHashFns::equal(akey, v[k]))
00354 return v[k];
00355 k = (k + open_hash_primes[j]) % n;
00356 }
00357 return 0;
00358 }
00359
00360 template <class K, class AHashFns, class C, class A> inline C *
00361 HashSet<K, AHashFns, C, A>::put(C avalue) {
00362 if (n < MAP_INTEGRAL_SIZE) {
00363 if (!v)
00364 v = e;
00365 for (int i = 0; i < n; i++)
00366 if (AHashFns::equal(avalue, v[i]))
00367 return &v[i];
00368 v[n] = avalue;
00369 n++;
00370 return &v[n-1];
00371 }
00372 if (n > MAP_INTEGRAL_SIZE) {
00373 uintptr_t h = AHashFns::hash(avalue);
00374 h = h % n;
00375 for (int k = h, j = 0; j < i + 3; j++) {
00376 if (!v[k]) {
00377 v[k] = avalue;
00378 return &v[k];
00379 }
00380 k = (k + open_hash_primes[j]) % n;
00381 }
00382 } else
00383 i = SET_INITIAL_INDEX-1;
00384 HashSet<K,AHashFns,C,A> vv(*this);
00385 Vec<C,A>::set_expand();
00386 for (int i = 0; i < vv.n; i++)
00387 if (vv.v[i])
00388 put(vv.v[i]);
00389 return put(avalue);
00390 }
00391
00392 template <class K, class AHashFns, class C, class A> inline MapElem<K,C> *
00393 HashMap<K,AHashFns,C,A>::get_internal(K akey) {
00394 if (!n)
00395 return 0;
00396 if (n <= MAP_INTEGRAL_SIZE) {
00397 for (MapElem<K,C> *c = v; c < v + n; c++)
00398 if (c->key)
00399 if (AHashFns::equal(akey, c->key))
00400 return c;
00401 return 0;
00402 }
00403 uintptr_t h = AHashFns::hash(akey);
00404 h = h % n;
00405 for (size_t k = h, j = 0; j < i + 3;j++) {
00406 if (!v[k].key)
00407 return 0;
00408 else if (AHashFns::equal(akey, v[k].key))
00409 return &v[k];
00410 k = (k + open_hash_primes[j]) % n;
00411 }
00412 return 0;
00413 }
00414
00415 template <class K, class AHashFns, class C, class A> inline C
00416 HashMap<K,AHashFns,C,A>::get(K akey) {
00417 MapElem<K,C> *x = get_internal(akey);
00418 if (!x)
00419 return 0;
00420 return x->value;
00421 }
00422
00423 template <class K, class AHashFns, class C, class A> inline MapElem<K,C> *
00424 HashMap<K,AHashFns,C,A>::put(K akey, C avalue) {
00425 MapElem<K,C> *x = get_internal(akey);
00426 if (x) {
00427 x->value = avalue;
00428 return x;
00429 } else {
00430 if (n < MAP_INTEGRAL_SIZE) {
00431 if (!v)
00432 v = e;
00433 v[n].key = akey;
00434 v[n].value = avalue;
00435 n++;
00436 return &v[n-1];
00437 }
00438 if (n > MAP_INTEGRAL_SIZE) {
00439 uintptr_t h = AHashFns::hash(akey);
00440 h = h % n;
00441 for (size_t k = h, j = 0; j < i + 3; j++) {
00442 if (!v[k].key) {
00443 v[k].key = akey;
00444 v[k].value = avalue;
00445 return &v[k];
00446 }
00447 k = (k + open_hash_primes[j]) % n;
00448 }
00449 } else
00450 i = SET_INITIAL_INDEX-1;
00451 }
00452 HashMap<K,AHashFns,C,A> vv(*this);
00453 Map<K,C,A>::set_expand();
00454 for (size_t i = 0; i < vv.n; i++)
00455 if (vv.v[i].key)
00456 put(vv.v[i].key, vv.v[i].value);
00457 return put(akey, avalue);
00458 }
00459
00460 template <class K, class AHashFns, class C, class A> inline void
00461 HashMap<K,AHashFns,C,A>::get_keys(Vec<K> &keys) { Map<K,C,A>::get_keys(keys); }
00462
00463 template <class K, class AHashFns, class C, class A> inline void
00464 HashMap<K,AHashFns,C,A>::get_values(Vec<C> &values) { Map<K,C,A>::get_values(values); }
00465
00466 template <class C, class AHashFns, class A> C
00467 ChainHash<C, AHashFns, A>::put(C c) {
00468 uintptr_t h = AHashFns::hash(c);
00469 List<C,A> *l;
00470 MapElem<uintptr_t,List<C,A> > e(h, (C)0);
00471 MapElem<uintptr_t,List<C,A> > *x = this->set_in(e);
00472 if (x)
00473 l = &x->value;
00474 else {
00475 l = &Map<uintptr_t, List<C,A>, A>::put(h, c)->value;
00476 return l->head->car;
00477 }
00478 forc_List(ChainCons, x, *l)
00479 if (AHashFns::equal(c, x->car))
00480 return x->car;
00481 l->push(c);
00482 return (C)0;
00483 }
00484
00485 template <class C, class AHashFns, class A> C
00486 ChainHash<C, AHashFns, A>::get(C c) {
00487 uintptr_t h = AHashFns::hash(c);
00488 List<C> empty;
00489 MapElem<uintptr_t,List<C,A> > e(h, empty);
00490 MapElem<uintptr_t,List<C,A> > *x = this->set_in(e);
00491 if (!x)
00492 return 0;
00493 List<C> *l = &x->value;
00494 forc_List(ChainCons, x, *l)
00495 if (AHashFns::equal(c, x->car))
00496 return x->car;
00497 return 0;
00498 }
00499
00500 template <class C, class AHashFns, class A> C
00501 ChainHash<C, AHashFns, A>::put_bag(C c) {
00502 uintptr_t h = AHashFns::hash(c);
00503 List<C, A> *l;
00504 MapElem<uintptr_t,List<C,A> > e(h, (C)0);
00505 MapElem<uintptr_t,List<C,A> > *x = this->set_in(e);
00506 if (x)
00507 l = &x->value;
00508 else {
00509 l = &Map<uintptr_t, List<C,A> >::put(h, c)->value;
00510 return l->head->car;
00511 }
00512 l->push(c);
00513 return (C)0;
00514 }
00515
00516 template <class C, class AHashFns, class A> int
00517 ChainHash<C, AHashFns, A>::get_bag(C c, Vec<C> &v) {
00518 uintptr_t h = AHashFns::hash(c);
00519 List<C,A> empty;
00520 MapElem<uintptr_t,List<C,A> > e(h, empty);
00521 MapElem<uintptr_t,List<C,A> > *x = this->set_in(e);
00522 if (!x)
00523 return 0;
00524 List<C,A> *l = &x->value;
00525 forc_List(C, x, *l)
00526 if (AHashFns::equal(c, x->car))
00527 v.add(x->car);
00528 return v.n;
00529 }
00530
00531 template <class C, class AHashFns, class A> void
00532 ChainHash<C, AHashFns, A>::get_elements(Vec<C> &elements) {
00533 for (int i = 0; i < n; i++) {
00534 List<C, A> *l = &v[i].value;
00535 forc_List(C, x, *l)
00536 elements.add(x);
00537 }
00538 }
00539
00540 template <class C, class AHashFns, class A> int
00541 ChainHash<C, AHashFns, A>::del(C c) {
00542 uintptr_t h = AHashFns::hash(c);
00543 List<C> *l;
00544 MapElem<uintptr_t,List<C,A> > e(h, (C)0);
00545 MapElem<uintptr_t,List<C,A> > *x = this->set_in(e);
00546 if (x)
00547 l = &x->value;
00548 else
00549 return 0;
00550 ConsCell<C> *last = 0;
00551 forc_List(ConsCell<C>, x, *l) {
00552 if (AHashFns::equal(c, x->car)) {
00553 if (!last)
00554 l->head = x->cdr;
00555 else
00556 last->cdr = x->cdr;
00557 A::free(x);
00558 return 1;
00559 }
00560 last = x;
00561 }
00562 return 0;
00563 }
00564
00565 template <class K, class AHashFns, class C, class A> MapElem<K,C> *
00566 ChainHashMap<K, AHashFns, C, A>::put(K akey, C avalue) {
00567 uintptr_t h = AHashFns::hash(akey);
00568 List<MapElem<K,C>,A> empty;
00569 List<MapElem<K,C>,A> *l;
00570 MapElem<K, C> c(akey, avalue);
00571 MapElem<uintptr_t,List<MapElem<K,C>,A> > e(h, empty);
00572 MapElem<uintptr_t,List<MapElem<K,C>,A> > *x = this->set_in(e);
00573 if (x)
00574 l = &x->value;
00575 else {
00576 l = &Map<uintptr_t, List<MapElem<K,C>,A>,A>::put(h, c)->value;
00577 return &l->head->car;
00578 }
00579 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00580 if (AHashFns::equal(akey, p->car.key)) {
00581 p->car.value = avalue;
00582 return &p->car;
00583 }
00584 l->push(c);
00585 return 0;
00586 }
00587
00588 template <class K, class AHashFns, class C, class A> C
00589 ChainHashMap<K, AHashFns, C, A>::get(K akey) {
00590 uintptr_t h = AHashFns::hash(akey);
00591 List<MapElem<K,C>, A> empty;
00592 MapElem<uintptr_t,List<MapElem<K,C>,A> > e(h, empty);
00593 MapElem<uintptr_t,List<MapElem<K,C>,A> > *x = this->set_in(e);
00594 if (!x)
00595 return 0;
00596 List<MapElem<K,C>,A> *l = &x->value;
00597 if (l->head)
00598 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00599 if (AHashFns::equal(akey, p->car.key))
00600 return p->car.value;
00601 return 0;
00602 }
00603
00604 template <class K, class AHashFns, class C, class A> MapElem<K,C> *
00605 ChainHashMap<K, AHashFns, C, A>::put_bag(K akey, C avalue) {
00606 uintptr_t h = AHashFns::hash(akey);
00607 List<MapElem<K,C>,A> empty;
00608 List<MapElem<K,C>,A> *l;
00609 MapElem<K, C> c(akey, avalue);
00610 MapElem<uintptr_t,List<MapElem<K,C>,A> > e(h, empty);
00611 MapElem<uintptr_t,List<MapElem<K,C>,A> > *x = this->set_in(e);
00612 if (x)
00613 l = &x->value;
00614 else {
00615 l = &Map<uintptr_t, List<MapElem<K,C>,A>,A>::put(h, c)->value;
00616 return &l->head->car;
00617 }
00618 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00619 if (AHashFns::equal(akey, p->car.key) && AHashFns::equal_value(avalue, p->car.value))
00620 return &p->car;
00621 l->push(c);
00622 return 0;
00623 }
00624
00625 template <class K, class AHashFns, class C, class A> int
00626 ChainHashMap<K, AHashFns, C, A>::get_bag(K akey, Vec<C> &v) {
00627 uintptr_t h = AHashFns::hash(akey);
00628 List<MapElem<K,C>,A> empty;
00629 MapElem<uintptr_t,List<MapElem<K,C>,A> > e(h, empty);
00630 MapElem<uintptr_t,List<MapElem<K,C>,A> > *x = this->set_in(e);
00631 if (!x)
00632 return 0;
00633 List<MapElem<K,C>,A> *l = &x->value;
00634 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00635 if (AHashFns::equal(akey, p->car.key))
00636 return v.add(x->car);
00637 return v.n;
00638 }
00639
00640 template <class K, class AHashFns, class C, class A> int
00641 ChainHashMap<K, AHashFns, C, A>::del(K akey) {
00642 uintptr_t h = AHashFns::hash(akey);
00643 List<MapElem<K,C>,A> empty;
00644 List<MapElem<K,C>,A> *l;
00645 MapElem<uintptr_t,List<MapElem<K,C>,A> > e(h, empty);
00646 MapElem<uintptr_t,List<MapElem<K,C>,A> > *x = this->set_in(e);
00647 if (x)
00648 l = &x->value;
00649 else
00650 return 0;
00651 ConsCell<MapElem<K,C>,A> *last = 0;
00652 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr) {
00653 if (AHashFns::equal(akey, p->car.key)) {
00654 if (!last)
00655 l->head = p->cdr;
00656 else
00657 last->cdr = p->cdr;
00658 return 1;
00659 }
00660 last = p;
00661 }
00662 return 0;
00663 }
00664
00665 template <class K, class AHashFns, class C, class A> void
00666 ChainHashMap<K, AHashFns, C, A>::get_keys(Vec<K> &keys) {
00667 for (size_t i = 0; i < n; i++) {
00668 List<MapElem<K,C> > *l = &v[i].value;
00669 if (l->head)
00670 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00671 keys.add(p->car.key);
00672 }
00673 }
00674
00675 template <class K, class AHashFns, class C, class A> void
00676 ChainHashMap<K, AHashFns, C, A>::get_values(Vec<C> &values) {
00677 for (size_t i = 0; i < n; i++) {
00678 List<MapElem<K,C>,A> *l = &v[i].value;
00679 if (l->head)
00680 for (ConsCell<MapElem<K,C>,A> *p = l->head; p; p = p->cdr)
00681 values.add(p->car.value);
00682 }
00683 }
00684
00685 template <class F, class A> inline cchar *
00686 StringChainHash<F,A>::canonicalize(cchar *s, cchar *e) {
00687 uintptr_t h = 0;
00688 cchar *a = s;
00689
00690 if (e)
00691 while (a != e) h = h * 27 + (unsigned char)*a++;
00692 else
00693 while (*a) h = h * 27 + (unsigned char)*a++;
00694 MapElem<uintptr_t,List<cchar*, A> > me(h, (char*)0);
00695 MapElem<uintptr_t,List<cchar*, A> > *x = this->set_in(me);
00696 if (x) {
00697 List<cchar*, A> *l = &x->value;
00698 typedef ConsCell<cchar *, A> TT;
00699 forc_List(TT, x, *l) {
00700 a = s;
00701 cchar *b = x->car;
00702 while (1) {
00703 if (!*b) {
00704 if (a == e)
00705 return x->car;
00706 break;
00707 }
00708 if (a >= e || *a != *b)
00709 break;
00710 a++; b++;
00711 }
00712 }
00713 }
00714 s = _dupstr<A>(s, e);
00715 cchar *ss = ChainHash<cchar *, F, A>::put(s);
00716 if (ss)
00717 return ss;
00718 return s;
00719 }
00720
00721 template <class K, class C, class A> inline C
00722 Env<K,C,A>::get(K akey) {
00723 MapElem<K,List<C, A> *> e(akey, 0);
00724 MapElem<K,List<C, A> *> *x = store.set_in(e);
00725 if (x)
00726 return x->value->first();
00727 return (C)0;
00728 }
00729
00730 template <class K, class C, class A> inline List<C, A> *
00731 Env<K,C,A>::get_bucket(K akey) {
00732 List<C, A> *bucket = store.get(akey);
00733 if (bucket)
00734 return bucket;
00735 bucket = new List<C>();
00736 store.put(akey, bucket);
00737 return bucket;
00738 }
00739
00740 template <class K, class C, class A> inline void
00741 Env<K,C,A>::put(K akey, C avalue) {
00742 scope.head->car.push(akey);
00743 get_bucket(akey)->push(avalue);
00744 }
00745
00746 template <class K, class C, class A> inline void
00747 Env<K,C,A>::push() {
00748 scope.push();
00749 }
00750
00751 template <class K, class C, class A> inline void
00752 Env<K,C,A>::pop() {
00753 forc_List(EnvCons, e, scope.first())
00754 get_bucket(e->car)->pop();
00755 }
00756
00757 template <class C, class AHashFns, int N, class A> inline
00758 NBlockHash<C, AHashFns, N, A>::NBlockHash() : n(1), i(0) {
00759 memset(&e[0], 0, sizeof(e));
00760 v = e;
00761 }
00762
00763 template <class C, class AHashFns, int N, class A> inline C*
00764 NBlockHash<C, AHashFns, N, A>::first() {
00765 return &v[0];
00766 }
00767
00768 template <class C, class AHashFns, int N, class A> inline C*
00769 NBlockHash<C, AHashFns, N, A>::last() {
00770 return &v[n * N];
00771 }
00772
00773 template <class C, class AHashFns, int N, class A> inline C
00774 NBlockHash<C, AHashFns, N, A>::put(C c) {
00775 int a;
00776 uintptr_t h = AHashFns::hash(c);
00777 C *x = &v[(h % n) * N];
00778 for (a = 0; a < N; a++) {
00779 if (!x[a])
00780 break;
00781 if (AHashFns::equal(c, x[a]))
00782 return x[a];
00783 }
00784 if (a < N) {
00785 x[a] = c;
00786 return (C)0;
00787 }
00788 C *vv = first(), *ve = last();
00789 C *old_v = v;
00790 i = i + 1;
00791 size(i);
00792 for (;vv < ve; vv++)
00793 if (*vv)
00794 put(*vv);
00795 if (old_v != &e[0])
00796 A::free(old_v);
00797 return put(c);
00798 }
00799
00800 template <class C, class AHashFns, int N, class A> inline void
00801 NBlockHash<C, AHashFns, N, A>::size(int p2) {
00802 n = prime2[p2];
00803 v = (C*)A::alloc(n * sizeof(C) * N);
00804 memset(v, 0, n * sizeof(C) * N);
00805 }
00806
00807 template <class C, class AHashFns, int N, class A> inline C
00808 NBlockHash<C, AHashFns, N, A>::get(C c) {
00809 if (!n)
00810 return (C)0;
00811 uintptr_t h = AHashFns::hash(c);
00812 C *x = &v[(h % n) * N];
00813 for (int a = 0; a < N; a++) {
00814 if (!x[a])
00815 return (C)0;
00816 if (AHashFns::equal(c, x[a]))
00817 return x[a];
00818 }
00819 return (C)0;
00820 }
00821
00822 template <class C, class AHashFns, int N, class A> inline C*
00823 NBlockHash<C, AHashFns, N, A>::assoc_get(C *c) {
00824 if (!n)
00825 return (C*)0;
00826 uintptr_t h = AHashFns::hash(*c);
00827 C *x = &v[(h % n) * N];
00828 int a = 0;
00829 if (c >= x && c < x + N)
00830 a = c - x + 1;
00831 for (; a < N; a++) {
00832 if (!x[a])
00833 return (C*)0;
00834 if (AHashFns::equal(*c, x[a]))
00835 return &x[a];
00836 }
00837 return (C*)0;
00838 }
00839
00840 template <class C, class AHashFns, int N, class A> inline C*
00841 NBlockHash<C, AHashFns, N, A>::assoc_put(C *c) {
00842 int a;
00843 uintptr_t h = AHashFns::hash(*c);
00844 C *x = &v[(h % n) * N];
00845 for (a = 0; a < N; a++) {
00846 if (!x[a])
00847 break;
00848 }
00849 if (a < N) {
00850 x[a] = *c;
00851 return &x[a];
00852 }
00853 x[i % N] = *c;
00854 i++;
00855 return &x[i % N];
00856 }
00857
00858 template <class C, class AHashFns, int N, class A> inline int
00859 NBlockHash<C, AHashFns, N, A>::del(C c) {
00860 int a, b;
00861 if (!n)
00862 return 0;
00863 uintptr_t h = AHashFns::hash(c);
00864 C *x = &v[(h % n) * N];
00865 for (a = 0; a < N; a++) {
00866 if (!x[a])
00867 return 0;
00868 if (AHashFns::equal(c, x[a])) {
00869 if (a < N - 1) {
00870 for (b = a + 1; b < N; b++) {
00871 if (!x[b])
00872 break;
00873 }
00874 if (b != a + 1)
00875 x[a] = x[b - 1];
00876 x[b - 1] = (C)0;
00877 return 1;
00878 } else {
00879 x[N - 1] = (C)0;
00880 return 1;
00881 }
00882 }
00883 }
00884 return 0;
00885 }
00886
00887 template <class C, class AHashFns, int N, class A> inline void
00888 NBlockHash<C, AHashFns, N, A>::clear() {
00889 if (v && v != e) A::free(v);
00890 v = e;
00891 n = 1;
00892 }
00893
00894 template <class C, class AHashFns, int N, class A> inline void
00895 NBlockHash<C, AHashFns, N, A>::reset() {
00896 if (v)
00897 memset(v, 0, n * N * sizeof(C));
00898 }
00899
00900 template <class C, class AHashFns, int N, class A> inline int
00901 NBlockHash<C, AHashFns, N, A>::count() {
00902 int nelements = 0;
00903 C *l = last();
00904 for (C *xx = first(); xx < l; xx++)
00905 if (*xx)
00906 nelements++;
00907 return nelements;
00908 }
00909
00910 template <class C, class AHashFns, int N, class A> inline void
00911 NBlockHash<C, AHashFns, N, A>::copy(const NBlockHash<C, AHashFns, N, A> &hh) {
00912 clear();
00913 n = hh.n;
00914 i = hh.i;
00915 if (hh.v == &hh.e[0]) {
00916 memcpy(e, &hh.e[0], sizeof(e));
00917 v = e;
00918 } else {
00919 if (hh.v) {
00920 v = (C*)A::alloc(n * sizeof(C) * N);
00921 memcpy(v, hh.v, n * sizeof(C) * N);
00922 } else
00923 v = 0;
00924 }
00925 }
00926
00927 template <class C, class AHashFns, int N, class A> inline void
00928 NBlockHash<C, AHashFns, N, A>::move(NBlockHash<C, AHashFns, N, A> &hh) {
00929 clear();
00930 n = hh.n;
00931 i = hh.i;
00932 v = hh.v;
00933 if (hh.v == &hh.e[0]) {
00934 memcpy(e, &hh.e[0], sizeof(e));
00935 v = e;
00936 }
00937 hh.clear();
00938 }
00939
00940 void test_map();
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 template <
01028 typename H
01029 >
01030 class TSHashTable {
01031 public:
01032 typedef TSHashTable self;
01033
01034
01035 typedef H Hasher;
01036 typedef typename Hasher::ID ID;
01037 typedef typename Hasher::Key Key;
01038 typedef typename Hasher::Value Value;
01039 typedef typename Hasher::ListHead ListHead;
01040
01041
01042 enum ExpansionPolicy {
01043 MANUAL,
01044 AVERAGE,
01045 MAXIMUM
01046 };
01047
01048
01049
01050
01051
01052
01053
01054 struct Bucket {
01055 ListHead m_chain;
01056 size_t m_count;
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 LINK(Bucket, m_link);
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 bool m_mixed_p;
01077
01078
01079 Bucket() : m_count(0), m_mixed_p(false) { ink_zero(m_link); }
01080 };
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 struct Location {
01093 Value* m_value;
01094 Bucket* m_bucket;
01095 ID m_id;
01096 size_t m_distance;
01097
01098
01099 Location() : m_value(NULL), m_bucket(NULL), m_id(0), m_distance(0) {}
01100
01101
01102 bool isValid() const { return NULL != m_value; }
01103
01104
01105
01106
01107 operator Value* () const { return m_value; }
01108
01109
01110 Value& operator * () const { return *m_value; }
01111
01112 Value* operator -> () const { return m_value; }
01113
01114
01115 Location& operator ++ () { if (m_value) this->advance(); return *this; }
01116
01117 Location& operator ++ (int) {
01118 Location zret(*this);
01119 if (m_value) this->advance();
01120 return zret;
01121 }
01122
01123 protected:
01124
01125 void advance();
01126
01127 friend class TSHashTable;
01128 };
01129
01130
01131
01132
01133
01134 struct iterator {
01135 Value* m_value;
01136 Bucket* m_bucket;
01137
01138 iterator() : m_value(0), m_bucket(0) {}
01139 iterator& operator ++ ();
01140 Value& operator * () { return *m_value; }
01141 Value* operator -> () { return m_value; }
01142 bool operator == (iterator const& that) { return m_bucket == that.m_bucket && m_value == that.m_value; }
01143 bool operator != (iterator const& that) { return !(*this == that); }
01144
01145 protected:
01146
01147 iterator(Bucket* b, Value* v) : m_value(v), m_bucket(b) {}
01148 friend class TSHashTable;
01149 };
01150
01151 iterator begin();
01152 iterator end();
01153
01154
01155 static size_t const DEFAULT_BUCKET_COUNT = 7;
01156
01157 static size_t const DEFAULT_EXPANSION_LIMIT = 4;
01158
01159
01160
01161
01162 TSHashTable(size_t nb = DEFAULT_BUCKET_COUNT);
01163
01164
01165
01166
01167
01168 void insert(Value* value);
01169
01170
01171
01172
01173
01174
01175
01176
01177 Location find(Key key);
01178
01179
01180
01181
01182
01183
01184
01185
01186 Location find(Value* value);
01187
01188
01189
01190
01191
01192
01193
01194 bool remove(Location const& location);
01195
01196
01197
01198
01199
01200
01201
01202 bool remove(Key key);
01203
01204
01205
01206
01207
01208
01209 void clear();
01210
01211
01212 size_t count() const { return m_count; }
01213
01214
01215 size_t bucketCount() const { return m_array.n; }
01216
01217
01218 void setExpansionPolicy(ExpansionPolicy p) { m_expansion_policy = p; }
01219
01220 void expansionPolicy() const { return m_expansion_policy; }
01221
01222 void setExpansionLimit(size_t n) { m_expansion_limit = n; }
01223
01224 size_t expansionLimit() const { return m_expansion_limit; }
01225
01226
01227
01228
01229
01230 void expand();
01231
01232 protected:
01233 typedef Vec<Bucket, DefaultAlloc, 0> Array;
01234
01235 size_t m_count;
01236 ExpansionPolicy m_expansion_policy;
01237 size_t m_expansion_limit;
01238 Array m_array;
01239
01240
01241
01242
01243
01244 typedef DLL<Bucket, typename Bucket::Link_m_link> BucketChain;
01245
01246 BucketChain m_bucket_chain;
01247
01248
01249
01250
01251 void findBucket(Key key, Location& location);
01252 };
01253
01254 template < typename H > typename TSHashTable<H>::iterator
01255 TSHashTable<H>::begin() {
01256
01257 Bucket* b = m_bucket_chain.head;
01258 return b && b->m_chain.head
01259 ? iterator(b, b->m_chain.head)
01260 : this->end()
01261 ;
01262 }
01263
01264 template < typename H > typename TSHashTable<H>::iterator
01265 TSHashTable<H>::end() {
01266 return iterator(0,0);
01267 }
01268
01269 template < typename H > typename TSHashTable<H>::iterator&
01270 TSHashTable<H>::iterator::operator ++ () {
01271 if (m_value) {
01272 if (NULL == (m_value = ListHead::next(m_value))) {
01273 if (NULL != (m_bucket = BucketChain::next(m_bucket))) {
01274 m_value = m_bucket->m_chain.head;
01275 ink_assert(m_value);
01276 }
01277 }
01278 }
01279 return *this;
01280 }
01281
01282 template < typename H > TSHashTable<H>::TSHashTable(size_t nb)
01283 : m_count(0), m_expansion_policy(AVERAGE), m_expansion_limit(DEFAULT_EXPANSION_LIMIT) {
01284 if (nb) {
01285 int idx = 1;
01286 while (prime2[idx] < nb) ++idx;
01287 m_array.n = 1;
01288 m_array.i = idx - 1;
01289 }
01290 m_array.set_expand();
01291 }
01292
01293 template < typename H > void
01294 TSHashTable<H>::Location::advance() {
01295 Key key = Hasher::key(m_value);
01296
01297 do {
01298 ++m_distance;
01299 m_value = ListHead::next(m_value);
01300 } while (m_value && ! Hasher::equal(key, Hasher::key(m_value)));
01301 }
01302
01303 template < typename H > void
01304 TSHashTable<H>::findBucket(Key key, Location& location) {
01305 location.m_id = Hasher::hash(key);
01306 location.m_bucket = &(m_array[location.m_id % m_array.n]);
01307 }
01308
01309 template < typename H > typename TSHashTable<H>::Location
01310 TSHashTable<H>::find(Key key) {
01311 Location zret;
01312 Value* v;
01313
01314 this->findBucket(key, zret);
01315 v = zret.m_bucket->m_chain.head;
01316
01317 while (0 != v && ! Hasher::equal(key, Hasher::key(v)))
01318 v = ListHead::next(v);
01319 zret.m_value = v;
01320 return zret;
01321 }
01322
01323 template < typename H > typename TSHashTable<H>::Location
01324 TSHashTable<H>::find(Value* value) {
01325 Location zret;
01326 this->findBucket(Hasher::key(value), zret);
01327 if (zret.m_bucket->m_chain.in(value))
01328 zret.m_value = value;
01329 return zret;
01330 }
01331
01332 template < typename H > void
01333 TSHashTable<H>::insert(Value* value) {
01334 Key key = Hasher::key(value);
01335 Bucket* bucket = &(m_array[Hasher::hash(key) % m_array.n]);
01336
01337
01338 ink_assert(! bucket->m_chain.in(value));
01339
01340
01341 if (!bucket->m_mixed_p && !bucket->m_chain.empty() && ! Hasher::equal(key, Hasher::key(bucket->m_chain.head)))
01342 bucket->m_mixed_p = true;
01343
01344 bucket->m_chain.push(value);
01345 ++m_count;
01346 if (1 == ++(bucket->m_count))
01347 m_bucket_chain.push(bucket);
01348
01349 if ((AVERAGE == m_expansion_policy && (m_count / m_array.n) > m_expansion_limit)
01350 || (MAXIMUM == m_expansion_policy && bucket->m_count > m_expansion_limit && bucket->m_mixed_p))
01351 this->expand();
01352 }
01353
01354 template < typename H > bool
01355 TSHashTable<H>::remove(Location const& l) {
01356 bool zret = false;
01357 if (l.isValid()) {
01358 ink_assert(l.m_bucket->m_count);
01359 ink_assert(l.m_bucket->m_chain.head);
01360 l.m_bucket->m_chain.remove(l.m_value);
01361 --m_count;
01362 --(l.m_bucket->m_count);
01363 if (0 == l.m_bucket->m_count)
01364 m_bucket_chain.remove(l.m_bucket);
01365 else if (1 == l.m_bucket->m_count)
01366 l.m_bucket->m_mixed_p = false;
01367 zret = true;
01368 }
01369 return zret;
01370 }
01371
01372 template < typename H > bool
01373 TSHashTable<H>::remove(Key key) {
01374 Location loc = this->find(key);
01375 bool zret = loc.isValid();
01376 while (loc.isValid()) {
01377 Location target(loc);
01378 loc.advance();
01379 this->remove(target);
01380 }
01381 return zret;
01382 }
01383
01384 template < typename H > void
01385 TSHashTable<H>::clear() {
01386 Bucket null_bucket;
01387
01388 for ( size_t i = 0 ; i < m_array.n ; ++i ) {
01389 m_array[i] = null_bucket;
01390 }
01391
01392 m_count = 0;
01393 m_bucket_chain.clear();
01394 }
01395
01396 template < typename H > void
01397 TSHashTable<H>::expand() {
01398 Bucket* b = m_bucket_chain.head;
01399 ExpansionPolicy org_expansion_policy = m_expansion_policy;
01400 Array tmp;
01401 tmp.move(m_array);
01402
01403 m_count = 0;
01404 m_bucket_chain.clear();
01405
01406
01407
01408
01409 m_array.n = 1;
01410 m_array.i = tmp.i;
01411 m_array.set_expand();
01412
01413 m_expansion_policy = MANUAL;
01414
01415 while (b) {
01416 Value* v = b->m_chain.head;
01417 while (v) {
01418 b->m_chain.remove(v);
01419 this->insert(v);
01420 v = b->m_chain.head;
01421 }
01422 b = BucketChain::next(b);
01423 }
01424
01425 m_expansion_policy = org_expansion_policy;
01426 }
01427
01428
01429
01430 #endif