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