map.icc
Go to the documentation of this file.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
00034
00035
00036
00037
00038 namespace Gecode { namespace Support {
00039
00045 template <class Key, class Value>
00046 class Map {
00047 private:
00049 class Pair {
00050 public:
00051 Key k; Value v;
00052 Pair(const Key& k0, const Value& v0) : k(k0), v(v0) {}
00053 };
00054
00056 Pair** a;
00058 int n;
00060 int usage;
00062 int modulo(void) const;
00064 void rehash(void);
00065 public:
00067 Map(void);
00069 void put(const Key& k, Value v);
00071 bool get(const Key& k, Value& v) const;
00073 GECODE_MSC_VIRTUAL ~Map(void);
00074 };
00075
00077 template <class Value>
00078 class SymbolMap : public Map<Symbol,Value> {
00079 };
00080
00082 template <class P>
00083 class Pointer {
00084 protected:
00086 P* p;
00087 public:
00089 Pointer(P* p0) : p(p0) {}
00091 P* operator()(void) { return p; }
00093 bool operator==(const Pointer<P>& p0) const {
00094 return p == p0.p;
00095 }
00097 int hash(int m) const {
00098 return static_cast<unsigned int>(reinterpret_cast<ptrdiff_t>(p)) % m;
00099 }
00100 };
00101
00103 template <class P, class Value>
00104 class PtrMap : public Map<Pointer<P>,Value> {
00105 };
00106
00107
00108
00109
00110
00111
00112 template <class Key, class Value>
00113 forceinline int
00114 Map<Key,Value>::modulo(void) const {
00115 const int primes[] = { 17, 47, 1021, 2039, 4093, 8191,
00116 16381, 32749, 65521, 131071,
00117 262139, 524287, 1048573, 2097143,
00118 4194301, 8388593 };
00119 return primes[n];
00120 }
00121
00122 template <class Key, class Value>
00123 Map<Key,Value>::Map(void) : n(0), usage(0) {
00124 a = static_cast<Pair**>(Memory::malloc(sizeof(Pair*)*modulo()));
00125 for (int i=modulo(); i--; )
00126 a[i] = NULL;
00127 }
00128
00129 template <class Key, class Value>
00130 void
00131 Map<Key,Value>::rehash(void) {
00132 int oldM = modulo();
00133 n++;
00134 Pair** olda = a;
00135 a = static_cast<Pair**>(Memory::malloc(sizeof(Pair*)*modulo()));
00136 for (int i=modulo(); i--; )
00137 a[i] = NULL;
00138 for (int i=oldM; i--;) {
00139 if (olda[i] != NULL) {
00140 int j = olda[i]->k.hash(modulo());
00141 for (; j < modulo() && a[j] != NULL; j++) {}
00142 if (j >= modulo()) {
00143 for (j=0; a[j] != NULL; j++) {}
00144 assert(j<olda[i]->k.hash(modulo()));
00145 }
00146 assert(j < modulo());
00147 assert(a[j] == NULL);
00148 a[j] = olda[i];
00149 }
00150 }
00151 #ifndef NDEBUG
00152 int actualUsage = 0;
00153 for (int i=modulo(); i--;)
00154 if (a[i]) actualUsage++;
00155 assert(actualUsage == usage);
00156 #endif
00157 Memory::free(olda);
00158 }
00159
00160 template <class Key, class Value>
00161 void
00162 Map<Key,Value>::put(const Key& k, Value v) {
00163
00164 if (usage * 3 >= modulo() * 2)
00165 rehash();
00166
00167 int i = k.hash(modulo());
00168 for (; i < modulo() && a[i] != NULL; i++) {}
00169 if (i >= modulo()) {
00170 for (i=0; a[i] != NULL; i++) {}
00171 assert(i<k.hash(modulo()));
00172 }
00173 assert(i < modulo());
00174 assert(a[i] == NULL);
00175 a[i] = new Pair(k,v);
00176 usage++;
00177 }
00178
00179 template <class Key, class Value>
00180 inline bool
00181 Map<Key,Value>::get(const Key& k, Value& v) const {
00182 int i=k.hash(modulo());
00183 for (; i<modulo() && a[i] != NULL; i++) {
00184 if (a[i]->k == k) {
00185 v = a[i]->v; return true;
00186 }
00187 }
00188 if (i >= modulo()) {
00189 for (i=0; a[i] != NULL; i++) {
00190 if (a[i]->k == k) {
00191 v = a[i]->v; return true;
00192 }
00193 }
00194 }
00195 return false;
00196 }
00197
00198 template <class Key, class Value>
00199 Map<Key,Value>::~Map(void) {
00200 for (int i=modulo(); i--; )
00201 delete a[i];
00202 Memory::free(a);
00203 }
00204
00205 }}
00206
00207