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];