22 #include <ndb_types.h>
24 #define SEGMENTSIZE 64
25 #define SEGMENTLOGSIZE 6
26 #define DIRECTORYSIZE 64
27 #define DIRINDEX(adress) ((adress) >> SEGMENTLOGSIZE)
28 #define SEGINDEX(adress) ((adress) & (SEGMENTSIZE-1))
30 #if !defined(MAXLOADFCTR)
33 #if !defined(MINLOADFCTR)
34 #define MINLOADFCTR (MAXLOADFCTR/2)
60 void createHashTable(
void);
61 void releaseHashTable(
void);
63 int insertKey(
const char * str, Uint32 len, Uint32 lkey1, C* data);
64 C *deleteKey(
const char * str, Uint32 len);
66 C* getData(
const char *, Uint32);
67 Uint32* getKey(
const char *, Uint32);
69 void shrinkTable(
void);
70 void expandHashTable(
void);
72 Uint32 Hash(
const char *str, Uint32 len);
73 Uint32 Hash(Uint32 h);
78 void getBucket(Uint32 hash,
int * dirindex,
int * segindex);
87 Segment_t * directory[DIRECTORYSIZE];
119 h = (h << 5) + h + str[0];
120 h = (h << 5) + h + str[1];
121 h = (h << 5) + h + str[2];
122 h = (h << 5) + h + str[3];
128 h = (h << 5) + h + *str++;
167 max = SEGMENTSIZE - 1;
168 slack = SEGMENTSIZE * MAXLOADFCTR;
169 directory[0] =
new Segment_t();
173 for(i = 0; i < SEGMENTSIZE; i++ )
174 directory[0]->elements[i] = 0;
177 for(i = 1; i < DIRECTORYSIZE; i++)
185 Uint32 adress = hash & max;
187 adress = hash & (2 * max + 1);
189 * dir = DIRINDEX(adress);
190 * seg = SEGINDEX(adress);
198 const Uint32 hash = Hash(str, len);
200 getBucket(hash, &dir, &seg);
210 for(chain = *chainp; chain != 0; chain = chain->next){
211 if(chain->len == len && !memcmp(chain->str, str, len))
221 chain->localkey1 = lkey1;
223 chain->theData = data;
225 chain->str =
new Uint32[((len + 3) >> 2)];
226 memcpy( &chain->str[0], str, len);
228 oldChain->next = chain;
237 return chain->localkey1;
246 const Uint32 tHash = Hash(str, len);
248 getBucket(tHash, &dir, &seg);
254 if(key->len == len && !memcmp(key->str, str, len)) {
255 return &key->localkey1;
266 const Uint32 tHash = Hash(str, len);
268 getBucket(tHash, &dir, &seg);
274 if(key->len == len && !memcmp(key->str, str, len)) {
285 const Uint32 hash = Hash(str, len);
287 getBucket(hash, &dir, &seg);
291 for(
NdbElement_t<C> * chain = *chainp; chain != 0; chain = chain->next){
292 if(chain->len == len && !memcmp(chain->str, str, len)){
293 C *data= chain->theData;
295 * chainp = chain->next;
297 oldChain->next = chain->next;
316 for(
int countd = 0; countd < DIRECTORYSIZE;countd++ ){
317 if (directory[countd] != 0) {
319 for(
int counts = 0; counts < SEGMENTSIZE; counts++ )
320 if (directory[countd]->elements[counts] != 0) {
321 tElement = directory[countd]->elements[counts];
324 tNextElement = tElement->next;
326 tElement = tNextElement;
327 }
while (tNextElement != 0);
329 delete directory[countd];
341 Uint32 oldlast = p + max;
356 slack -= MAXLOADFCTR;
360 chainp = &directory[DIRINDEX(p)]->elements[SEGINDEX(p)];
361 while( *chainp != 0 ) {
362 chainp = &((*chainp)->next);
363 lastseg = directory[DIRINDEX(oldlast)];
364 *chainp = lastseg->elements[SEGINDEX(oldlast)];
367 if( SEGINDEX(oldlast) == 0)
379 Uint32 maxp = max + 1;
380 Uint32 newadress = maxp + p;
384 if( newadress >= DIRECTORYSIZE * SEGMENTSIZE ) {
389 if( SEGINDEX(newadress) == 0 )
390 directory[DIRINDEX(newadress)] =
new Segment_t();
393 oldbucketp = &directory[DIRINDEX(p)]->elements[SEGINDEX(p)];
403 slack += MAXLOADFCTR;
409 for( chain = *oldbucketp; chain != 0; chain = next ) {
411 if( chain->hash & maxp ) {
412 chain->next = headofnew;
416 chain->next = headofold;
420 *oldbucketp = headofold;
421 directory[DIRINDEX(newadress)]->elements[SEGINDEX(newadress)] = headofnew;
428 if(curr != 0 && curr->next != 0)
431 int dir = 0, seg = 0;
435 getBucket(curr->hash, &dir, &seg);
443 for(
int countd = dir; countd < DIRECTORYSIZE;countd++ ){
444 if (directory[countd] != 0) {
445 for(; counts < SEGMENTSIZE; counts++ ){
446 if (directory[countd]->elements[counts] != 0) {
447 return directory[countd]->elements[counts];