MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DLHashTable2.hpp
1 /*
2  Copyright (C) 2003-2006, 2008 MySQL AB
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef DL_HASHTABLE2_HPP
20 #define DL_HASHTABLE2_HPP
21 
22 #include <ndb_global.h>
23 #include "ArrayPool.hpp"
24 
32 template <class T, class U>
33 class DLHashTable2 {
34 public:
35  DLHashTable2(ArrayPool<U> & thePool);
36  ~DLHashTable2();
37 
43  bool setSize(Uint32 noOfElements);
44 
51  bool seize(Ptr<T> &);
52 
56  void add(Ptr<T> &);
57 
63  bool find(Ptr<T> &, const T & key) const;
64 
68  void getPtr(Ptr<T> &, Uint32 i) const;
69 
73  void getPtr(Ptr<T> &) const;
74 
78  T * getPtr(Uint32 i) const;
79 
84  void remove(Ptr<T> &, const T & key);
85 
90  void remove(Uint32 i);
91 
96  void remove(Ptr<T> &);
97 
101  void removeAll();
102 
107  void release(Ptr<T> &, const T & key);
108 
112  void release(Uint32 i);
113 
117  void release(Ptr<T> &);
118 
119  class Iterator {
120  public:
121  Ptr<T> curr;
122  Uint32 bucket;
123  inline bool isNull() const { return curr.isNull();}
124  inline void setNull() { curr.setNull(); }
125  };
126 
130  void getPtr(Iterator & iter) const ;
131 
135  bool first(Iterator & iter) const;
136 
142  bool next(Iterator & iter) const;
143 
150  bool next(Uint32 bucket, Iterator & iter) const;
151 
152  inline bool isEmpty() const { Iterator iter; return ! first(iter); }
153 
154 private:
155  Uint32 mask;
156  Uint32 * hashValues;
157  ArrayPool<U> & thePool;
158 };
159 
160 template<class T, class U>
161 inline
163  : thePool(_pool)
164 {
165  mask = 0;
166  hashValues = 0;
167 }
168 
169 template<class T, class U>
170 inline
172  if(hashValues != 0)
173  delete [] hashValues;
174 }
175 
176 template<class T, class U>
177 inline
178 bool
180  Uint32 i = 1;
181  while(i < size) i *= 2;
182 
183  if(mask == (i - 1)){
187  return true;
188  }
189 
190  if(mask != 0){
194  return false;
195  }
196 
197  mask = (i - 1);
198  hashValues = new Uint32[i];
199  for(Uint32 j = 0; j<i; j++)
200  hashValues[j] = RNIL;
201 
202  return true;
203 }
204 
205 template<class T, class U>
206 inline
207 void
209  const Uint32 hv = obj.p->hashValue() & mask;
210  const Uint32 i = hashValues[hv];
211 
212  if(i == RNIL){
213  hashValues[hv] = obj.i;
214  obj.p->nextHash = RNIL;
215  obj.p->prevHash = RNIL;
216  } else {
217 
218  T * tmp = (T*)thePool.getPtr(i); // cast
219  tmp->prevHash = obj.i;
220  obj.p->nextHash = i;
221  obj.p->prevHash = RNIL;
222 
223  hashValues[hv] = obj.i;
224  }
225 }
226 
230 template<class T, class U>
231 inline
232 bool
234  Uint32 i = 0;
235  while(i <= mask && hashValues[i] == RNIL) i++;
236  if(i <= mask){
237  iter.bucket = i;
238  iter.curr.i = hashValues[i];
239  iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
240  return true;
241  } else {
242  iter.curr.i = RNIL;
243  }
244  return false;
245 }
246 
247 template<class T, class U>
248 inline
249 bool
251  if(iter.curr.p->nextHash == RNIL){
252  Uint32 i = iter.bucket + 1;
253  while(i <= mask && hashValues[i] == RNIL) i++;
254  if(i <= mask){
255  iter.bucket = i;
256  iter.curr.i = hashValues[i];
257  iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
258  return true;
259  } else {
260  iter.curr.i = RNIL;
261  return false;
262  }
263  }
264 
265  iter.curr.i = iter.curr.p->nextHash;
266  iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
267  return true;
268 }
269 
270 template<class T, class U>
271 inline
272 void
273 DLHashTable2<T, U>::remove(Ptr<T> & ptr, const T & key){
274  const Uint32 hv = key.hashValue() & mask;
275 
276  Uint32 i;
277  T * p;
278  Ptr<T> prev;
279  prev.i = RNIL;
280 
281  i = hashValues[hv];
282  while(i != RNIL){
283  p = (T*)thePool.getPtr(i); // cast
284  if(key.equal(* p)){
285  const Uint32 next = p->nextHash;
286  if(prev.i == RNIL){
287  hashValues[hv] = next;
288  } else {
289  prev.p->nextHash = next;
290  }
291 
292  if(next != RNIL){
293  T * nextP = (T*)thePool.getPtr(next); // cast
294  nextP->prevHash = prev.i;
295  }
296 
297  ptr.i = i;
298  ptr.p = p;
299  return;
300  }
301  prev.p = p;
302  prev.i = i;
303  i = p->nextHash;
304  }
305  ptr.i = RNIL;
306 }
307 
308 template<class T, class U>
309 inline
310 void
311 DLHashTable2<T, U>::release(Ptr<T> & ptr, const T & key){
312  const Uint32 hv = key.hashValue() & mask;
313 
314  Uint32 i;
315  T * p;
316  Ptr<T> prev;
317  prev.i = RNIL;
318 
319  i = hashValues[hv];
320  while(i != RNIL){
321  p = (T*)thePool.getPtr(i); // cast
322  if(key.equal(* p)){
323  const Uint32 next = p->nextHash;
324  if(prev.i == RNIL){
325  hashValues[hv] = next;
326  } else {
327  prev.p->nextHash = next;
328  }
329 
330  if(next != RNIL){
331  T * nextP = (T*)thePool.getPtr(next); // cast
332  nextP->prevHash = prev.i;
333  }
334 
335  p->~T(); // dtor
336  thePool.release(i);
337  ptr.i = i;
338  ptr.p = p; // invalid
339  return;
340  }
341  prev.p = p;
342  prev.i = i;
343  i = p->nextHash;
344  }
345  ptr.i = RNIL;
346 }
347 
348 template<class T, class U>
349 inline
350 void
352  Ptr<T> tmp;
353  tmp.i = i;
354  tmp.p = (T*)thePool.getPtr(i); // cast
355  remove(tmp);
356 }
357 
358 template<class T, class U>
359 inline
360 void
362  Ptr<T> tmp;
363  tmp.i = i;
364  tmp.p = (T*)thePool.getPtr(i); // cast
365  release(tmp);
366 }
367 
368 template<class T, class U>
369 inline
370 void
372  const Uint32 next = ptr.p->nextHash;
373  const Uint32 prev = ptr.p->prevHash;
374 
375  if(prev != RNIL){
376  T * prevP = (T*)thePool.getPtr(prev); // cast
377  prevP->nextHash = next;
378  } else {
379  const Uint32 hv = ptr.p->hashValue() & mask;
380  if (hashValues[hv] == ptr.i)
381  {
382  hashValues[hv] = next;
383  }
384  else
385  {
386  // Will add assert in 5.1
387  }
388  }
389 
390  if(next != RNIL){
391  T * nextP = (T*)thePool.getPtr(next); // cast
392  nextP->prevHash = prev;
393  }
394 }
395 
396 template<class T, class U>
397 inline
398 void
400  const Uint32 next = ptr.p->nextHash;
401  const Uint32 prev = ptr.p->prevHash;
402 
403  if(prev != RNIL){
404  T * prevP = (T*)thePool.getPtr(prev); // cast
405  prevP->nextHash = next;
406  } else {
407  const Uint32 hv = ptr.p->hashValue() & mask;
408  if (hashValues[hv] == ptr.i)
409  {
410  hashValues[hv] = next;
411  }
412  else
413  {
414  // Will add assert in 5.1
415  }
416  }
417 
418  if(next != RNIL){
419  T * nextP = (T*)thePool.getPtr(next); // cast
420  nextP->prevHash = prev;
421  }
422 
423  thePool.release(ptr.i);
424 }
425 
426 template<class T, class U>
427 inline
428 void
430  for(Uint32 i = 0; i<=mask; i++)
431  hashValues[i] = RNIL;
432 }
433 
434 template<class T, class U>
435 inline
436 bool
437 DLHashTable2<T, U>::next(Uint32 bucket, Iterator & iter) const {
438  while (bucket <= mask && hashValues[bucket] == RNIL)
439  bucket++;
440 
441  if (bucket > mask) {
442  iter.bucket = bucket;
443  iter.curr.i = RNIL;
444  return false;
445  }
446 
447  iter.bucket = bucket;
448  iter.curr.i = hashValues[bucket];
449  iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
450  return true;
451 }
452 
453 template<class T, class U>
454 inline
455 bool
457  Ptr<U> ptr2;
458  thePool.seize(ptr2);
459  ptr.i = ptr2.i;
460  ptr.p = (T*)ptr2.p; // cast
461  if (ptr.p != NULL){
462  ptr.p->nextHash = RNIL;
463  ptr.p->prevHash = RNIL;
464  new (ptr.p) T; // ctor
465  }
466  return !ptr.isNull();
467 }
468 
469 template<class T, class U>
470 inline
471 void
472 DLHashTable2<T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const {
473  ptr.i = i;
474  ptr.p = (T*)thePool.getPtr(i); // cast
475 }
476 
477 template<class T, class U>
478 inline
479 void
481  Ptr<U> ptr2;
482  thePool.getPtr(ptr2);
483  ptr.i = ptr2.i;
484  ptr.p = (T*)ptr2.p; // cast
485 }
486 
487 template<class T, class U>
488 inline
489 T *
491  return (T*)thePool.getPtr(i); // cast
492 }
493 
494 template<class T, class U>
495 inline
496 bool
497 DLHashTable2<T, U>::find(Ptr<T> & ptr, const T & key) const {
498  const Uint32 hv = key.hashValue() & mask;
499 
500  Uint32 i;
501  T * p;
502 
503  i = hashValues[hv];
504  while(i != RNIL){
505  p = (T*)thePool.getPtr(i); // cast
506  if(key.equal(* p)){
507  ptr.i = i;
508  ptr.p = p;
509  return true;
510  }
511  i = p->nextHash;
512  }
513  ptr.i = RNIL;
514  ptr.p = NULL;
515  return false;
516 }
517 #endif