00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00017 #ifndef __DERS__HASH_VEC_HPP__
00018 #define __DERS__HASH_VEC_HPP__
00019
00020 #include <ders/config.hpp>
00021 #include <algorithm>
00022 #include <ders/text.hpp>
00023
00024 namespace ders {
00025
00026 using namespace std;
00027
00028 namespace detail {
00029
00030 template<class Key, class Val>
00031 struct hash_vec_nodes {
00032 struct node {
00033 Key key;
00034 Val val;
00035 int next;
00036
00037 node(const Key& k, const Val& v) : key(k), val(v), next(-1) {}
00038 };
00039
00040 int resd;
00041 int used;
00042 node* nodes;
00043
00044 hash_vec_nodes(int rsrv);
00045 ~hash_vec_nodes();
00046
00047 void create_at(int pos, const Key& k, const Val& v);
00048 void destroy_at(int pos);
00049 void move_to(int to, int from);
00050 };
00051
00052 template<class Key, class Val>
00053 hash_vec_nodes<Key, Val>::hash_vec_nodes(int rsrv) :
00054 resd(rsrv), used(0), nodes(0)
00055 {
00056 assert(resd>0);
00057 nodes=static_cast<node*>(operator new(sizeof(node)*resd));
00058 }
00059
00060 template<class Key, class Val>
00061 hash_vec_nodes<Key, Val>::~hash_vec_nodes()
00062 {
00063 for (int i=0; i<used; i++) destroy_at(i);
00064 operator delete(nodes);
00065 }
00066
00067 template<class Key, class Val>
00068 inline void hash_vec_nodes<Key, Val>::create_at(int pos, const Key& k, const
00069 Val& v)
00070 {
00071 new(nodes+pos) node(k, v);
00072 }
00073
00074 template<class Key, class Val>
00075 inline void hash_vec_nodes<Key, Val>::destroy_at(int pos)
00076 {
00077 nodes[pos].~node();
00078 }
00079
00080 template<class Key, class Val>
00081 inline void hash_vec_nodes<Key, Val>::move_to(int to, int from)
00082 {
00083 memcpy(nodes+to, nodes+from, sizeof(*nodes));
00084 }
00085
00086 size_t calc_hash(const void* ptr, int n);
00087
00088 }
00089
00093 template<class Key>
00094 struct key_hash {
00095 };
00096
00097 #define TRIVIAL_KEY_HASH(type) \
00098 template<> \
00099 struct key_hash<type> { \
00100 size_t operator()(type k) const { return k; } \
00101 }
00102
00103 TRIVIAL_KEY_HASH(char);
00104 TRIVIAL_KEY_HASH(unsigned char);
00105 TRIVIAL_KEY_HASH(signed char);
00106 TRIVIAL_KEY_HASH(short);
00107 TRIVIAL_KEY_HASH(unsigned short);
00108 TRIVIAL_KEY_HASH(int);
00109 TRIVIAL_KEY_HASH(unsigned int);
00110 TRIVIAL_KEY_HASH(long);
00111 TRIVIAL_KEY_HASH(unsigned long);
00112
00113 #undef TRIVIAL_KEY_HASH
00114
00115 template<class T>
00116 struct key_hash<T*> {
00117 size_t operator()(T* k) const { return reinterpret_cast<size_t>(k); }
00118 };
00119
00120 template<>
00121 struct key_hash<sh_text> {
00122 size_t operator()(const sh_text& t) const
00123 { return detail::calc_hash(t->begin(), t->size()); }
00124 };
00125
00129 template<class Key>
00130 struct key_eql {
00131 bool operator()(const Key& key1, const Key& key2) const
00132 { return (key1==key2) ? true : false; }
00133 };
00134
00138 template<class Key, class Val, class KeyHash=key_hash<Key>, class KeyEql=
00139 key_eql<Key> >
00140 class hash_vec {
00141 typedef detail::hash_vec_nodes<Key, Val> nodes;
00142
00143 KeyHash khash;
00144 KeyEql keql;
00145 int* hndx;
00146 nodes nds;
00147
00148 int* root(const Key& k) const { return hndx+khash(k)%nds.resd; }
00149 int* find(int* root, const Key& k) const;
00150
00151 hash_vec(const hash_vec&);
00152 hash_vec& operator=(const hash_vec&);
00153
00154 public:
00155 hash_vec(int rsrv, const KeyHash& kh=KeyHash(), const KeyEql& ke=
00156 KeyEql());
00157 ~hash_vec() { operator delete(hndx); }
00158
00159 int size() const { return nds.used; }
00160 int capacity() const { return nds.resd; }
00161 void reserve(int n);
00162
00163 const Key& key(int pos) const;
00164 Val& val(int pos);
00165 const Val& val(int pos) const;
00166
00167 int insert(const Key& k, const Val& v);
00168 int find(const Key& k) const { return *find(root(k), k); }
00169 void erase(int pos);
00170 };
00171
00172 template<class Key, class Val, class KeyHash, class KeyEql>
00173 int* hash_vec<Key, Val, KeyHash, KeyEql>::find(int* root, const Key& k) const
00174 {
00175 for (int* ptr=root; ; ptr=&nds.nodes[*ptr].next)
00176 if (*ptr==-1 || keql(nds.nodes[*ptr].key, k)) return ptr;
00177 }
00178
00179 template<class Key, class Val, class KeyHash, class KeyEql>
00180 hash_vec<Key, Val, KeyHash, KeyEql>::hash_vec(int rsrv, const KeyHash& kh, const
00181 KeyEql& ke) : khash(kh), keql(ke), hndx(0), nds(rsrv)
00182 {
00183 hndx=static_cast<int*>(operator new(sizeof(int)*nds.resd));
00184 fill_n(hndx, nds.resd, -1);
00185 }
00186
00187 template<class Key, class Val, class KeyHash, class KeyEql>
00188 void hash_vec<Key, Val, KeyHash, KeyEql>::reserve(int n)
00189 {
00190 assert(n>0);
00191 if (nds.resd>=n) return;
00192
00193 int* hndx2=static_cast<int*>(operator new(sizeof(int)*n));
00194
00195 typedef typename nodes::node node;
00196 node* nodes2;
00197 try { nodes2=static_cast<node*>(operator new(sizeof(node)*n)); }
00198 catch (...) {
00199 operator delete(hndx);
00200 throw;
00201 }
00202
00203 fill_n(hndx2, n, -1);
00204
00205 memcpy(nodes2, nds.nodes, sizeof(*nodes2)*nds.used);
00206 for (int i=0; i<nds.used; i++) nodes2[i].next=-1;
00207
00208 for (int i=0; i<nds.used; i++) {
00209 int* pnode=hndx2+khash(nodes2[i].key)%n;
00210 nodes2[i].next=*pnode;
00211 *pnode=i;
00212 }
00213
00214 operator delete(hndx);
00215 hndx=hndx2;
00216
00217 operator delete(nds.nodes);
00218 nds.nodes=nodes2;
00219 nds.resd=n;
00220 }
00221
00222 template<class Key, class Val, class KeyHash, class KeyEql>
00223 inline const Key& hash_vec<Key, Val, KeyHash, KeyEql>::key(int pos) const
00224 {
00225 assert(pos>=0 && pos<size());
00226 return nds.nodes[pos].key;
00227 }
00228
00229 template<class Key, class Val, class KeyHash, class KeyEql>
00230 inline Val& hash_vec<Key, Val, KeyHash, KeyEql>::val(int pos)
00231 {
00232 assert(pos>=0 && pos<size());
00233 return nds.nodes[pos].val;
00234 }
00235
00236 template<class Key, class Val, class KeyHash, class KeyEql>
00237 inline const Val& hash_vec<Key, Val, KeyHash, KeyEql>::val(int pos) const
00238 {
00239 assert(pos>=0 && pos<size());
00240 return nds.nodes[pos].val;
00241 }
00242
00243 template<class Key, class Val, class KeyHash, class KeyEql>
00244 int hash_vec<Key, Val, KeyHash, KeyEql>::insert(const Key& k, const Val& v)
00245 {
00246 assert(nds.used<=nds.resd);
00247 if (nds.used==nds.resd) reserve(nds.resd*2+1);
00248
00249 int* pnode=find(root(k), k);
00250 if (*pnode!=-1) return -1;
00251
00252 nds.create_at(nds.used, k, v);
00253 return *pnode=nds.used++;
00254 }
00255
00256 template<class Key, class Val, class KeyHash, class KeyEql>
00257 void hash_vec<Key, Val, KeyHash, KeyEql>::erase(int pos)
00258 {
00259 assert(pos>=0 && pos<size());
00260
00261 const Key& k=nds.nodes[pos].key;
00262 int* pnode=find(root(k), k);
00263 assert(*pnode==pos);
00264
00265 int tail=nds.nodes[pos].next;
00266
00267 nds.destroy_at(pos);
00268 *pnode=-1;
00269
00270 if (tail!=-1) {
00271 int* ptr=root(nds.nodes[tail].key);
00272 while (*ptr!=-1) ptr=&nds.nodes[*ptr].next;
00273
00274 *ptr=tail;
00275 }
00276
00277 int last=nds.used-1;
00278 if (pos!=last) {
00279 const Key& lkey=nds.nodes[last].key;
00280 int* nlast=find(root(lkey), lkey);
00281 assert(*nlast==last);
00282
00283 nds.move_to(pos, last);
00284 *nlast=pos;
00285 }
00286
00287 nds.used--;
00288 }
00289
00290 }
00291
00292 #endif // __DERS__HASH_VEC_HPP__
00293