1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#ifndef DL_HASHTABLE2_HPP
17
#define DL_HASHTABLE2_HPP
19
#include <ndb_global.h>
20
#include "ArrayPool.hpp"
23
* DLHashTable2 is a DLHashTable variant meant for cases where different
24
* DLHashTable instances share a common pool (based on a union U).
26
* Calls T constructor after seize from pool and T destructor before
27
* release (in all forms) into pool.
29
template <class T, class U>
32
DLHashTable2(ArrayPool<U> & thePool);
36
* Set the no of bucket in the hashtable
38
* Note, can currently only be called once
40
bool setSize(Uint32 noOfElements);
43
* Seize element from pool - return i
45
* Note *must* be added using <b>add</b> (even before hash.release)
46
* or be released using pool
51
* Add an object to the hashtable
56
* Find element key in hashtable update Ptr (i & p)
57
* (using key.equal(...))
58
* @return true if found and false otherwise
60
bool find(Ptr<T> &, const T & key) const;
63
* Update i & p value according to <b>i</b>
65
void getPtr(Ptr<T> &, Uint32 i) const;
68
* Get element using ptr.i (update ptr.p)
70
void getPtr(Ptr<T> &) const;
75
T * getPtr(Uint32 i) const;
78
* Remove element (and set Ptr to removed element)
79
* Note does not return to pool
81
void remove(Ptr<T> &, const T & key);
85
* Note does not return to pool
87
void remove(Uint32 i);
91
* Note does not return to pool
93
void remove(Ptr<T> &);
96
* Remove all elements, but dont return them to pool
101
* Remove element (and set Ptr to removed element)
102
* And return element to pool
104
void release(Ptr<T> &, const T & key);
107
* Remove element and return to pool
109
void release(Uint32 i);
112
* Remove element and return to pool
114
void release(Ptr<T> &);
120
inline bool isNull() const { return curr.isNull();}
121
inline void setNull() { curr.setNull(); }
125
* Sets curr.p according to curr.i
127
void getPtr(Iterator & iter) const ;
130
* First element in bucket
132
bool first(Iterator & iter) const;
137
* param iter - A "fully set" iterator
139
bool next(Iterator & iter) const;
142
* Get next element starting from bucket
144
* @param bucket - Which bucket to start from
145
* @param iter - An "uninitialized" iterator
147
bool next(Uint32 bucket, Iterator & iter) const;
149
inline bool isEmpty() const { Iterator iter; return ! first(iter); }
154
ArrayPool<U> & thePool;
157
template<class T, class U>
159
DLHashTable2<T, U>::DLHashTable2(ArrayPool<U> & _pool)
166
template<class T, class U>
168
DLHashTable2<T, U>::~DLHashTable2(){
170
delete [] hashValues;
173
template<class T, class U>
176
DLHashTable2<T, U>::setSize(Uint32 size){
178
while(i < size) i *= 2;
182
* The size is already set to <b>size</b>
189
* The mask is already set
195
hashValues = new Uint32[i];
196
for(Uint32 j = 0; j<i; j++)
197
hashValues[j] = RNIL;
202
template<class T, class U>
205
DLHashTable2<T, U>::add(Ptr<T> & obj){
206
const Uint32 hv = obj.p->hashValue() & mask;
207
const Uint32 i = hashValues[hv];
210
hashValues[hv] = obj.i;
211
obj.p->nextHash = RNIL;
212
obj.p->prevHash = RNIL;
215
T * tmp = (T*)thePool.getPtr(i); // cast
216
tmp->prevHash = obj.i;
218
obj.p->prevHash = RNIL;
220
hashValues[hv] = obj.i;
227
template<class T, class U>
230
DLHashTable2<T, U>::first(Iterator & iter) const {
232
while(i <= mask && hashValues[i] == RNIL) i++;
235
iter.curr.i = hashValues[i];
236
iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
244
template<class T, class U>
247
DLHashTable2<T, U>::next(Iterator & iter) const {
248
if(iter.curr.p->nextHash == RNIL){
249
Uint32 i = iter.bucket + 1;
250
while(i <= mask && hashValues[i] == RNIL) i++;
253
iter.curr.i = hashValues[i];
254
iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
262
iter.curr.i = iter.curr.p->nextHash;
263
iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
267
template<class T, class U>
270
DLHashTable2<T, U>::remove(Ptr<T> & ptr, const T & key){
271
const Uint32 hv = key.hashValue() & mask;
280
p = (T*)thePool.getPtr(i); // cast
282
const Uint32 next = p->nextHash;
284
hashValues[hv] = next;
286
prev.p->nextHash = next;
290
T * nextP = (T*)thePool.getPtr(next); // cast
291
nextP->prevHash = prev.i;
305
template<class T, class U>
308
DLHashTable2<T, U>::release(Ptr<T> & ptr, const T & key){
309
const Uint32 hv = key.hashValue() & mask;
318
p = (T*)thePool.getPtr(i); // cast
320
const Uint32 next = p->nextHash;
322
hashValues[hv] = next;
324
prev.p->nextHash = next;
328
T * nextP = (T*)thePool.getPtr(next); // cast
329
nextP->prevHash = prev.i;
335
ptr.p = p; // invalid
345
template<class T, class U>
348
DLHashTable2<T, U>::remove(Uint32 i){
351
tmp.p = (T*)thePool.getPtr(i); // cast
355
template<class T, class U>
358
DLHashTable2<T, U>::release(Uint32 i){
361
tmp.p = (T*)thePool.getPtr(i); // cast
365
template<class T, class U>
368
DLHashTable2<T, U>::remove(Ptr<T> & ptr){
369
const Uint32 next = ptr.p->nextHash;
370
const Uint32 prev = ptr.p->prevHash;
373
T * prevP = (T*)thePool.getPtr(prev); // cast
374
prevP->nextHash = next;
376
const Uint32 hv = ptr.p->hashValue() & mask;
377
if (hashValues[hv] == ptr.i)
379
hashValues[hv] = next;
383
// Will add assert in 5.1
388
T * nextP = (T*)thePool.getPtr(next); // cast
389
nextP->prevHash = prev;
393
template<class T, class U>
396
DLHashTable2<T, U>::release(Ptr<T> & ptr){
397
const Uint32 next = ptr.p->nextHash;
398
const Uint32 prev = ptr.p->prevHash;
401
T * prevP = (T*)thePool.getPtr(prev); // cast
402
prevP->nextHash = next;
404
const Uint32 hv = ptr.p->hashValue() & mask;
405
if (hashValues[hv] == ptr.i)
407
hashValues[hv] = next;
411
// Will add assert in 5.1
416
T * nextP = (T*)thePool.getPtr(next); // cast
417
nextP->prevHash = prev;
420
thePool.release(ptr.i);
423
template<class T, class U>
426
DLHashTable2<T, U>::removeAll(){
427
for(Uint32 i = 0; i<=mask; i++)
428
hashValues[i] = RNIL;
431
template<class T, class U>
434
DLHashTable2<T, U>::next(Uint32 bucket, Iterator & iter) const {
435
while (bucket <= mask && hashValues[bucket] == RNIL)
439
iter.bucket = bucket;
444
iter.bucket = bucket;
445
iter.curr.i = hashValues[bucket];
446
iter.curr.p = (T*)thePool.getPtr(iter.curr.i); // cast
450
template<class T, class U>
453
DLHashTable2<T, U>::seize(Ptr<T> & ptr){
457
ptr.p = (T*)ptr2.p; // cast
459
ptr.p->nextHash = RNIL;
460
ptr.p->prevHash = RNIL;
461
new (ptr.p) T; // ctor
463
return !ptr.isNull();
466
template<class T, class U>
469
DLHashTable2<T, U>::getPtr(Ptr<T> & ptr, Uint32 i) const {
471
ptr.p = (T*)thePool.getPtr(i); // cast
474
template<class T, class U>
477
DLHashTable2<T, U>::getPtr(Ptr<T> & ptr) const {
479
thePool.getPtr(ptr2);
481
ptr.p = (T*)ptr2.p; // cast
484
template<class T, class U>
487
DLHashTable2<T, U>::getPtr(Uint32 i) const {
488
return (T*)thePool.getPtr(i); // cast
491
template<class T, class U>
494
DLHashTable2<T, U>::find(Ptr<T> & ptr, const T & key) const {
495
const Uint32 hv = key.hashValue() & mask;
502
p = (T*)thePool.getPtr(i); // cast