Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_dynSetHash.H
1 # ifndef TPL_DYNSETHASH_H
2 # define TPL_DYNSETHASH_H
3 
4 # include <algorithm>
5 # include <typeinfo>
6 # include <ahDry.H>
7 # include <primes.H>
8 # include <htlist.H>
9 # include <tpl_dynArray.H>
10 # include <tpl_dynSetOhash.H>
11 # include <tpl_lhash.H>
12 # include <tpl_linHash.H>
13 
14 
15 namespace Aleph
16 {
17 
31  template <typename Key,
32  class Cmp = Aleph::equal_to<Key>,
33  template <typename, class> class HashTable = LhashTable>
34 class DynHashTable : public HashTable<Key, Cmp>
35 {
36 protected:
37 
38  typedef HashTable<Key, Cmp> Base;
39 
40  typedef typename HashTable<Key, Cmp>::Bucket Bucket;
41 
42 public:
43 
45  typedef typename Base::Hash_Fct Hash_Fct;
46 
47  typedef Key Key_Type;
48 
49  typedef Key Item_Type;
50 
61  DynHashTable(Hash_Fct hash_fct = Aleph::dft_hash_fct<Key>,
62  const size_t len = Primes::DefaultPrime,
63  const float lower_alpha = hash_default_lower_alpha,
64  const float upper_alpha = hash_default_upper_alpha)
65  : Base(hash_fct, len, lower_alpha, upper_alpha, true, true)
66  {
67  // empty
68  }
69 
70 private:
71 
72  void copy(const DynHashTable & other)
73  {
74  for (typename Base::Iterator it(other); it.has_curr(); it.next())
75  {
76  Bucket * bucket = (Bucket*) it.get_curr();
77  insert(bucket->get_key());
78  I(*search(bucket->get_key()) == bucket->get_key());
79  }
80  }
81 
82 public:
83 
84  DynHashTable(const DynHashTable & other)
85  : Base(other.hash_fct, other.len,
86  other.lower_alpha, other.upper_alpha, true, true)
87  {
88  copy(other);
89  }
90 
91  DynHashTable(DynHashTable && other)
92  : Base(other.hash_fct, other.len,
93  other.lower_alpha, other.upper_alpha, true, true)
94  {
95  this->swap(other);
96  }
97 
98  ~DynHashTable()
99  {
100  this->empty();
101  }
102 
103  DynHashTable & operator = (const DynHashTable & other)
104  {
105  if (this == &other)
106  return *this;
107 
108  this->empty();
109  copy(other);
110 
111  return *this;
112  }
113 
114  DynHashTable & operator = (DynHashTable && other)
115  {
116  this->swap(other);
117  return *this;
118  }
119 
120 protected:
121 
122  Key * insert_bucket(Bucket * bucket)
123  {
124  Bucket * ret_val = (Bucket*) this->Base::insert(bucket);
125  if (ret_val == NULL) // is the key in the table?
126  { // yes! ==> free bucket
127  delete bucket;
128  return NULL;
129  }
130 
131  return &ret_val->get_key();
132  }
133 
134 public:
135 
138  Key * insert(const Key & key)
139  {
140  return insert_bucket(new Bucket (key));
141  }
142 
143  Key * insert(Key && key)
144  {
145  return insert_bucket(new Bucket (std::move(key)));
146  }
147 
148  Key * add(const Key & key)
149  {
150  return insert_bucket(new Bucket (key));
151  }
152 
153  Key * add(Key && key)
154  {
155  return insert_bucket(new Bucket (std::move(key)));
156  }
157 
161  Key * search(const Key & key) const
162  {
163  Bucket * bucket = (Bucket*) this->Base::search(key);
164 
165  return bucket != NULL ? &bucket->get_key() : NULL;
166  }
167 
168  bool has(const Key & key) const
169  {
170  return this->Base::search(key) != NULL;
171  }
172 
173  bool contains(const Key & key) const { return has(key); }
174 
175  Key & find(const Key & key)
176  {
177  Bucket * bucket = (Bucket*) this->Base::search(key);
178 
179  if (bucket == NULL)
180  throw std::domain_error("Key not found in hash");
181 
182  return bucket->get_key();
183  }
184 
186  Generic_Keys(Key);
187 
188 protected:
189 
190  static Bucket * key_to_bucket(Key * key)
191  {
192  Bucket * ret_val = 0;
193  size_t offset = reinterpret_cast<size_t>(&ret_val->get_key());
194 
195  return reinterpret_cast<Bucket*>(reinterpret_cast<size_t>(key) - offset);
196  }
197 
198 public:
199 
202  void remove(Key * key)
203  {
204  Bucket * bucket = key_to_bucket(key);
205  this->Base::remove(bucket);
206  delete bucket;
207  }
208 
209  void remove(const Key & key)
210  {
211  Bucket * bucket = (Bucket*) this->Base::search(key);
212  if (bucket == NULL)
213  throw std::domain_error("Key not in hash table");
214 
215  this->Base::remove(bucket);
216  delete bucket;
217  }
218 
219 
247  Generic_Traverse(Key);
248  Functional_Methods(Key);
249  Equal_To_Method(DynHashTable);
250 
251  class Iterator : public Base::Iterator
252  {
253  public:
254 
255  Iterator(const DynHashTable & table) : Base::Iterator(table) {}
256 
257  const Key & get_curr()
258  {
259  return this->Base::Iterator::get_curr()->get_key();
260  }
261 
262  void del() { delete this->Base::Iterator::del(); }
263  };
264 };
265 
266 
267  template <typename Key, class Cmp = Aleph::equal_to<Key>>
268 struct DynSetHash : public DynHashTable<Key, Cmp, LhashTable>
269 {
271 
272  using Base::Base;
273 };
274 
275  template <typename Key, class Cmp = Aleph::equal_to<Key>>
276 struct DynSetLinHash : public DynHashTable<Key, Cmp, LinearHashTable>
277 {
279 
280  using Base::Base;
281 };
282 
283 
284 template <typename Key, typename Data,
286  template <class, class> class HashTable = LinearHashTable>
288  : public DynHashTable<std::pair<Key, Data>, Cmp, HashTable>
289 {
290  typedef std::pair<Key, Data> Pair;
291 
292  typedef DynHashTable<std::pair<Key, Data>, Cmp, HashTable> Base;
293 
294  typedef typename Base::Bucket Bucket;
295 
296  public:
297 
298  // given a valid reference to key, given from find or through iterator
299  // or other functional primitives, get_data() retrieves the data
300  // associated to the key inside the table.
301  Data & get_data(const Key & key)
302  {
303  return key_to_pair<Key, Data>(&const_cast<Key&>(key))->second;
304  }
305 
306  const Key & get_key(Data * data_ptr)
307  {
308  return data_to_pair<Key, Data>(data_ptr)->first;
309  }
310 
311  typedef Data Value_Type;
312 
313  typedef size_t (*Hash_Fct)(const Key&);
314 
315  using Base::Base;
316 
317  template <size_t (*fct)(const Key & k)> static
318  size_t wrapper(const std::pair<Key, Data> & p)
319  {
320  return (*fct)(p.first);
321  }
322 
334  (typename Base::Hash_Fct hash_fct = wrapper<Aleph::dft_hash_fct<Key>>,
335  const size_t len = Primes::DefaultPrime,
336  const float lower_alpha = hash_default_lower_alpha,
337  const float upper_alpha = hash_default_upper_alpha)
338  : Base(hash_fct, len, lower_alpha, upper_alpha)
339  {
340  // empty
341  }
342 
346  Key * insert(const Key & key, const Data & data)
347  {
348  Pair * p = this->insert_bucket(new typename Base::Bucket (Pair(key, data)));
349 
350  return p != NULL ? &p->first : NULL;
351  }
352 
353  Key * insert(const Key & key, Data && data)
354  {
355  Pair * p = this->insert_bucket
356  (new typename Base::Bucket (Pair(key, std::move(data))));
357 
358  return p != NULL ? &p->first : NULL;
359  }
360 
361  Key * insert(Key && key, Data && data)
362  {
363  Pair * p = this->insert_bucket
364  (new typename Base::Bucket (Pair(std::move(key), std::move(data))));
365 
366  return p != NULL ? &p->first : NULL;
367  }
368 
369  Key * insert(Key && key, const Data & data)
370  {
371  Pair * p= this->insert_bucket
372  (new typename Base::Bucket (Pair(std::move(key), data)));
373 
374  return p != NULL ? &p->first : NULL;
375  }
376 
380  Data * search(const Key & key) const
381  {
382  Pair * p = this->Base::search(Pair(key, Data()));
383  return p != NULL ? &p->second : NULL;
384  }
385 
386  bool has(const Key & key)
387  {
388  return this->Base::search(Pair(key, Data())) != NULL;
389  }
390 
391  Data & find(const Key & key)
392  {
393  return Base::find(Pair(key, Data())).second;
394  }
395 
398  void remove_by_data(Data & data)
399  {
400  Base::remove(data_to_pair<Key, Data>(&data));
401  }
402 
403  void remove(const Key & key)
404  {
405  Base::remove(Pair(key, Data()));
406  }
407 
408  Map_Sequences_Methods();
409 
410  Generate_Proxy_Operator(DynMapHashTable);
411 };
412 
413 template <typename Key,
414  typename Data,
416 struct DynMapLinHash : public DynMapHashTable<Key, Data, Cmp, LinearHashTable>
417 {
419 
420  using Base::Base;
421 };
422 
423 template <typename Key,
424  typename Data,
426 struct DynMapHash : public DynMapHashTable<Key, Data, Cmp, LhashTable>
427 {
429 
430  using Base::Base;
431 };
432 
433 
434 
435 } // end namespace Aleph
436 
437 # endif // TPL_DYNSETHASH_H
DynHashTable(Hash_Fct hash_fct=Aleph::dft_hash_fct< Key >, const size_t len=Primes::DefaultPrime, const float lower_alpha=hash_default_lower_alpha, const float upper_alpha=hash_default_upper_alpha)
Definition: tpl_dynSetHash.H:61
Key * insert(const Key &key)
Definition: tpl_dynSetHash.H:138
Data * search(const Key &key) const
Definition: tpl_dynSetHash.H:380
Definition: tpl_dynSetHash.H:426
Definition: tpl_dynSetHash.H:287
Definition: tpl_dynSetHash.H:416
Itor1 search(Itor1 beg, const Itor1 &end, Itor2 searchBeg, const Itor2 &searchEnd, BinaryPredicate op=BinaryPredicate())
Definition: ahAlgo.H:327
DynMapHashTable(typename Base::Hash_Fct hash_fct=wrapper< Aleph::dft_hash_fct< Key >>, const size_t len=Primes::DefaultPrime, const float lower_alpha=hash_default_lower_alpha, const float upper_alpha=hash_default_upper_alpha)
Definition: tpl_dynSetHash.H:334
Definition: tpl_dynSetHash.H:276
Key * search(const Key &key) const
Definition: tpl_dynSetHash.H:161
void remove_by_data(Data &data)
Definition: tpl_dynSetHash.H:398
Definition: tpl_linHash.H:55
Definition: tpl_lhash.H:531
void remove(std::pair< Key, Data > *key)
Definition: tpl_dynSetHash.H:202
Definition: ahDry.H:523
Definition: tpl_dynSetHash.H:251
Key * insert(const Key &key, const Data &data)
Definition: tpl_dynSetHash.H:346
Generic_Keys(Key)
returns a container with all the keys of the table
Base::Hash_Fct Hash_Fct
El tipo de función hash.
Definition: tpl_dynSetHash.H:45
Definition: tpl_dynSetHash.H:34
Definition: tpl_dynSetHash.H:268
Definition: ahFunction.H:115
Definition: tpl_linHash.H:560

Leandro Rabindranath León