Aleph-w  1.9
General library for algorithms and data structures
tpl_dynLhash.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 
28 # ifndef TPL_DYNLHASH_H
29 # define TPL_DYNLHASH_H
30 
31 # include <tpl_lhash.H>
32 
33 using namespace Aleph;
34 
35 namespace Aleph {
36 
61  template <typename Key, typename Record, class Cmp = Aleph::equal_to<Key>>
62 class DynLhashTable : public LhashTable<Key>
63 {
64 private:
65 
66  struct DLBucket : public LhashTable<Key>::Bucket
67  {
68  Record record;
69 
70  DLBucket(const Key & key, const Record & _record)
71  : LhashTable<Key>::Bucket(key), record(_record) { /* Empty */ }
72 
73  DLBucket(const Key & key, Record && _record)
74  : LhashTable<Key>::Bucket(key), record(std::forward<Record>(_record))
75  { /* Empty */ }
76 
77  DLBucket(Key && key, const Record & _record)
78  : LhashTable<Key>::Bucket(std::forward<Key>(key)), record(_record)
79  { /* Empty */ }
80 
81  DLBucket(Key && key, Record && _record)
82  : LhashTable<Key>::Bucket(std::forward<Key>(key)),
83  record(std::forward<Record>(_record)) { /* Empty */ }
84  };
85 
86  static DLBucket * record_to_bucket(Record * rec)
87  {
88  DLBucket * ret_val = 0;
89  size_t offset = (size_t) &ret_val->record;
90  return (DLBucket*) (((size_t) rec) - offset);
91  }
92 
93  class DLProxy
94  {
95  DynLhashTable & table;
96  const Key & key;
97  DLBucket * bucket;
98 
99  public:
100 
101  DLProxy(DynLhashTable & _table, const Key& _key)
102  : table(_table), key(_key)
103  {
104  Record * record = table.search(key);
105  bucket = record not_eq nullptr ? record_to_bucket(record) : nullptr;
106  }
107 
108  operator const Record & () const
109  {
110  if (bucket == nullptr)
111  throw std::invalid_argument("access to unexisting entry");
112 
113  return bucket->record;
114  }
115 
116  DLProxy& operator = (const Record& record)
117  {
118  if (bucket != nullptr)
119  {
120  bucket->record = record;
121  return *this;
122  }
123 
124  bucket = new DLBucket (key, record);
125  table.LhashTable<Key>::insert(bucket);
126  return *this;
127  }
128 
129  DLProxy& operator = (const DLProxy& proxy)
130  {
131  if (proxy.bucket == nullptr)
132  throw std::invalid_argument("access to unexisting entry");
133 
134  if (bucket != nullptr)
135  {
136  bucket->record = proxy.bucket->record;
137  return *this;
138  }
139 
140  bucket = new DLBucket (key, proxy.bucket->record);
141  table.LhashTable<Key>::insert(bucket);
142  return *this;
143  }
144  };
145 
146 public:
147 
150 
151  void swap(DynLhashTable & table)
152  {
153  this->LhashTable<Key>::swap(table);
154  }
155 
159  DynLhashTable(size_t len = DefaultPrime,
160  Hash_Fct_Ptr hash_fct = dft_hash_fct<Key>)
161  : LhashTable<Key>(len, hash_fct)
162  {
163  // Empty
164  }
165 
166 private:
167 
168  void copy(DynLhashTable & table)
169  {
170  for (typename LhashTable<Key>::Iterator it(table); it.has_curr();
171  it.next_ne())
172  {
173  DLBucket * Bucket = (DLBucket*) it.get_curr_ne();
174  insert(Bucket->get_key(), Bucket->record);
175  }
176  }
177 
178 public:
179 
180  DynLhashTable(const DynLhashTable & table)
181  : LhashTable<Key>(table.hash_fct, table.len)
182  {
183  copy(table);
184  }
185 
186  DynLhashTable(DynLhashTable && table)
187  {
188  swap(table);
189  }
190 
191  DynLhashTable & operator = (const DynLhashTable & table)
192  {
193  if (this == &table)
194  return *this;
195 
196  this->empty();
197  copy(table);
198 
199  return *this;
200  }
201 
202  DynLhashTable & operator = (DynLhashTable && table)
203  {
204  swap(table);
205  return *this;
206  }
207 
208 private:
209 
210  Record * __insert(DLBucket * bucket)
211  {
212  LhashTable<Key>::insert(bucket);
213  return &bucket->record;
214  }
215 
216 public:
217 
221  Record * insert(const Key & key, const Record & record)
222  {
223  return __insert(new DLBucket (key, record));
224  }
225 
226  Record * insert(const Key & key, Record && record = Record())
227  {
228  return __insert(new DLBucket(key, std::forward<Record>(record)));
229  }
230 
231  Record * insert(Key && key, const Record & record)
232  {
233  return __insert(new DLBucket (std::forward<Key>(key), record));
234  }
235 
236  Record * insert(Key && key, Record && record)
237  {
238  return __insert(new DLBucket(std::forward<Key>(key),
239  std::forward<Record>(record)));
240  }
241 
245  Record * search(const Key & key)
246  {
247  DLBucket * bucket = (DLBucket*) LhashTable<Key>::search(key);
248  return bucket != nullptr ? &bucket->record : nullptr;
249  }
250 
253  void remove(Record * record)
254  {
255  DLBucket* bucket = record_to_bucket(record);
256  LhashTable<Key>::remove(bucket);
257  delete bucket;
258  }
259 
260  DLProxy operator [] (const Key& key) const
261  {
262  return DLProxy ( const_cast<DynLhashTable&>(*this), key);
263  }
264 
265  DLProxy operator [] (const Key& key)
266  {
267  return DLProxy (*this, key);
268  }
269 };
270 
271 } // end namespace Aleph
272 
273 # endif // TPL_DYNLHASH_H
274 
Record * search(const Key &key)
Definition: tpl_dynLhash.H:245
Bucket * insert(Bucket *bucket)
Definition: tpl_lhash.H:216
Bucket * remove(Bucket *bucket) noexcept
Definition: tpl_lhash.H:288
Definition: ah-comb.H:35
Record * insert(const Key &key, const Record &record)
Definition: tpl_dynLhash.H:221
void empty() noexcept
Vacía la tabla hash; libera memoria de todas las cubetas.
Definition: tpl_lhash.H:173
Definition: tpl_dynLhash.H:62
DynLhashTable(size_t len=DefaultPrime, Hash_Fct_Ptr hash_fct=dft_hash_fct< Key >)
Definition: tpl_dynLhash.H:159
Definition: tpl_lhash.H:660
typename DynLhashTable< Key, Record >::Hash_Fct_Ptr Hash_Fct_Ptr
El tipo de función hash.
Definition: tpl_dynLhash.H:149

Leandro Rabindranath León