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_dynLhash.H
1 
2 # ifndef TPL_DYNLHASH_H
3 # define TPL_DYNLHASH_H
4 
5 # include <tpl_lhash.H>
6 
7 using namespace Aleph;
8 
9 namespace Aleph {
10 
35  template <typename Key, typename Record, class Cmp = Aleph::equal_to<Key>>
36 class DynLhashTable : public LhashTable<Key>
37 {
38 private:
39 
40  struct DLBucket : public LhashTable<Key>::Bucket
41  {
42  Record record;
43 
44  DLBucket(const Key & key, const Record & _record)
45  : LhashTable<Key>::Bucket(key), record(_record) { /* Empty */ }
46 
47 
48  DLBucket(const Key & key, Record && _record)
49  : LhashTable<Key>::Bucket(key), record(std::move(_record)) { /* Empty */ }
50 
51  DLBucket(Key && key, const Record & _record)
52  : LhashTable<Key>::Bucket(std::move(key)), record(_record) { /* Empty */ }
53 
54  DLBucket(Key && key, Record && _record)
55  : LhashTable<Key>::Bucket(std::move(key)),
56  record(std::move(_record)) { /* Empty */ }
57  };
58 
59  static DLBucket * record_to_bucket(Record * rec)
60  {
61  DLBucket * ret_val = 0;
62  size_t offset = (size_t) &ret_val->record;
63  return (DLBucket*) (((size_t) rec) - offset);
64  }
65 
66  class DLProxy
67  {
68  DynLhashTable & table;
69  const Key & key;
70  DLBucket * bucket;
71 
72  public:
73 
74  DLProxy(DynLhashTable & _table, const Key& _key)
75  : table(_table), key(_key)
76  {
77  Record * record = table.search(key);
78  bucket = record not_eq NULL ? record_to_bucket(record) : NULL;
79  }
80 
81  operator const Record & () const
82  throw(std::exception, std::invalid_argument)
83  {
84  if (bucket == NULL)
85  throw std::invalid_argument("access to unexisting entry");
86 
87  return bucket->record;
88  }
89 
90  DLProxy& operator = (const Record& record)
91  throw(std::exception, std::bad_alloc)
92  {
93  if (bucket != NULL)
94  {
95  bucket->record = record;
96  return *this;
97  }
98 
99  bucket = new DLBucket (key, record);
100  table.LhashTable<Key>::insert(bucket);
101  return *this;
102  }
103 
104  DLProxy& operator = (const DLProxy& proxy)
105  throw(std::exception, std::bad_alloc, std::invalid_argument)
106  {
107  if (proxy.bucket == NULL)
108  throw std::invalid_argument("access to unexisting entry");
109 
110  if (bucket != NULL)
111  {
112  bucket->record = proxy.bucket->record;
113  return *this;
114  }
115 
116  bucket = new DLBucket (key, proxy.bucket->record);
117  table.LhashTable<Key>::insert(bucket);
118  return *this;
119  }
120  };
121 
122 public:
123 
126 
127  void swap(DynLhashTable & table)
128  {
129  this->LhashTable<Key>::swap(table);
130  }
131 
135  DynLhashTable(Hash_Fct hash_fct, const size_t & len = DefaultPrime)
136  throw (std::exception, std::bad_alloc) : LhashTable<Key>(hash_fct, len)
137  {
138  // Empty
139  }
140 
141 private:
142 
143  void copy(DynLhashTable & table)
144  {
145  for (typename LhashTable<Key>::Iterator it(table); it.has_curr(); it.next())
146  {
147  DLBucket * Bucket = (DLBucket*) it.get_curr();
148  insert(Bucket->get_key(), Bucket->record);
149  }
150  }
151 
152 public:
153 
154  DynLhashTable(const DynLhashTable & table)
155  : LhashTable<Key>(table.hash_fct, table.len)
156  {
157  copy(table);
158  }
159 
160  DynLhashTable(DynLhashTable && table)
161  {
162  swap(table);
163  }
164 
165  DynLhashTable & operator = (const DynLhashTable & table)
166  {
167  if (this == &table)
168  return *this;
169 
170  this->empty();
171  copy(table);
172 
173  return *this;
174  }
175 
176  DynLhashTable & operator = (DynLhashTable && table)
177  {
178  swap(table);
179  return *this;
180  }
181 
182 private:
183 
184  Record * __insert(DLBucket * bucket)
185  {
186  LhashTable<Key>::insert(bucket);
187  return &bucket->record;
188  }
189 
190 public:
191 
195  Record * insert(const Key & key, const Record & record)
196  throw (std::exception, std::bad_alloc)
197  {
198  return __insert(new DLBucket (key, record));
199  }
200 
201  Record * insert(const Key & key, Record && record = Record())
202  throw (std::exception, std::bad_alloc)
203  {
204  return __insert(new DLBucket (key, std::move(record)));
205  }
206 
207  Record * insert(Key && key, const Record & record)
208  throw (std::exception, std::bad_alloc)
209  {
210  return __insert(new DLBucket (std::move(key), record));
211  }
212 
213  Record * insert(Key && key, Record && record)
214  throw (std::exception, std::bad_alloc)
215  {
216  return __insert(new DLBucket (std::move(key), std::move(record)));
217  }
218 
222  Record * search(const Key & key)
223  {
224  DLBucket * bucket = (DLBucket*) LhashTable<Key>::search(key);
225  return bucket != NULL ? &bucket->record : NULL;
226  }
227 
230  void remove(Record * record)
231  {
232  DLBucket* bucket = record_to_bucket(record);
233  LhashTable<Key>::remove(bucket);
234  delete bucket;
235  }
236 
237  DLProxy operator [] (const Key& key) const
238  throw(std::exception, std::invalid_argument)
239  {
240  return DLProxy ( const_cast<DynLhashTable&>(*this), key);
241  }
242 
243  DLProxy operator [] (const Key& key)
244  throw(std::exception, std::bad_alloc, std::invalid_argument)
245  {
246  return DLProxy (*this, key);
247  }
248 };
249 
250 } // end namespace Aleph
251 
252 # endif // TPL_DYNLHASH_H
253 
Record * search(const Key &key)
Definition: tpl_dynLhash.H:222
Bucket * insert(Bucket *bucket)
Definition: tpl_lhash.H:160
void empty()
Vacía la tabla hash; libera memoria de todas las cubetas.
Definition: tpl_lhash.H:123
DynLhashTable(Hash_Fct hash_fct, const size_t &len=DefaultPrime)
Definition: tpl_dynLhash.H:135
Record * insert(const Key &key, const Record &record)
Definition: tpl_dynLhash.H:195
Definition: tpl_lhash.H:531
Definition: tpl_dynLhash.H:36
Definition: tpl_lhash.H:472
Bucket * remove(Bucket *bucket)
Definition: tpl_lhash.H:209
DynLhashTable< Key, Record >::Hash_Fct Hash_Fct
El tipo de función hash.
Definition: tpl_dynLhash.H:125

Leandro Rabindranath León